@@ -176,6 +176,69 @@ exclude-result-prefixes="#all"
176176 </xsl : if >
177177 </xsl : template >
178178
179+ <!-- show drag handle on left edge hover -->
180+
181+ <xsl : template match =" div[ac:mode() = '&ldh;ContentMode'][contains-token(@class, 'block')][key('elements-by-class', 'drag-handle', .)][acl:mode() = '&acl;Write']" mode =" ixsl:onmousemove" priority =" 2" >
182+ <xsl : variable name =" dom-x" select =" ixsl:get(ixsl:event(), 'clientX')" as =" xs:double" />
183+ <xsl : variable name =" rect" select =" ixsl:call(., 'getBoundingClientRect', [])" />
184+ <xsl : variable name =" offset-x" select =" $dom-x - ixsl:get($rect, 'x')" as =" xs:double" />
185+ <xsl : variable name =" left-edge-threshold" select =" 30" as =" xs:double" />
186+
187+ <xsl : variable name =" drag-handle" select =" key('elements-by-class', 'drag-handle', .)[1]" as =" element()" />
188+
189+ <!-- check that the mouse is on the left edge -->
190+ <xsl : choose >
191+ <xsl : when test =" $offset-x < = $left-edge-threshold and ixsl:style($drag-handle)?display = 'none'" >
192+ <!-- get both block and span12 rectangles to calculate intersection -->
193+ <xsl : variable name =" span12" select =" $drag-handle/parent::*[contains-token(@class, 'span12')]" as =" element()" />
194+ <xsl : variable name =" block-rect" select =" $rect" /> <!-- block's getBoundingClientRect -->
195+ <xsl : variable name =" span12-rect" select =" ixsl:call($span12, 'getBoundingClientRect', [])" />
196+
197+ <!-- calculate intersection of block and span12 -->
198+ <xsl : variable name =" left" select =" max((ixsl:get($block-rect, 'left'), ixsl:get($span12-rect, 'left')))" as =" xs:double" />
199+ <xsl : variable name =" top" select =" max((ixsl:get($block-rect, 'top'), ixsl:get($span12-rect, 'top')))" as =" xs:double" />
200+ <xsl : variable name =" right" select =" min((ixsl:get($block-rect, 'right'), ixsl:get($span12-rect, 'right')))" as =" xs:double" />
201+ <xsl : variable name =" bottom" select =" min((ixsl:get($block-rect, 'bottom'), ixsl:get($span12-rect, 'bottom')))" as =" xs:double" />
202+ <xsl : variable name =" visible-height" select =" max((0, $bottom - $top))" as =" xs:double" />
203+
204+ <!-- only show drag-handle if there's actually visible area -->
205+ <xsl : if test =" $visible-height > 0" >
206+ <!-- position drag-handle to cover the visible intersection area -->
207+ <ixsl : set-style name =" position" select =" 'fixed'" object =" $drag-handle" />
208+ <ixsl : set-style name =" left" select =" $left || 'px'" object =" $drag-handle" />
209+ <ixsl : set-style name =" top" select =" $top || 'px'" object =" $drag-handle" />
210+ <ixsl : set-style name =" height" select =" $visible-height || 'px'" object =" $drag-handle" />
211+ <ixsl : set-style name =" z-index" select =" '999'" object =" $drag-handle" />
212+ <!-- enable draggable on the block when drag-handle is shown -->
213+ <ixsl : set-attribute name =" draggable" select =" 'true'" object =" ." />
214+ <!-- show drag-handle -->
215+ <ixsl : set-style name =" display" select =" 'block'" object =" $drag-handle" />
216+ </xsl : if >
217+ </xsl : when >
218+ <xsl : when test =" $offset-x > $left-edge-threshold and ixsl:style($drag-handle)?display = 'block'" >
219+ <!-- disable draggable on the block when drag-handle is hidden -->
220+ <ixsl : set-attribute name =" draggable" select =" 'false'" object =" ." />
221+ <!-- hide drag-handle when mouse moves away from left edge -->
222+ <ixsl : set-style name =" display" select =" 'none'" object =" $drag-handle" />
223+ </xsl : when >
224+ </xsl : choose >
225+
226+ <!-- call the next matching template to preserve existing block controls functionality -->
227+ <xsl : next-match />
228+ </xsl : template >
229+
230+ <!-- hide drag handle when mouse leaves block -->
231+
232+ <xsl : template match =" div[contains-token(@class, 'block')][key('elements-by-class', 'drag-handle', .)][acl:mode() = '&acl;Write']" mode =" ixsl:onmouseout" >
233+ <xsl : variable name =" related-target" select =" ixsl:get(ixsl:event(), 'relatedTarget')" as =" element()?" /> <!-- the element mouse entered -->
234+ <xsl : variable name =" drag-handle" select =" key('elements-by-class', 'drag-handle', .)[1]" as =" element()" />
235+
236+ <!-- only hide if the related target does not have this div as ancestor (is not its child) -->
237+ <xsl : if test =" not($related-target/ancestor-or-self::div[. is current()])" >
238+ <ixsl : set-style name =" display" select =" 'none'" object =" $drag-handle" />
239+ </xsl : if >
240+ </xsl : template >
241+
179242 <!-- override inline editing form for block types (do nothing if the button is disabled) - prioritize over form.xsl -->
180243
181244 <xsl : template match =" div[following-sibling::div[@typeof = ('&ldh;XHTML', '&ldh;Object')]]//button[contains-token(@class, 'btn-edit')][not(contains-token(@class, 'disabled'))]" mode =" ixsl:onclick" priority =" 1" >
@@ -255,22 +318,30 @@ exclude-result-prefixes="#all"
255318 </xsl : choose >
256319 </xsl : template >
257320
258- <!-- start dragging top-level block (or its descendants - necessary for Map and Graph modes to work correctly) -->
321+ <!-- start dragging block when drag-handle is dragged -->
259322
260- <xsl : template match =" div[@id = 'content-body']/div[ac:mode() = '&ldh;ContentMode'][@about][contains-token(@class, 'block')]/descendant-or-self::*" mode =" ixsl:ondragstart" >
261- <xsl : choose >
262- <!-- allow drag on the block element (not necessarily top-level) -->
263- <!-- TO-DO: better condition for checking whether blocks are top-level? -->
264- <xsl : when test =" self::div[contains-token(@class, 'block')][parent::div[@id = 'content-body']]" >
265- <ixsl : set-property name =" dataTransfer.effectAllowed" select =" 'move'" object =" ixsl:event()" />
266- <xsl : variable name =" block-uri" select =" @about" as =" xs:anyURI" />
267- <xsl : sequence select =" ixsl:call(ixsl:get(ixsl:event(), 'dataTransfer'), 'setData', [ 'text/uri-list', $block-uri ])" />
268- </xsl : when >
269- <!-- prevent drag on its descendants. This makes sure that content drag-and-drop doesn't interfere with drag events in the Map and Graph modes -->
270- <xsl : otherwise >
271- <xsl : sequence select =" ixsl:call(ixsl:event(), 'preventDefault', [])" />
272- </xsl : otherwise >
273- </xsl : choose >
323+ <xsl : template match =" div[contains-token(@class, 'drag-handle')]" mode =" ixsl:ondragstart" >
324+ <!-- find the parent block to drag -->
325+ <xsl : variable name =" block" select =" ancestor::div[contains-token(@class, 'block')][parent::div[@id = 'content-body']][1]" as =" element()?" />
326+ <xsl : for-each select =" $block" >
327+ <ixsl : set-property name =" dataTransfer.effectAllowed" select =" 'move'" object =" ixsl:event()" />
328+ <xsl : variable name =" block-uri" select =" @about" as =" xs:anyURI" />
329+ <xsl : sequence select =" ixsl:call(ixsl:get(ixsl:event(), 'dataTransfer'), 'setData', [ 'text/uri-list', $block-uri ])" />
330+ <!-- make it appear like the whole block is being dragged -->
331+ <xsl : sequence select =" ixsl:call(ixsl:get(ixsl:event(), 'dataTransfer'), 'setDragImage', [ ., 0, 0 ])" />
332+ </xsl : for-each >
333+ </xsl : template >
334+
335+ <!-- cleanup after drag ends -->
336+
337+ <xsl : template match =" div[contains-token(@class, 'drag-handle')]" mode =" ixsl:ondragend" >
338+ <!-- hide the drag-handle -->
339+ <ixsl : set-style name =" display" select =" 'none'" object =" ." />
340+ <!-- disable draggable on the parent block -->
341+ <xsl : variable name =" block" select =" ancestor::div[contains-token(@class, 'block')][1]" as =" element()?" />
342+ <xsl : if test =" exists($block)" >
343+ <ixsl : set-attribute name =" draggable" select =" 'false'" object =" $block" />
344+ </xsl : if >
274345 </xsl : template >
275346
276347 <!-- dragging block over other block -->
@@ -302,8 +373,6 @@ exclude-result-prefixes="#all"
302373 <xsl : variable name =" block-uri" select =" @about" as =" xs:anyURI?" />
303374 <xsl : variable name =" drop-block-uri" select =" ixsl:call(ixsl:get(ixsl:event(), 'dataTransfer'), 'getData', [ 'text/uri-list' ])" as =" xs:anyURI" />
304375
305- <xsl : message >$drop-block-uri: <xsl : value-of select =" $drop-block-uri" /></xsl : message >
306-
307376 <xsl : sequence select =" ixsl:call(ixsl:get(., 'classList'), 'toggle', [ 'drag-over', false() ])[current-date() lt xs:date('2000-01-01')]" />
308377
309378 <!-- only persist the change if the block is already saved and has an @about -->
@@ -354,7 +423,7 @@ exclude-result-prefixes="#all"
354423
355424 <xsl : variable name =" container" select =" $context('container')" as =" element()" />
356425
357- <xsl : message >ldh:hide-block-progress-bar $container/@typeof: < xsl : value-of select = " $container/@typeof " /> </xsl : message >
426+ <xsl : message >ldh:hide-block-progress-bar</xsl : message >
358427
359428 <!-- hide the progress bar -->
360429 <xsl : for-each select =" $container/ancestor::div[contains-token(@class, 'span12')][contains-token(@class, 'progress')][contains-token(@class, 'active')]" >
0 commit comments