jenkins-bot has submitted this change and it was merged.
Change subject: [BREAKING CHANGE] Create ve.dm.Focusable and store focusable
flag there
......................................................................
[BREAKING CHANGE] Create ve.dm.Focusable and store focusable flag there
Eventually all selection logic should be in the model, and as
focusable nodes behave differently, this information needs to
be in the model too.
Change-Id: Ib381510366f8c8ebb7a67af627178490ff6a736e
---
M .docs/eg-iframe.html
M build/modules.json
M demos/ve/desktop.html
M demos/ve/mobile.html
M src/ce/ve.ce.Document.js
M src/ce/ve.ce.FocusableNode.js
M src/ce/ve.ce.Node.js
M src/ce/ve.ce.NodeFactory.js
M src/ce/ve.ce.ResizableNode.js
M src/ce/ve.ce.Surface.js
M src/dm/nodes/ve.dm.AlienNode.js
M src/dm/nodes/ve.dm.CommentNode.js
M src/dm/nodes/ve.dm.ImageNode.js
A src/dm/ve.dm.FocusableNode.js
M src/dm/ve.dm.Node.js
M src/dm/ve.dm.NodeFactory.js
M src/dm/ve.dm.ResizableNode.js
M tests/index.html
18 files changed, 104 insertions(+), 50 deletions(-)
Approvals:
Catrope: Looks good to me, approved
jenkins-bot: Verified
diff --git a/.docs/eg-iframe.html b/.docs/eg-iframe.html
index cc89fcb..fc795ac 100644
--- a/.docs/eg-iframe.html
+++ b/.docs/eg-iframe.html
@@ -125,6 +125,7 @@
<script src="../src/dm/ve.dm.AnnotationFactory.js"></script>
<script src="../src/dm/ve.dm.AnnotationSet.js"></script>
<script src="../src/dm/ve.dm.MetaItemFactory.js"></script>
+ <script src="../src/dm/ve.dm.FocusableNode.js"></script>
<script src="../src/dm/ve.dm.Scalable.js"></script>
<script src="../src/dm/ve.dm.ResizableNode.js"></script>
<script src="../src/dm/ve.dm.Node.js"></script>
diff --git a/build/modules.json b/build/modules.json
index c0b0bbc..3ea5cd5 100644
--- a/build/modules.json
+++ b/build/modules.json
@@ -145,6 +145,7 @@
"src/dm/ve.dm.AnnotationFactory.js",
"src/dm/ve.dm.AnnotationSet.js",
"src/dm/ve.dm.MetaItemFactory.js",
+ "src/dm/ve.dm.FocusableNode.js",
"src/dm/ve.dm.Scalable.js",
"src/dm/ve.dm.ResizableNode.js",
"src/dm/ve.dm.Node.js",
diff --git a/demos/ve/desktop.html b/demos/ve/desktop.html
index f860c0c..ca883ec 100644
--- a/demos/ve/desktop.html
+++ b/demos/ve/desktop.html
@@ -138,6 +138,7 @@
<script src="../../src/dm/ve.dm.AnnotationFactory.js"></script>
<script src="../../src/dm/ve.dm.AnnotationSet.js"></script>
<script src="../../src/dm/ve.dm.MetaItemFactory.js"></script>
+ <script src="../../src/dm/ve.dm.FocusableNode.js"></script>
<script src="../../src/dm/ve.dm.Scalable.js"></script>
<script src="../../src/dm/ve.dm.ResizableNode.js"></script>
<script src="../../src/dm/ve.dm.Node.js"></script>
diff --git a/demos/ve/mobile.html b/demos/ve/mobile.html
index 55c3be4..4258cf3 100644
--- a/demos/ve/mobile.html
+++ b/demos/ve/mobile.html
@@ -139,6 +139,7 @@
<script src="../../src/dm/ve.dm.AnnotationFactory.js"></script>
<script src="../../src/dm/ve.dm.AnnotationSet.js"></script>
<script src="../../src/dm/ve.dm.MetaItemFactory.js"></script>
+ <script src="../../src/dm/ve.dm.FocusableNode.js"></script>
<script src="../../src/dm/ve.dm.Scalable.js"></script>
<script src="../../src/dm/ve.dm.ResizableNode.js"></script>
<script src="../../src/dm/ve.dm.Node.js"></script>
diff --git a/src/ce/ve.ce.Document.js b/src/ce/ve.ce.Document.js
index 8ea5658..65ab884 100644
--- a/src/ce/ve.ce.Document.js
+++ b/src/ce/ve.ce.Document.js
@@ -107,7 +107,7 @@
adjacentDataOffset = offset + ( direction > 0 ? 0 : -1 );
if (
data.isElementData( adjacentDataOffset ) &&
- ve.ce.nodeFactory.isNodeFocusable( data.getType(
adjacentDataOffset ) )
+ ve.dm.nodeFactory.isNodeFocusable( data.getType(
adjacentDataOffset ) )
) {
// We are adjacent to a focusableNode, move inside it
return offset + direction;
@@ -120,7 +120,7 @@
} else {
isFocusable = ( relativeStructuralOffset - offset < 0 ?
-1 : 1 ) === direction &&
data.isElementData( relativeStructuralOffset +
direction ) &&
- ve.ce.nodeFactory.isNodeFocusable(
data.getType( relativeStructuralOffset + direction ) );
+ ve.dm.nodeFactory.isNodeFocusable(
data.getType( relativeStructuralOffset + direction ) );
}
// Check if we've moved into a slug or a focusableNode
if ( isFocusable || this.getSlugAtOffset(
relativeStructuralOffset ) ) {
@@ -243,14 +243,14 @@
}
if (
this.isOpenElementData( index ) &&
- ve.ce.nodeFactory.isNodeFocusable(
this.getType( index ) )
+ ve.dm.nodeFactory.isNodeFocusable(
this.getType( index ) )
) {
coveredOffset = index + 1;
return true;
}
if (
this.isCloseElementData( index ) &&
- ve.ce.nodeFactory.isNodeFocusable(
this.getType( index ) )
+ ve.dm.nodeFactory.isNodeFocusable(
this.getType( index ) )
) {
coveredOffset = index;
return true;
diff --git a/src/ce/ve.ce.FocusableNode.js b/src/ce/ve.ce.FocusableNode.js
index 74bcf4a..8bfa15a 100644
--- a/src/ce/ve.ce.FocusableNode.js
+++ b/src/ce/ve.ce.FocusableNode.js
@@ -46,6 +46,10 @@
} );
};
+/* Inheritance */
+
+OO.initClass( ve.ce.FocusableNode );
+
/* Events */
/**
@@ -55,12 +59,6 @@
/**
* @event blur
*/
-
-/* Static Methods */
-
-ve.ce.FocusableNode.static = {};
-
-ve.ce.FocusableNode.static.isFocusable = true;
/* Methods */
diff --git a/src/ce/ve.ce.Node.js b/src/ce/ve.ce.Node.js
index 75cd487..8cc5d8f 100644
--- a/src/ce/ve.ce.Node.js
+++ b/src/ce/ve.ce.Node.js
@@ -48,20 +48,6 @@
ve.ce.Node.static.splitOnEnter = false;
/**
- * Whether this node type can be focused.
- *
- * If this is set to true on a node, it should implement:
- *
- * setFocused( boolean val )
- * boolean isFocused()
- *
- * @static
- * @property
- * @inheritable
- */
-ve.ce.Node.static.isFocusable = false;
-
-/**
* Command to execute when Enter is pressed while this node is selected, or
when the node is double-clicked.
*
* @static
@@ -177,11 +163,17 @@
/**
* Check if the node is focusable
*
- * @see #static-isFocusable
+ * This method passes through to the model.
+ *
+ * If this is set to true on a node, it should implement:
+ *
+ * setFocused( boolean val )
+ * boolean isFocused()
+ *
* @returns {boolean} Node is focusable
*/
ve.ce.Node.prototype.isFocusable = function () {
- return this.constructor.static.isFocusable;
+ return this.model.isFocusable();
};
/**
diff --git a/src/ce/ve.ce.NodeFactory.js b/src/ce/ve.ce.NodeFactory.js
index 1768ead..6dc5948 100644
--- a/src/ce/ve.ce.NodeFactory.js
+++ b/src/ce/ve.ce.NodeFactory.js
@@ -53,21 +53,6 @@
};
/**
- * Check if the node is focusable.
- *
- * @method
- * @param {string} type Node type
- * @returns {boolean} Whether the node is focusable
- * @throws {Error} Unknown node type
- */
-ve.ce.NodeFactory.prototype.isNodeFocusable = function ( type ) {
- if ( type in this.registry ) {
- return this.registry[type].static.isFocusable;
- }
- throw new Error( 'Unknown node type: ' + type );
-};
-
-/**
* Get primary command for node type.
*
* @method
diff --git a/src/ce/ve.ce.ResizableNode.js b/src/ce/ve.ce.ResizableNode.js
index fd11d73..139698d 100644
--- a/src/ce/ve.ce.ResizableNode.js
+++ b/src/ce/ve.ce.ResizableNode.js
@@ -67,6 +67,8 @@
/* Inheritance */
+OO.initClass( ve.ce.ResizableNode );
+
/* Events */
/**
@@ -81,10 +83,6 @@
/**
* @event resizeEnd
*/
-
-/* Static Properties */
-
-ve.ce.ResizableNode.static = {};
/* Methods */
diff --git a/src/ce/ve.ce.Surface.js b/src/ce/ve.ce.Surface.js
index af231af..acc651d 100644
--- a/src/ce/ve.ce.Surface.js
+++ b/src/ce/ve.ce.Surface.js
@@ -2264,9 +2264,9 @@
}
// If the user tries to delete a focusable node from a
collapsed selection,
// just select the node and cancel the deletion.
- startNode =
documentView.getDocumentNode().getNodeFromOffset( offset + 1 );
+ startNode =
documentModel.getDocumentNode().getNodeFromOffset( offset + 1 );
if ( startNode.isFocusable() ) {
- model.setSelection(
startNode.getModel().getOuterRange() );
+ model.setSelection( startNode.getOuterRange() );
return;
}
}
diff --git a/src/dm/nodes/ve.dm.AlienNode.js b/src/dm/nodes/ve.dm.AlienNode.js
index b91dc08..1bf3216 100644
--- a/src/dm/nodes/ve.dm.AlienNode.js
+++ b/src/dm/nodes/ve.dm.AlienNode.js
@@ -11,6 +11,7 @@
* @class
* @abstract
* @extends ve.dm.LeafNode
+ * @mixins ve.dm.FocusableNode
* @mixins ve.dm.GeneratedContentNode
*
* @constructor
@@ -22,12 +23,15 @@
// Mixin constructors
ve.dm.GeneratedContentNode.call( this );
+ ve.dm.FocusableNode.call( this );
};
/* Inheritance */
OO.inheritClass( ve.dm.AlienNode, ve.dm.LeafNode );
+OO.mixinClass( ve.dm.AlienNode, ve.dm.FocusableNode );
+
OO.mixinClass( ve.dm.AlienNode, ve.dm.GeneratedContentNode );
/* Static members */
diff --git a/src/dm/nodes/ve.dm.CommentNode.js
b/src/dm/nodes/ve.dm.CommentNode.js
index 0794863..7510f19 100644
--- a/src/dm/nodes/ve.dm.CommentNode.js
+++ b/src/dm/nodes/ve.dm.CommentNode.js
@@ -9,18 +9,25 @@
* @class
* @abstract
* @extends ve.dm.LeafNode
+ * @mixins ve.dm.FocusableNode
*
* @constructor
* @param {Object} element Reference to element in meta-linmod
*/
ve.dm.CommentNode = function VeDmCommentNode( element ) {
+ // Parent constructor
ve.dm.CommentNode.super.call( this, element );
+
+ // Mixin constructors
+ ve.dm.FocusableNode.call( this );
};
/* Inheritance */
OO.inheritClass( ve.dm.CommentNode, ve.dm.LeafNode );
+OO.mixinClass( ve.dm.CommentNode, ve.dm.FocusableNode );
+
/* Static Properties */
ve.dm.CommentNode.static.isContent = true;
diff --git a/src/dm/nodes/ve.dm.ImageNode.js b/src/dm/nodes/ve.dm.ImageNode.js
index 073cc5b..88b1624 100644
--- a/src/dm/nodes/ve.dm.ImageNode.js
+++ b/src/dm/nodes/ve.dm.ImageNode.js
@@ -10,6 +10,7 @@
*
* @class
* @abstract
+ * @mixins ve.dm.FocusableNode
* @mixins ve.dm.ResizableNode
*
* @constructor
@@ -17,10 +18,15 @@
ve.dm.ImageNode = function VeDmImageNode() {
// Mixin constructor
ve.dm.ResizableNode.call( this );
+
+ // Mixin constructors
+ ve.dm.FocusableNode.call( this );
};
/* Inheritance */
+OO.mixinClass( ve.dm.ImageNode, ve.dm.FocusableNode );
+
OO.mixinClass( ve.dm.ImageNode, ve.dm.ResizableNode );
/* Methods */
diff --git a/src/dm/ve.dm.FocusableNode.js b/src/dm/ve.dm.FocusableNode.js
new file mode 100644
index 0000000..77dc540
--- /dev/null
+++ b/src/dm/ve.dm.FocusableNode.js
@@ -0,0 +1,23 @@
+/*!
+ * VisualEditor DataModel Focusable node.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * A mixin class for focusable nodes.
+ *
+ * @class
+ * @abstract
+ * @constructor
+ */
+ve.dm.FocusableNode = function VeDmFocusableNode() {};
+
+/* Inheritance */
+
+OO.initClass( ve.dm.FocusableNode );
+
+/* Static Properties */
+
+ve.dm.FocusableNode.static.isFocusable = true;
diff --git a/src/dm/ve.dm.Node.js b/src/dm/ve.dm.Node.js
index 7a830cc..f2921ff 100644
--- a/src/dm/ve.dm.Node.js
+++ b/src/dm/ve.dm.Node.js
@@ -99,6 +99,15 @@
ve.dm.Node.static.isContent = false;
/**
+ * Whether this node type can be focused. Focusable nodes react to selections
differently.
+ *
+ * @static
+ * @property {boolean}
+ * @inheritable
+ */
+ve.dm.Node.static.isFocusable = false;
+
+/**
* Whether this node type can contain content. The children of content
container nodes must be
* content nodes.
*
@@ -359,6 +368,16 @@
};
/**
+ * Check if the node is focusable.
+ *
+ * @method
+ * @returns {boolean} Node is focusable
+ */
+ve.dm.Node.prototype.isFocusable = function () {
+ return this.constructor.static.isFocusable;
+};
+
+/**
* Check if the node has significant whitespace.
*
* Can only be true if canContainContent is also true.
diff --git a/src/dm/ve.dm.NodeFactory.js b/src/dm/ve.dm.NodeFactory.js
index df64c10..539932b 100644
--- a/src/dm/ve.dm.NodeFactory.js
+++ b/src/dm/ve.dm.NodeFactory.js
@@ -194,6 +194,21 @@
};
/**
+ * Check if the node is focusable.
+ *
+ * @method
+ * @param {string} type Node type
+ * @returns {boolean} Whether the node is focusable
+ * @throws {Error} Unknown node type
+ */
+ve.dm.NodeFactory.prototype.isNodeFocusable = function ( type ) {
+ if ( type in this.registry ) {
+ return this.registry[type].static.isFocusable;
+ }
+ throw new Error( 'Unknown node type: ' + type );
+};
+
+/**
* Check if the node has significant whitespace.
*
* Can only be true if canContainContent is also true.
diff --git a/src/dm/ve.dm.ResizableNode.js b/src/dm/ve.dm.ResizableNode.js
index 483acb8..59d3c6a 100644
--- a/src/dm/ve.dm.ResizableNode.js
+++ b/src/dm/ve.dm.ResizableNode.js
@@ -14,12 +14,14 @@
* @abstract
* @constructor
*/
-ve.dm.ResizableNode = function VeDmResizableNode( config ) {
- config = config || {};
-
+ve.dm.ResizableNode = function VeDmResizableNode() {
this.scalable = null;
};
+/* Inheritance */
+
+OO.initClass( ve.dm.ResizableNode );
+
/**
* Get a scalable object for this node.
*
diff --git a/tests/index.html b/tests/index.html
index bb706f8..97e3c8f 100644
--- a/tests/index.html
+++ b/tests/index.html
@@ -86,6 +86,7 @@
<script src="../src/dm/ve.dm.AnnotationFactory.js"></script>
<script src="../src/dm/ve.dm.AnnotationSet.js"></script>
<script src="../src/dm/ve.dm.MetaItemFactory.js"></script>
+ <script src="../src/dm/ve.dm.FocusableNode.js"></script>
<script src="../src/dm/ve.dm.Scalable.js"></script>
<script src="../src/dm/ve.dm.ResizableNode.js"></script>
<script src="../src/dm/ve.dm.Node.js"></script>
--
To view, visit https://gerrit.wikimedia.org/r/159640
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib381510366f8c8ebb7a67af627178490ff6a736e
Gerrit-PatchSet: 3
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits