Trevor Parscal has uploaded a new change for review.

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


Change subject: Allow node focusing
......................................................................

Allow node focusing

*.php
* Added links to new file

ve.ce.ImageNode.js
* Added focusable node mixin

ve.ce.FocusableNode.js
* New class!
* Adds isFocused and setFocused methods
* When a node is focused or blurred, 'focus' and 'blur' events are emitted
* While a node is focused, it will have the 've-ce-node-focused' class added to 
it's this.$

ve.ce.Surface.js
* Add detection of node focusing and setting focus and blur on nodes on change

Change-Id: I3f1ad6309571f2bfe568550e2e8f1bd5a0302085
---
M VisualEditor.php
M demos/ve/index.php
M modules/ve/ce/nodes/ve.ce.ImageNode.js
A modules/ve/ce/ve.ce.FocusableNode.js
M modules/ve/ce/ve.ce.Surface.js
M modules/ve/test/index.php
6 files changed, 104 insertions(+), 2 deletions(-)


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

diff --git a/VisualEditor.php b/VisualEditor.php
index f97bce1..e8a478c 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -301,6 +301,7 @@
                        've/ce/ve.ce.BranchNode.js',
                        've/ce/ve.ce.ContentBranchNode.js',
                        've/ce/ve.ce.LeafNode.js',
+                       've/ce/ve.ce.FocusableNode.js',
                        've/ce/ve.ce.Surface.js',
                        've/ce/ve.ce.SurfaceObserver.js',
 
diff --git a/demos/ve/index.php b/demos/ve/index.php
index 57cd489..de8fc24 100644
--- a/demos/ve/index.php
+++ b/demos/ve/index.php
@@ -181,6 +181,7 @@
                <script src="../../modules/ve/ce/ve.ce.BranchNode.js"></script>
                <script 
src="../../modules/ve/ce/ve.ce.ContentBranchNode.js"></script>
                <script src="../../modules/ve/ce/ve.ce.LeafNode.js"></script>
+               <script 
src="../../modules/ve/ce/ve.ce.FocusableNode.js"></script>
                <script src="../../modules/ve/ce/ve.ce.Surface.js"></script>
                <script 
src="../../modules/ve/ce/ve.ce.SurfaceObserver.js"></script>
                <script 
src="../../modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js"></script>
diff --git a/modules/ve/ce/nodes/ve.ce.ImageNode.js 
b/modules/ve/ce/nodes/ve.ce.ImageNode.js
index 55966be..503eaec 100644
--- a/modules/ve/ce/nodes/ve.ce.ImageNode.js
+++ b/modules/ve/ce/nodes/ve.ce.ImageNode.js
@@ -10,12 +10,17 @@
  *
  * @class
  * @extends ve.ce.LeafNode
