Christian has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/69279


Change subject: RelocatableNode for Inline and Block Images
......................................................................

RelocatableNode for Inline and Block Images

HTML5's drag and drop has a ton of benefits an a couple
limitations. To achieve a native drag marker, an image tag helper
is used to indicate the size of the relocatable node. Chrome
shades the marker gray natively, Firefox is styled to match.

Change-Id: I755b698a3d968cc7e6ff125109d68ac83fd8a8a2
---
M modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js
M modules/ve/ce/nodes/ve.ce.MWInlineImageNode.js
M modules/ve/ce/styles/ve.ce.Node.css
M modules/ve/ce/ve.ce.RelocatableNode.js
M modules/ve/ce/ve.ce.ResizableNode.js
M modules/ve/ce/ve.ce.Surface.js
6 files changed, 95 insertions(+), 23 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor 
refs/changes/79/69279/1

diff --git a/modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js 
b/modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js
index 8ea8f73..c618052 100644
--- a/modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js
+++ b/modules/ve/ce/nodes/ve.ce.MWBlockImageNode.js
@@ -26,6 +26,7 @@
        ve.ce.ProtectedNode.call( this );
        ve.ce.FocusableNode.call( this );
        ve.ce.ResizableNode.call( this );
+       ve.ce.RelocatableNode.call( this );
 
        if ( this.model.getAttribute( 'align' ) === 'center' ) {
                this.$.addClass( 'center' );
@@ -83,6 +84,8 @@
 
 ve.mixinClass( ve.ce.MWBlockImageNode, ve.ce.ResizableNode );
 
+ve.mixinClass( ve.ce.MWBlockImageNode, ve.ce.RelocatableNode );
+
 /* Static Properties */
 
 ve.ce.MWBlockImageNode.static.name = 'mwBlockImage';
diff --git a/modules/ve/ce/nodes/ve.ce.MWInlineImageNode.js 
b/modules/ve/ce/nodes/ve.ce.MWInlineImageNode.js
index eb9e9f2..f373163 100644
--- a/modules/ve/ce/nodes/ve.ce.MWInlineImageNode.js
+++ b/modules/ve/ce/nodes/ve.ce.MWInlineImageNode.js
@@ -35,6 +35,7 @@
        // Mixin constructors
        ve.ce.ProtectedNode.call( this );
        ve.ce.FocusableNode.call( this );
+       ve.ce.RelocatableNode.call( this );
 
        this.$image
                .attr( 'src', this.model.getAttribute( 'src' ) )
@@ -62,6 +63,8 @@
 
 ve.mixinClass( ve.ce.MWInlineImageNode, ve.ce.FocusableNode );
 
+ve.mixinClass( ve.ce.MWInlineImageNode, ve.ce.RelocatableNode );
+
 /* Static Properties */
 
 ve.ce.MWInlineImageNode.static.name = 'mwInlineImage';
diff --git a/modules/ve/ce/styles/ve.ce.Node.css 
b/modules/ve/ce/styles/ve.ce.Node.css
index e51f48b..6d61749 100644
--- a/modules/ve/ce/styles/ve.ce.Node.css
+++ b/modules/ve/ce/styles/ve.ce.Node.css
@@ -70,24 +70,17 @@
 
 /* ve.ce.ResizableNode */
 
-.ve-ce-resizableNode-transitioning {
-       -webkit-transition: width 100ms ease-in-out, height 100ms ease-in-out;
-       -moz-transition: width 100ms ease-in-out, height 100ms ease-in-out;
-       -ms-transition: width 100ms ease-in-out, height 100ms ease-in-out;
-       -o-transition: width 100ms ease-in-out, height 100ms ease-in-out;
-       transition: width 100ms ease-in-out, height 100ms ease-in-out;
-}
-
-.ve-ce-resizableNode-handles-resizing {
-       z-index: 10000;
-}
-
 .ve-ce-resizableNode-handles {
        position: absolute;
        box-shadow: inset 0 0 0 1px rgba(0,0,0,.25);
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
+       z-index: 1; /* Position above RelocatableNode's relocatableMarker */
+}
+
+.ve-ce-resizableNode-handles.resizing {
+       z-index: 10000;
 }
 
 .ve-ce-resizableNode-handles div {
@@ -127,6 +120,17 @@
        right: -0.33em;
 }
 
+/* ve.ce.RelocatableNode */
+
+.ve-ce-relocatableMarker {
+       cursor: move;
+       position: absolute;
+}
+
+.ve-ce-relocatableMarker.relocating {
+       background: rgba(0,0,0,1);
+}
+
 /* ve.ce.ImageNode */
 
 .ve-ce-imageNode {
diff --git a/modules/ve/ce/ve.ce.RelocatableNode.js 
b/modules/ve/ce/ve.ce.RelocatableNode.js
index b87950a..2e026c4 100644
--- a/modules/ve/ce/ve.ce.RelocatableNode.js
+++ b/modules/ve/ce/ve.ce.RelocatableNode.js
@@ -8,31 +8,71 @@
 /**
  * ContentEditable relocatable node.
  *
+ * Requires that the node also is Focusable
+ *
  * @class
  * @abstract
  *
  * @constructor
- * @param {jQuery} [$draggable=this.$] Draggable DOM element
  */
-ve.ce.RelocatableNode = function VeCeRelocatableNode( $draggable ) {
+ve.ce.RelocatableNode = function VeCeRelocatableNode() {
        // Properties
-       this.$draggable = $draggable || this.$;
        this.relocatingSurface = null;
+       this.$relocatableMarker = $('<img>');
 
        // Events
-       this.$draggable.on( {
-               'dragstart': ve.bind( this.onRelocatableDragStart, this ),
-               'dragend': ve.bind( this.onRelocatableDragEnd, this )
+       this.connect( this, {
+               'focus': 'onRelocatableFocus',
+               'blur': 'onRelocatableBlur',
+               'resize': 'onRelocatableResize'
        } );
+
+       // Initialization
+       this.$relocatableMarker
+               .addClass( 've-ce-relocatableMarker' )
+               .attr('src', 
'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==')
+               .on( {
+                       'dragstart': ve.bind( this.onRelocatableDragStart, this 
),
+                       'dragend': ve.bind( this.onRelocatableDragEnd, this )
+               } );
 };
 
+/* Static Properties */
+
 /* Methods */
+
+/**
+ * Handle node focus.
+ *
+ * @method
+ */
+ve.ce.RelocatableNode.prototype.onRelocatableFocus = function () {
+       this.setRelocatableMarkerSizeAndPosition();
+       this.$relocatableMarker.appendTo( 
this.root.getSurface().getSurface().$localOverlay );
+};
+
+/**
+ * Handle node blur.
+ *
+ * @method
+ */
+ve.ce.RelocatableNode.prototype.onRelocatableBlur = function () {
+       this.$relocatableMarker.detach();
+};
+
+/**
+ * Handle node resize.
+ *
+ * @method
+ */
+ve.ce.RelocatableNode.prototype.onRelocatableResize = function () {
+       this.setRelocatableMarkerSizeAndPosition();
+};
 
 /**
  * Handle element drag start.
  *
  * @method
- * @param {jQuery.Event} e Drag start event
  */
 ve.ce.RelocatableNode.prototype.onRelocatableDragStart = function () {
        // Store a copy of the surface, when dragend occurs the node will be 
detached
@@ -42,17 +82,36 @@
                // Allow dragging this node in the surface
                this.relocatingSurface.startRelocation( this );
        }
+       this.$relocatableMarker.addClass('relocating');
+
+       setTimeout( ve.bind( function () {
+               this.$relocatableMarker.css( { 'top': -10000, 'left': -10000 } 
);
+       }, this ), 0 );
 };
 
 /**
  * Handle element drag end.
  *
  * @method
- * @param {jQuery.Event} e Drag end event
  */
 ve.ce.RelocatableNode.prototype.onRelocatableDragEnd = function () {
        if ( this.relocatingSurface ) {
                this.relocatingSurface.endRelocation();
                this.relocatingSurface = null;
        }
+       this.$relocatableMarker.removeClass('relocating');
+};
+
+/**
+ * Set the correct size and position of the relocatable marker.
+ *
+ * @method
+ */
+ve.ce.RelocatableNode.prototype.setRelocatableMarkerSizeAndPosition = function 
() {
+       this.$relocatableMarker.css({
+               'height': this.$.height(),
+               'width': this.$.width(),
+               'top': this.$.offset().top,
+               'left': this.$.offset().left
+       });
 };
diff --git a/modules/ve/ce/ve.ce.ResizableNode.js 
b/modules/ve/ce/ve.ce.ResizableNode.js
index 36bb9a5..c2a8b69 100644
--- a/modules/ve/ce/ve.ce.ResizableNode.js
+++ b/modules/ve/ce/ve.ce.ResizableNode.js
@@ -125,7 +125,7 @@
 
        // Set bounding box width and undo the handle margins
        this.$resizeHandles
-               .addClass( 've-ce-resizableNode-handles-resizing' )
+               .addClass( 'resizing' )
                .css( {
                        'width': this.$resizable.width(),
                        'height': this.$resizable.height()
@@ -248,7 +248,7 @@
                selection = surfaceModel.getSelection(),
                attrChanges = {};
 
-       this.$resizeHandles.removeClass( 've-ce-resizableNode-handles-resizing' 
);
+       this.$resizeHandles.removeClass( 'resizing' );
        $( this.getElementDocument() ).off( '.ve-ce-resizableNode' );
        this.resizing = false;
 
diff --git a/modules/ve/ce/ve.ce.Surface.js b/modules/ve/ce/ve.ce.Surface.js
index 1fbea19..f0bc192 100644
--- a/modules/ve/ce/ve.ce.Surface.js
+++ b/modules/ve/ce/ve.ce.Surface.js
@@ -378,7 +378,10 @@
                                nodeRange = node.getModel().getOuterRange();
 
                        // Get a fragment from the drop point
-                       dropPoint = rangy.positionFromPoint( 
e.originalEvent.pageX, e.originalEvent.pageY );
+                       dropPoint = rangy.positionFromPoint(
+                               e.originalEvent.pageX - 
this.$document.scrollLeft(),
+                               e.originalEvent.pageY - 
this.$document.scrollTop()
+                       );
                        if ( !dropPoint ) {
                                // Getting position from point supported
                                return false;

-- 
To view, visit https://gerrit.wikimedia.org/r/69279
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I755b698a3d968cc7e6ff125109d68ac83fd8a8a2
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Christian <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to