Skip to content

Commit ab7aaa2

Browse files
committed
Blocks can be dragged by drag handle only
Closes #220
1 parent c191f1a commit ab7aaa2

File tree

3 files changed

+100
-20
lines changed

3 files changed

+100
-20
lines changed

src/main/webapp/static/com/atomgraph/linkeddatahub/css/bootstrap.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ li button.btn-edit-constructors, li button.btn-add-data, li button.btn-add-ontol
9595
#content-body > [about].row-fluid, .constructor-triple.row-fluid { border-bottom: 2px solid rgb(223, 223, 223); }
9696
#content-body > [about].row-fluid.drag-over { border-bottom: 4px dotted #0f82f5; }
9797
.row-fluid.block { max-height: 80em; }
98+
.row-fluid.block .drag-handle { display: none; width: 30px; background-color: #149bdf; background-image: radial-gradient(circle at 3px 3px, #0480be 1px, transparent 1.5px); background-size: 6px 6px; border-radius: 2px; cursor: move; }
9899
.list-mode.active { background-image: url('../icons/ic_navigate_before_black_24px.svg'); }
99100
legend.create-action { background-image: url('../icons/ic_note_add_black_24px.svg'); background-position: 12px center; background-repeat: no-repeat; padding-left: 40px; }
100101
alert.violation { background-image: url('../icons/ic_error_white_24px.svg '); background-position: 12px center; background-repeat: no-repeat; padding-left: 40px; }

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/block.xsl

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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 &lt;= $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 &gt; $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')]">

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/resource.xsl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ extension-element-prefixes="ixsl"
460460
<xsl:param name="class" select="'row-fluid block'" as="xs:string?"/>
461461
<xsl:param name="about" select="@rdf:about" as="xs:anyURI?"/>
462462
<xsl:param name="typeof" select="rdf:type/@rdf:resource/xs:anyURI(.)" as="xs:anyURI*"/>
463-
<xsl:param name="draggable" select="$acl:mode = '&acl;Write'" as="xs:boolean?"/>
463+
<xsl:param name="draggable" select="false()" as="xs:boolean?"/>
464464
<xsl:param name="show-row-block-controls" select="true()" as="xs:boolean"/>
465465

466466
<xsl:apply-templates select="key('resources', .)" mode="bs2:RowContentHeader"/>
@@ -486,6 +486,11 @@ extension-element-prefixes="ixsl"
486486
<xsl:if test="$show-row-block-controls">
487487
<xsl:attribute name="class" select="'span12 progress progress-striped active'"/>
488488

489+
<div class="drag-handle">
490+
<xsl:if test="$acl:mode = '&acl;Write'">
491+
<xsl:attribute name="draggable" select="'true'"/>
492+
</xsl:if>
493+
</div>
489494
<div class="row-fluid row-block-controls" style="position: relative; top: 30px; margin-top: -30px; z-index: 1;">
490495
<div class="span12">
491496
<xsl:if test="$acl:mode = '&acl;Write'">
@@ -520,7 +525,7 @@ extension-element-prefixes="ixsl"
520525
<xsl:param name="main-class" select="'main span7'" as="xs:string?"/>
521526
<xsl:param name="transclude" select="false()" as="xs:boolean"/>
522527
<xsl:param name="base" as="xs:anyURI?"/>
523-
<xsl:param name="draggable" select="$acl:mode = '&acl;Write'" as="xs:boolean?"/>
528+
<xsl:param name="draggable" select="false()" as="xs:boolean?"/>
524529

525530
<xsl:apply-templates select="." mode="bs2:RowContentHeader"/>
526531

@@ -542,6 +547,11 @@ extension-element-prefixes="ixsl"
542547
</xsl:if>
543548

544549
<div class="span12">
550+
<div class="drag-handle">
551+
<xsl:if test="$acl:mode = '&acl;Write'">
552+
<xsl:attribute name="draggable" select="'true'"/>
553+
</xsl:if>
554+
</div>
545555
<div class="row-fluid row-block-controls" style="position: relative; top: 30px; margin-top: -30px; z-index: 1;">
546556
<div class="span12">
547557
<xsl:if test="$acl:mode = '&acl;Write'">

0 commit comments

Comments
 (0)