MarkTraceur has uploaded a new change for review.
https://gerrit.wikimedia.org/r/54067
Change subject: Add documentation to DOMUtils
......................................................................
Add documentation to DOMUtils
Another patch for documentation, this time with only comment changes, and
only on one file. Also added the filename to the jsduck conf.
Change-Id: I6168da8944650abb9787d284b87e3ec521f2f88d
---
M js/jsduck-conf.json
M js/lib/mediawiki.DOMUtils.js
2 files changed, 347 insertions(+), 28 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Parsoid
refs/changes/67/54067/1
diff --git a/js/jsduck-conf.json b/js/jsduck-conf.json
index 1a1f32a..01e8e8d 100644
--- a/js/jsduck-conf.json
+++ b/js/jsduck-conf.json
@@ -13,6 +13,7 @@
"./lib/ext.core.Sanitizer.js",
"./lib/ext.util.TokenCollector.js",
"./lib/mediawiki.ApiRequest.js",
+ "./lib/mediawiki.DOMUtils.js",
"./lib/mediawiki.ParsoidConfig.js",
"./lib/mediawiki.SelectiveSerializer.js",
"./lib/mediawiki.Title.js",
diff --git a/js/lib/mediawiki.DOMUtils.js b/js/lib/mediawiki.DOMUtils.js
index 3129485..35bcd80 100644
--- a/js/lib/mediawiki.DOMUtils.js
+++ b/js/lib/mediawiki.DOMUtils.js
@@ -1,22 +1,44 @@
"use strict";
-/**
- * General DOM utilities
- */
-
var Util = require('./mediawiki.Util.js').Util,
Node = require('./mediawiki.wikitext.constants.js').Node;
+/**
+ * @class
+ * @singleton
+ * General DOM utilities
+ */
var DOMUtils = {
+ /**
+ * @method
+ *
+ * Check whether this is an element node.
+ *
+ * @param {Node} node
+ * @returns {boolean}
+ */
isElt: function(node) {
return node.nodeType === Node.ELEMENT_NODE;
},
+ /**
+ * @method
+ * @param {Node} node
+ * @returns {boolean}
+ */
isBlockNode: function(node) {
return node && Util.isBlockTag(node.nodeName.toLowerCase());
},
- // Decode a JSON object into the data member of DOM nodes
+ /**
+ * @method
+ *
+ * Decode a JSON object into the data member of DOM nodes
+ *
+ * @param {Node} node
+ * @param {string} name We'll use the data-[name] attribute of the
passed-in node as the new value.
+ * @param {Mixed} defaultVal What to use if there is no JSON attribute
by that name.
+ */
loadDataAttrib: function(node, name, defaultVal) {
if ( ! node.data ) {
node.data = {};
@@ -27,7 +49,13 @@
// nothing to do if already loaded
},
- // Save all node.data.* structures to data attributes
+ /**
+ * @method
+ *
+ * Save all node.data.* structures to data attributes
+ *
+ * @param {Node} node
+ */
saveDataAttribs: function(node) {
for(var key in node.data) {
var val = node.data[key];
@@ -40,22 +68,57 @@
}
},
- // Decode data-parsoid into node.data.parsoid
+ /**
+ * @method
+ *
+ * Decode data-parsoid into node.data.parsoid
+ *
+ * @param {Node} node
+ */
loadDataParsoid: function(node) {
this.loadDataAttrib(node, 'parsoid', {});
},
-
+ /**
+ * @method
+ *
+ * Get the data-parsoid attribute from a node.
+ *
+ * TODO use this.getJSONAttribute
+ *
+ * @returns {Object} The contents of data-parsoid
+ */
dataParsoid: function(n) {
var str = n.getAttribute("data-parsoid");
return str ? JSON.parse(str) : {};
},
+ /**
+ * @method
+ *
+ * Set the data-parsoid attribute on a node.
+ *
+ * TODO use this.setJSONAttribute
+ *
+ * @param {Node} n
+ * @param {Object} dpObj The new value for data-parsoid
+ * @returns {Node}
+ */
setDataParsoid: function(n, dpObj) {
n.setAttribute("data-parsoid", JSON.stringify(dpObj));
return n;
},
+ /**
+ * @method
+ *
+ * Get an object from a JSON-encoded XML attribute on a node.
+ *
+ * @param {Node} n
+ * @param {string} name Name of the attribute
+ * @param {Mixed} defaultVal What should be returned if we fail to find
a valid JSON structure
+ * @returns {Object}
+ */
getJSONAttribute: function(n, name, defaultVal) {
var attVal = n.getAttribute(name);
if (!attVal) {
@@ -70,10 +133,32 @@
}
},
+ /**
+ * @method
+ *
+ * Set an attribute on a node to a JSON-encoded object.
+ *
+ * @param {Node} n
+ * @param {string} name Name of the attribute
+ * @param {Object} obj
+ */
setJSONAttribute: function(n, name, obj) {
n.setAttribute(name, JSON.stringify(obj));
},
+ /**
+ * @method
+ *
+ * Get shadowed information about an attribute on a node.
+ *
+ * @param {Node} node
+ * @param {string} name
+ * @param {Object} tplAttrs
+ * @returns {Object}
+ * @returns {Mixed} return.value
+ * @returns {boolean} return.modified If the value of the attribute
changed since we parsed the wikitext
+ * @returns {boolean} return.fromsrc Whether we got the value from
source-based roundtripping
+ */
getAttributeShadowInfo: function ( node, name, tplAttrs ) {
var curVal = node.getAttribute(name),
dp = node.data.parsoid;
@@ -124,6 +209,14 @@
}
},
+ /**
+ * @method
+ *
+ * Get the attributes on a node in an array of KV objects.
+ *
+ * @param {Node} node
+ * @returns {KV[]}
+ */
getAttributeKVArray: function(node) {
var attribs = node.attributes,
kvs = [];
@@ -134,10 +227,16 @@
return kvs;
},
-
-
- // Build path from n ---> ancestor
- // Doesn't include ancestor in the path itself
+ /**
+ * @method
+ *
+ * Build path from a node to its passed-in ancestor.
+ * Doesn't include the ancestor in the return value.
+ *
+ * @param {Node} n
+ * @param {Node} ancestor Should be an ancestor of n
+ * @returns {Node[]}
+ */
pathToAncestor: function (n, ancestor) {
var path = [];
while (n && n !== ancestor) {
@@ -148,13 +247,28 @@
return path;
},
+ /**
+ * @method
+ *
+ * Build path from a node to the root of the document.
+ *
+ * @param {Node} n
+ * @returns {Node[]}
+ */
pathToRoot: function(n) {
return this.pathToAncestor(n, null);
},
- // Build path from n ---> sibling (default)
- // If left is true, will build from sibling ---> n
- // Doesn't include sibling in the path in either case
+ /**
+ * @method
+ *
+ * Build path from a node to its passed-in sibling.
+ *
+ * @param {Node} n
+ * @param {Node} sibling
+ * @param {boolean} left Whether to go backwards, i.e., use
previousSibling instead of nextSibling.
+ * @returns {Node[]} Will not include the passed-in sibling.
+ */
pathToSibling: function(n, sibling, left) {
var path = [];
while (n && n !== sibling) {
@@ -165,7 +279,15 @@
return path;
},
- // Does 'n1' occur before 'n2 in their parent's children list?
+ /**
+ * @method
+ *
+ * Check whether a node comes before another node in their parent's
children list.
+ *
+ * @param {Node} n1 The node you expect to come first
+ * @param {Node} n2 Expected later sibling
+ * @returns {boolean}
+ */
inSiblingOrder: function(n1, n2) {
while (n1 && n1 !== n2) {
n1 = n1.nextSibling;
@@ -173,7 +295,15 @@
return n1 !== null;
},
- // Is 'n1' an ancestor of 'n2' in the DOM?
+ /**
+ * @method
+ *
+ * Check that a node is an ancestor of another node.
+ *
+ * @param {Node} n1 The suspected ancestor
+ * @param {Node} n2 The suspected descendant
+ * @returns {boolean}
+ */
isAncestorOf: function (n1, n2) {
while (n2 && n2 !== n1) {
n2 = n2.parentNode;
@@ -181,26 +311,75 @@
return n2 !== null;
},
+ /**
+ * @method
+ *
+ * Check whether a node's name is...
+ *
+ * @param {Node} n
+ * @param {string} name
+ * @returns {boolean}
+ */
hasNodeName: function(n, name) {
return n.nodeName.toLowerCase() === name;
},
+ /**
+ * @method
+ * @param {Node} n
+ * @param {string} name Passed into #hasNodeName
+ * @param {string} type Expected value of "typeof" attribute
+ * @returns {boolean}
+ */
isNodeOfType: function(n, name, type) {
return this.hasNodeName(n, name) && n.getAttribute("typeof")
=== type;
},
+ /**
+ * @method
+ *
+ * Check a node to see whether it's a meta with some typeof.
+ *
+ * @param {Node} n
+ * @param {string} type Passed into #isNodeOfType
+ * @returns {boolean}
+ */
isMarkerMeta: function(n, type) {
return this.isNodeOfType(n, "meta", type);
},
+ /**
+ * @method
+ *
+ * Check whether a meta's typeof indicates that it is a template
expansion.
+ *
+ * @param {string} nType
+ * @returns {boolean}
+ */
isTplMetaType: function(nType) {
return nType && nType.match(/\bmw:Object(\/[^\s]+)*\b/);
},
+ /**
+ * @method
+ *
+ * Check whether a meta's typeof indicates that it signifies an
expanded attribute.
+ *
+ * @param {string} nType
+ * @returns {boolean}
+ */
isExpandedAttrsMetaType: function(nType) {
return nType && nType.match(/\bmw:ExpandedAttrs(\/[^\s]+)*\b/);
},
+ /**
+ * @method
+ *
+ * Check whether a node is a meta tag that signifies a template
expansion.
+ *
+ * @param {Node} n
+ * @returns {boolean}
+ */
isTplMarkerMeta: function(n) {
return (
this.hasNodeName(n, "meta") &&
@@ -208,6 +387,14 @@
);
},
+ /**
+ * @method
+ *
+ * Check whether a node is a meta signifying the start of a template
expansion.
+ *
+ * @param {Node} n
+ * @returns {boolean}
+ */
isTplStartMarkerMeta: function(n) {
if (this.hasNodeName(n, "meta")) {
var t = n.getAttribute("typeof");
@@ -218,6 +405,14 @@
}
},
+ /**
+ * @method
+ *
+ * Check whether a node is a meta signifying the end of a template
expansion.
+ *
+ * @param {Node} n
+ * @returns {boolean}
+ */
isTplEndMarkerMeta: function(n) {
if (this.hasNodeName(n, "meta")) {
var t = n.getAttribute("typeof");
@@ -227,18 +422,53 @@
}
},
+ /**
+ * @method
+ *
+ * Check whether a node's data-parsoid object includes
+ * an indicator that the original wikitext was a literal
+ * HTML element (like table or p)
+ *
+ * @param {Object} dp
+ * @param {string/undefined} dp.stx
+ * @returns {boolean}
+ */
hasLiteralHTMLMarker: function(dp) {
return dp.stx === 'html';
},
+ /**
+ * @method
+ *
+ * Run a node through #hasLiteralHTMLMarker
+ *
+ * @param {Node} n
+ * @returns {boolean}
+ */
isLiteralHTMLNode: function(n) {
return this.hasLiteralHTMLMarker(this.dataParsoid(n));
},
+ /**
+ * @method
+ *
+ * Check whether a pre is caused by indentation in the original
wikitext.
+ *
+ * @param {Node} n
+ * @returns {boolean}
+ */
isIndentPre: function(n) {
return this.hasNodeName(n, "pre") && !this.isLiteralHTMLNode(n);
},
+ /**
+ * @method
+ *
+ * Check whether a node has any children that are elements.
+ *
+ * @param {Node} n
+ * @returns {boolean}
+ */
hasElementChild: function(node) {
var children = node.childNodes;
for (var i = 0, n = children.length; i < n; i++) {
@@ -250,7 +480,15 @@
return false;
},
- // This function tests if its end tag is outside a template.
+ /**
+ * @method
+ *
+ * Test if a node's end tag is outside a template.
+ *
+ * @param {Node} node
+ * @param {Object} dp The data-parsoid attribute of the node.
+ * @returns {boolean}
+ */
endTagOutsideTemplate: function(node, dp) {
if (dp.tsr) {
return true;
@@ -278,6 +516,14 @@
return false;
},
+ /**
+ * @method
+ *
+ * Find how much offset is necessary for the DSR of an
indent-originated pre tag.
+ *
+ * @param {TextNode} textNode
+ * @returns {number}
+ */
indentPreDSRCorrection: function(textNode) {
// NOTE: This assumes a text-node and doesn't check that it is
one.
var numNLs;
@@ -292,12 +538,20 @@
return numNLs && this.isIndentPre(textNode.parentNode) ? numNLs
: 0;
},
- // Check if node is an ELEMENT node belongs to a template/extension.
- //
- // NOTE: Use with caution. This technique works reliably for the
- // root level elements of tpl-content DOM subtrees since only they
- // are guaranteed to be marked and nested content might not
- // necessarily be marked.
+ /**
+ * @method
+ *
+ * Check if node is an ELEMENT node belongs to a template/extension.
+ *
+ * NOTE: Use with caution. This technique works reliably for the
+ * root level elements of tpl-content DOM subtrees since only they
+ * are guaranteed to be marked and nested content might not
+ * necessarily be marked.
+ *
+ * @param {MWParserEnvironment} env
+ * @param {Node} node
+ * @returns {boolean}
+ */
isTplElementNode: function(env, node) {
if (this.isElt(node)) {
var about = node.getAttribute('about');
@@ -308,18 +562,29 @@
},
/**
- * This method should return "true" for a node that can be edited in the
+ * @method
+ *
+ * Should return "true" for a node that can be edited in the
* VisualEditor extension. We're using this to basically ignore changes
on
* things that can't have changed, because nothing could possibly have
changed
* them.
*
* For now, template/extension content is not editable.
* TODO: Add anything else that is not covered here.
+ *
+ * @param {MWParserEnvironment} env
+ * @param {Node} someNode
+ * @returns {boolean}
*/
isNodeEditable: function(env, someNode) {
return !this.isTplElementNode(env, someNode);
},
+ /**
+ * @method
+ * @param {Token[]} tokBuf This is where the tokens get stored.
+ * @param {Node} node
+ */
convertDOMtoTokens: function(tokBuf, node) {
function domAttrsToTagAttrs(attrs) {
var out = [];
@@ -366,7 +631,12 @@
},
/**
- * Helper function to check for a change marker in data-ve-changed
structure
+ * @method
+ *
+ * Check for a change marker in a data-ve-changed structure
+ *
+ * @param {Object} dvec
+ * @returns {boolean}
*/
isModificationChangeMarker: function( dvec ) {
return dvec && (
@@ -376,6 +646,15 @@
);
},
+ /**
+ * @method
+ *
+ * Check whether a node has been changed in the DOM. Use
data-parsoid-diff.
+ *
+ * @param {Node} node
+ * @param {MWParserEnvironment} env
+ * @returns {boolean}
+ */
isNodeModified: function(node, env) {
if( node.nodeType !== node.ELEMENT_NODE ) {
return false;
@@ -387,6 +666,15 @@
return dpd.diff.indexOf('modified') !== -1;
},
+ /**
+ * @method
+ *
+ * Check that the diff markers on the node exist and are recent.
+ *
+ * @param {Node} node
+ * @param {MWParserEnvironment} env
+ * @returns {boolean}
+ */
hasCurrentDiffMark: function(node, env) {
if( !this.isElt(node)) {
return false;
@@ -395,6 +683,15 @@
return dpd !== null && dpd.id === env.page.id;
},
+ /**
+ * @method
+ *
+ * Set a diff marker on a node.
+ *
+ * @param {Node} node
+ * @param {MWParserEnvironment} env
+ * @param {string} change
+ */
setDiffMark: function(node, env, change) {
var dpd = this.getJSONAttribute(node, 'data-parsoid-diff',
null);
if (dpd !== null && dpd.id === env.page.id) {
@@ -414,7 +711,12 @@
},
/**
+ * @method
+ *
* Is a node representing inter-element ws?
+ *
+ * @param {Node} node
+ * @returns {boolean}
*/
isIEW: function (node) {
return node.nodeType === node.TEXT_NODE &&
@@ -429,7 +731,15 @@
(node.nextSibling && this.isElt(node.nextSibling))));
},
-
+ /**
+ * @method
+ *
+ * Make a span element to wrap some bare text.
+ *
+ * @param {TextNode} node
+ * @param {string} type The type for the wrapper span
+ * @returns {Element} The wrapper span
+ */
wrapTextInTypedSpan: function(node, type) {
var wrapperSpanNode = node.ownerDocument.createElement('span');
wrapperSpanNode.setAttribute('typeof', type);
@@ -440,7 +750,15 @@
return wrapperSpanNode;
},
-
+ /**
+ * @method
+ *
+ * Insert a meta element with the passed-in typeof attribute before a
node.
+ *
+ * @param {Node} node
+ * @param {string} type
+ * @returns {Element} The new meta.
+ */
prependTypedMeta: function(node, type) {
var meta = node.ownerDocument.createElement('meta');
meta.setAttribute('typeof', type);
--
To view, visit https://gerrit.wikimedia.org/r/54067
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6168da8944650abb9787d284b87e3ec521f2f88d
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Parsoid
Gerrit-Branch: master
Gerrit-Owner: MarkTraceur <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits