jenkins-bot has submitted this change and it was merged.

Change subject: T93973: Remove state from Cite extension
......................................................................


T93973: Remove state from Cite extension

Keep all state in the DOM post-processor in dom.processRefs.js, so
that there's no need to reset the extension and it can be safely
used for multiple documents

Change-Id: Iacf7e3003929f74b76774d3e765c792991700e51
---
M lib/dom.processRefs.js
M lib/ext.Cite.js
2 files changed, 96 insertions(+), 97 deletions(-)

Approvals:
  Subramanya Sastry: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/lib/dom.processRefs.js b/lib/dom.processRefs.js
index 18a0b62..c73f56d 100644
--- a/lib/dom.processRefs.js
+++ b/lib/dom.processRefs.js
@@ -1,6 +1,7 @@
 "use strict";
 
-var DU = require('./mediawiki.DOMUtils.js').DOMUtils;
+var DU = require('./mediawiki.DOMUtils.js').DOMUtils,
+       ReferencesData = require('./ext.Cite.js').ReferencesData;
 
 /* --------------------------------------------
  * This handles wikitext like this:
@@ -10,17 +11,19 @@
  * -------------------------------------------- */
 var _processRefs, _processRefsInReferences;
 
-_processRefsInReferences = function(cite, node, referencesId, referencesGroup, 
nestedRefsHTML) {
+_processRefsInReferences = function(cite, refsData, node, referencesId,
+                                                                       
referencesGroup, nestedRefsHTML) {
        var child = node.firstChild;
        while (child !== null) {
                var nextChild = child.nextSibling;
                if (DU.isElt(child)) {
                        var typeOf = child.getAttribute('typeof');
                        if 
((/(?:^|\s)mw:Extension\/ref\/Marker(?=$|\s)/).test(typeOf)) {
-                               cite.references.extractRefFromNode(child,
-                                       _processRefs.bind(null, cite), 
referencesId, referencesGroup, nestedRefsHTML);
+                               cite.references.extractRefFromNode(child, 
refsData,
+                                       _processRefs.bind(null, cite, refsData),
+                                       referencesId, referencesGroup, 
nestedRefsHTML);
                        } else if (child.childNodes.length > 0) {
-                               _processRefsInReferences(cite,
+                               _processRefsInReferences(cite, refsData,
                                        child, referencesId, referencesGroup, 
nestedRefsHTML);
                        }
                }
@@ -29,23 +32,23 @@
        }
 };
 
-_processRefs = function(cite, node) {
+_processRefs = function(cite, refsData, node) {
        var child = node.firstChild;
        while (child !== null) {
                var nextChild = child.nextSibling;
                if (DU.isElt(child)) {
                        var typeOf = child.getAttribute('typeof');
                        if 
((/(?:^|\s)mw:Extension\/ref\/Marker(?=$|\s)/).test(typeOf)) {
-                               cite.references.extractRefFromNode(child, 
_processRefs.bind(null, cite));
+                               cite.references.extractRefFromNode(child, 
refsData, _processRefs.bind(null, cite));
                        } else if 
((/(?:^|\s)mw:Extension\/references(?=$|\s)/).test(typeOf)) {
                                var referencesId = child.getAttribute("about");
                                var referencesGroup = 
DU.getDataParsoid(child).group;
                                var nestedRefsHTML = ["\n"];
-                               _processRefsInReferences(cite,
+                               _processRefsInReferences(cite, refsData,
                                        child, referencesId, referencesGroup, 
nestedRefsHTML);
-                               cite.references.insertReferencesIntoDOM(child, 
nestedRefsHTML);
+                               cite.references.insertReferencesIntoDOM(child, 
refsData, nestedRefsHTML);
                        } else if (child.childNodes.length > 0) {
-                               _processRefs(cite, child);
+                               _processRefs(cite, refsData, child);
                        }
                }
 
@@ -55,15 +58,9 @@
 
 function processRefs(cite, node, env, options, atTopLevel) {
        if (atTopLevel) {
-               _processRefs(cite, node);
-               cite.references.insertMissingReferencesIntoDOM(env, node);
-               // We have a broken design where all native extension objects
-               // are reused across all documents. So, given that Cite is
-               // maintaining object state (during a sync pass => it need not 
do that),
-               // we need to reset state so that other documents that are
-               // in the middle of being processed don't use that state.
-               // Future patches will fix both of these design issues.
-               cite.resetState({toplevel: true});
+               var refsData = new ReferencesData();
+               _processRefs(cite, refsData, node);
+               cite.references.insertMissingReferencesIntoDOM(env, refsData, 
node);
        }
 }
 
diff --git a/lib/ext.Cite.js b/lib/ext.Cite.js
index 0e11b86..80f6076 100644
--- a/lib/ext.Cite.js
+++ b/lib/ext.Cite.js
@@ -161,53 +161,6 @@
        return encodeURIComponent(v).replace(/%/g,".");
 }
 
-RefGroup.prototype.add = function(references, refName, about, skipLinkback) {
-       var ref;
-       refName = makeValidIdAttr(refName);
-       if ( refName && this.indexByName.has( refName ) ) {
-               ref = this.indexByName.get( refName );
-               if (ref.content) {
-                               ref.hasMultiples = true;
-               }
-       } else {
-               // The ids produced Cite.php have some particulars:
-               // Simple refs get 'cite_ref-' + index
-               // Refs with names get 'cite_ref-' + name + '_' + index + 
(backlink num || 0)
-               // Notes (references) whose ref doesn't have a name are 
'cite_note-' + index
-               // Notes whose ref has a name are 'cite_note-' + name + '-' + 
index
-               var n = references.index,
-                       refKey = (1+n) + '',
-                       refIdBase = 'cite_ref-' + (refName ? refName + '_' + 
refKey : refKey),
-                       noteId = 'cite_note-' + (refName ? refName + '-' + 
refKey : refKey);
-
-               // bump index
-               references.index += 1;
-
-               ref = {
-                       about: about,
-                       content: null,
-                       group: this.name,
-                       groupIndex: this.refs.length + 1,
-                       index: n,
-                       key: refIdBase,
-                       id: (refName ? refIdBase + '-0' : refIdBase),
-                       linkbacks: [],
-                       name: refName,
-                       target: noteId
-               };
-               this.refs.push( ref );
-               if (refName) {
-                       this.indexByName.set( refName, ref );
-               }
-       }
-
-       if (!skipLinkback) {
-               ref.linkbacks.push(ref.key + '-' + ref.linkbacks.length);
-       }
-
-       return ref;
-};
-
 RefGroup.prototype.renderLine = function(refsList, ref) {
        var ownerDoc = refsList.ownerDocument,
                arrow = ownerDoc.createTextNode('↑'),
@@ -262,32 +215,80 @@
        refsList.appendChild(li);
 };
 
-function getRefGroup(refGroups, groupName, allocIfMissing) {
-       groupName = groupName || '';
-       if ( !refGroups.has( groupName ) && allocIfMissing ) {
-               refGroups.set( groupName, new RefGroup( groupName ) );
-       }
-       return refGroups.get( groupName );
+function ReferencesData() {
+       this.index = 0;
+       this.refGroups = new Map();
 }
+
+ReferencesData.prototype.getRefGroup = function (groupName, allocIfMissing) {
+       groupName = groupName || '';
+       if ( !this.refGroups.has( groupName ) && allocIfMissing ) {
+               this.refGroups.set( groupName, new RefGroup( groupName ) );
+       }
+       return this.refGroups.get( groupName );
+};
+
+ReferencesData.prototype.removeRefGroup = function (groupName) {
+       if (groupName !== null && groupName !== undefined) {
+               // '' is a valid group (the default group)
+               this.refGroups.delete(groupName);
+       }
+};
+
+ReferencesData.prototype.add = function(groupName, refName, about, 
skipLinkback) {
+       var group = this.getRefGroup(groupName, true),
+               ref;
+       refName = makeValidIdAttr(refName);
+       if ( refName && group.indexByName.has( refName ) ) {
+               ref = group.indexByName.get( refName );
+               if (ref.content) {
+                               ref.hasMultiples = true;
+               }
+       } else {
+               // The ids produced Cite.php have some particulars:
+               // Simple refs get 'cite_ref-' + index
+               // Refs with names get 'cite_ref-' + name + '_' + index + 
(backlink num || 0)
+               // Notes (references) whose ref doesn't have a name are 
'cite_note-' + index
+               // Notes whose ref has a name are 'cite_note-' + name + '-' + 
index
+               var n = this.index,
+                       refKey = (1+n) + '',
+                       refIdBase = 'cite_ref-' + (refName ? refName + '_' + 
refKey : refKey),
+                       noteId = 'cite_note-' + (refName ? refName + '-' + 
refKey : refKey);
+
+               // bump index
+               this.index += 1;
+
+               ref = {
+                       about: about,
+                       content: null,
+                       group: group.name,
+                       groupIndex: group.refs.length + 1,
+                       index: n,
+                       key: refIdBase,
+                       id: (refName ? refIdBase + '-0' : refIdBase),
+                       linkbacks: [],
+                       name: refName,
+                       target: noteId
+               };
+               group.refs.push( ref );
+               if (refName) {
+                       group.indexByName.set( refName, ref );
+               }
+       }
+
+       if (!skipLinkback) {
+               ref.linkbacks.push(ref.key + '-' + ref.linkbacks.length);
+       }
+
+       return ref;
+};
 
 function References(cite) {
        this.cite = cite;
-       this.reset( null, true );
+       this.reset();
 }
 
-References.prototype.reset = function( group, resetIndex ) {
-       if (group !== null && group !== undefined) {
-               // '' is a valid group (the default group)
-               this.refGroups.delete(group);
-       } else {
-               this.refGroups = new Map();
-       }
-
-       // restart reference counter
-       if ( resetIndex ) {
-               this.index = 0;
-       }
-};
+References.prototype.reset = function() {};
 
 /**
  * Sanitize the references tag and convert it into a meta-token
@@ -357,7 +358,8 @@
        });
 };
 
-References.prototype.extractRefFromNode = function(node, refInRefProcessor, 
referencesAboutId, referencesGroup, refsInReferencesHTML) {
+References.prototype.extractRefFromNode = function(node, refsData,
+               refInRefProcessor, referencesAboutId, referencesGroup, 
refsInReferencesHTML) {
        var nestedInReferences = referencesAboutId !== undefined,
                dp = DU.getDataParsoid( node ),
                // SSS FIXME: Need to clarify semantics here.
@@ -366,8 +368,7 @@
                group = dp.group || referencesGroup || '',
                refName = dp.name,
                about = node.getAttribute("about"),
-               refGroup = getRefGroup(this.refGroups, group, true),
-               ref = refGroup.add(this, refName, about, nestedInReferences),
+               ref = refsData.add(group, refName, about, nestedInReferences),
                nodeType = (node.getAttribute("typeof") || 
'').replace(/mw:Extension\/ref\/Marker/, '');
 
        // Add ref-index linkback
@@ -449,14 +450,14 @@
        }
 };
 
-References.prototype.insertReferencesIntoDOM = function(refsNode, 
refsInReferencesHTML) {
+References.prototype.insertReferencesIntoDOM = function(refsNode, refsData, 
refsInReferencesHTML) {
        var about = refsNode.getAttribute('about'),
                dp = DU.getDataParsoid( refsNode ),
                group = dp.group || '',
                src = dp.src || '<references/>', // fall back so we don't crash
                // Extract ext-source for <references>..</references> usage
                body = Util.extractExtBody("references", src).trim(),
-               refGroup = getRefGroup(this.refGroups, group);
+               refGroup = refsData.getRefGroup(group);
 
        var dataMW =  DU.getDataMw(refsNode);
        if (!Object.keys(dataMW).length) {
@@ -495,15 +496,15 @@
                refGroup.refs.forEach(refGroup.renderLine.bind(refGroup, 
refsNode));
        }
 
-       // reset
-       this.reset(group);
+       // Remove the group from refsData
+       refsData.removeRefGroup(group);
 };
 
-References.prototype.insertMissingReferencesIntoDOM = function (env, node) {
+References.prototype.insertMissingReferencesIntoDOM = function (env, refsData, 
node) {
        var doc = node.ownerDocument,
                self = this;
 
-       this.refGroups.forEach(function (refsData, refsGroup) {
+       refsData.refGroups.forEach(function (refsValue, refsGroup) {
                var ol = doc.createElement('ol'),
                        dp = DU.getDataParsoid(ol);
                DU.addAttributes(ol, {
@@ -523,7 +524,7 @@
                // each <references /> tag appears on its own line.
                node.appendChild(doc.createTextNode("\n"));
                node.appendChild(ol);
-               self.insertReferencesIntoDOM(ol, [""]);
+               self.insertReferencesIntoDOM(ol, refsData, [""]);
        });
 };
 
@@ -539,10 +540,11 @@
 Cite.prototype.resetState = function(opts) {
        if (opts && opts.toplevel) {
                this.ref.reset();
-               this.references.reset( null, true );
+               this.references.reset();
        }
 };
 
 if (typeof module === "object") {
        module.exports.Cite = Cite;
+       module.exports.ReferencesData = ReferencesData;
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Iacf7e3003929f74b76774d3e765c792991700e51
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Marcoil <marc...@wikimedia.org>
Gerrit-Reviewer: Arlolra <abrea...@wikimedia.org>
Gerrit-Reviewer: Cscott <canan...@wikimedia.org>
Gerrit-Reviewer: Marcoil <marc...@wikimedia.org>
Gerrit-Reviewer: Subramanya Sastry <ssas...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to