+ * @mixins ve.ce.FocusableNode
+ *
  * @constructor
  * @param {ve.dm.ImageNode} model Model to observe
  */
 ve.ce.ImageNode = function VeCeImageNode( model ) {
        // Parent constructor
        ve.ce.LeafNode.call( this, model, $( '<img>' ) );
+
+       // Mixin constructors
+       ve.ce.FocusableNode.call( this );
 
        // Events
        this.model.addListenerMethod( this, 'update', 'onUpdate' );
@@ -34,6 +39,8 @@
 
 ve.inheritClass( ve.ce.ImageNode, ve.ce.LeafNode );
 
+ve.mixinClass( ve.ce.ImageNode, ve.ce.FocusableNode );
+
 /* Static Properties */
 
 ve.ce.ImageNode.static.name = 'image';
diff --git a/modules/ve/ce/ve.ce.FocusableNode.js 
b/modules/ve/ce/ve.ce.FocusableNode.js
new file mode 100644
index 0000000..fb8cebf
--- /dev/null
+++ b/modules/ve/ce/ve.ce.FocusableNode.js
@@ -0,0 +1,64 @@
+/*!
+ * VisualEditor ContentEditable FocusableNode class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * ContentEditable resizable node.
+ *
+ * @class
+ * @abstract
+ *
+ * @constructor
+ * @param {jQuery} [$resizable=this.$] Focusable DOM element
+ */
+ve.ce.FocusableNode = function VeCeFocusableNode() {
+       // Properties
+       this.focused = false;
+};
+
+/* Events */
+
+/**
+ * @event focus
+ */
+
+/**
+ * @event blur
+ */
+
+/* Methods */
+
+/**
+ * Check if node is focused.
+ *
+ * @method
+ * @returns {boolean} Node is focused
+ */
+ve.ce.FocusableNode.prototype.isFocused = function () {
+       return this.focused;
+};
+
+/**
+ * Set the selected state of the node.
+ *
+ * @method
+ * @param {boolean} value Node is focused
+ * @emits focus
+ * @emits blur
+ */
+ve.ce.FocusableNode.prototype.setFocused = function ( value ) {
+       value = !!value;
+       if ( this.focused !== value ) {
+               this.focused = value;
+               if ( this.focused ) {
+                       this.emit( 'focus' );
+                       this.$.addClass( 've-ce-node-focused' );
+               } else {
+                       this.emit( 'blur' );
+                       this.$.removeClass( 've-ce-node-focused' );
+               }
+       }
+};
diff --git a/modules/ve/ce/ve.ce.Surface.js b/modules/ve/ce/ve.ce.Surface.js
index 75eb836..68b899b 100644
--- a/modules/ve/ce/ve.ce.Surface.js
+++ b/modules/ve/ce/ve.ce.Surface.js
@@ -37,6 +37,7 @@
        this.$pasteTarget = $( '<div>' );
        this.pasting = false;
        this.clickHistory = [];
+       this.focusedNode = null;
 
        // Events
        this.surfaceObserver.addListenerMethods(
@@ -530,8 +531,35 @@
  * @param {ve.Range|undefined} selection
  */
 ve.ce.Surface.prototype.onChange = function ( transaction, selection ) {
-       if ( selection && this.isRenderingEnabled() ) {
-               this.showSelection( selection );
+       var start, end,
+               next = null,
+               previous = this.focusedNode;
+
+       if ( selection ) {
+               if ( this.isRenderingEnabled() ) {
+                       this.showSelection( selection );
+               }
+               // Detect when only a single inline element is selected
+               if ( !selection.isCollapsed() ) {
+                       start = 
this.documentView.getDocumentNode().getNodeFromOffset( selection.start + 1 );
+                       if ( typeof start.setFocused === 'function' ) {
+                               end = 
this.documentView.getDocumentNode().getNodeFromOffset( selection.end - 1 );
+                               if ( start === end ) {
+                                       next = start;
+                               }
+                       }
+               }
+               // Update nodes if something changed
+               if ( previous !== next ) {
+                       if ( previous ) {
+                               previous.setFocused( false );
+                               this.focusedNode = null;
+                       }
+                       if ( next ) {
+                               next.setFocused( true );
+                               this.focusedNode = start;
+                       }
+               }
        }
 };
 
diff --git a/modules/ve/test/index.php b/modules/ve/test/index.php
index fe9ccda..14f0296 100644
--- a/modules/ve/test/index.php
+++ b/modules/ve/test/index.php
@@ -124,6 +124,7 @@
                <script src="../../ve/ce/ve.ce.BranchNode.js"></script>
                <script src="../../ve/ce/ve.ce.ContentBranchNode.js"></script>
                <script src="../../ve/ce/ve.ce.LeafNode.js"></script>
+               <script src="../../ve/ce/ve.ce.FocusableNode.js"></script>
                <script src="../../ve/ce/ve.ce.Surface.js"></script>
                <script src="../../ve/ce/ve.ce.SurfaceObserver.js"></script>
                <script 
src="../../ve/ce/nodes/ve.ce.GeneratedContentNode.js"></script>

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

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

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

Reply via email to