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

Change subject: Rewrite TOCWidget based on Linker::generateTOC
......................................................................


Rewrite TOCWidget based on Linker::generateTOC

Use the new node cache to find headings.

Change-Id: I5eb75c5db5ca466fd6f16a57c693c2a4458cff7c
---
M extension.json
M modules/ve-mw/ce/nodes/ve.ce.MWHeadingNode.js
M modules/ve-mw/dm/nodes/ve.dm.MWHeadingNode.js
M modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js
D modules/ve-mw/ui/styles/widgets/ve.ui.MWTocWidget.css
D modules/ve-mw/ui/widgets/ve.ui.MWTocItemWidget.js
M modules/ve-mw/ui/widgets/ve.ui.MWTocWidget.js
7 files changed, 122 insertions(+), 293 deletions(-)

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



diff --git a/extension.json b/extension.json
index 5a51d3d..7a1e53e 100644
--- a/extension.json
+++ b/extension.json
@@ -1131,7 +1131,6 @@
                                
"modules/ve-mw/ui/datatransferhandlers/ve.ui.MWWikitextStringTransferHandler.js",
                                
"modules/ve-mw/ui/widgets/ve.ui.MWAceEditorWidget.js",
                                
"modules/ve-mw/ui/widgets/ve.ui.MWTargetWidget.js",
-                               
"modules/ve-mw/ui/widgets/ve.ui.MWTocItemWidget.js",
                                "modules/ve-mw/ui/widgets/ve.ui.MWTocWidget.js",
                                
"modules/ve-mw/ui/dialogs/ve.ui.MWExtensionDialog.js",
                                
"modules/ve-mw/ui/dialogs/ve.ui.MWExtensionPreviewDialog.js",
@@ -1156,7 +1155,6 @@
                                
"modules/ve-mw/ui/styles/elements/ve.ui.MWExpandableErrorElement.css",
                                
"modules/ve-mw/ui/styles/tools/ve.ui.MWPopupTool.css",
                                
"modules/ve-mw/ui/styles/widgets/ve.ui.MWAceEditorWidget.css",
-                               
"modules/ve-mw/ui/styles/widgets/ve.ui.MWTocWidget.css",
                                
"modules/ve-mw/ui/styles/tools/ve.ui.MWEducationPopupTool.css"
                        ],
                        "skinStyles": {
diff --git a/modules/ve-mw/ce/nodes/ve.ce.MWHeadingNode.js 
b/modules/ve-mw/ce/nodes/ve.ce.MWHeadingNode.js
index 8154c21..6ff5bb7 100644
--- a/modules/ve-mw/ce/nodes/ve.ce.MWHeadingNode.js
+++ b/modules/ve-mw/ce/nodes/ve.ce.MWHeadingNode.js
@@ -14,9 +14,12 @@
  * @param {ve.dm.MWHeadingNode} model Model to observe
  * @param {Object} [config] Configuration options
  */
-ve.ce.MWHeadingNode = function VeCeMWHeadingNode( model, config ) {
+ve.ce.MWHeadingNode = function VeCeMWHeadingNode() {
        // Parent constructor
-       ve.ce.HeadingNode.call( this, model, config );
+       ve.ce.MWHeadingNode.super.apply( this, arguments );
+
+       // Events
+       this.model.connect( this, { update: 'onUpdate' } );
 };
 
 /* Inheritance */
@@ -45,9 +48,24 @@
        this.rebuildToc();
 };
 
+ve.ce.MWHeadingNode.prototype.onUpdate = function () {
+       var surface = this.surface,
+               node = this;
+
+       if ( surface && surface.mwTocWidget ) {
+               surface.getModel().getDocument().once( 'transact', function () {
+                       surface.mwTocWidget.updateNode( node );
+               } );
+       }
+};
+
 ve.ce.MWHeadingNode.prototype.rebuildToc = function () {
-       if ( this.surface && this.surface.mwTocWidget ) {
-               this.surface.mwTocWidget.rebuild();
+       var surface = this.surface;
+
+       if ( surface && surface.mwTocWidget ) {
+               surface.getModel().getDocument().once( 'transact', function () {
+                       surface.mwTocWidget.rebuild();
+               } );
        }
 };
 
diff --git a/modules/ve-mw/dm/nodes/ve.dm.MWHeadingNode.js 
b/modules/ve-mw/dm/nodes/ve.dm.MWHeadingNode.js
index 709aacc..f124425 100644
--- a/modules/ve-mw/dm/nodes/ve.dm.MWHeadingNode.js
+++ b/modules/ve-mw/dm/nodes/ve.dm.MWHeadingNode.js
@@ -17,7 +17,7 @@
  */
 ve.dm.MWHeadingNode = function VeDmMWHeadingNode() {
        // Parent constructor
-       ve.dm.HeadingNode.apply( this, arguments );
+       ve.dm.MWHeadingNode.super.apply( this, arguments );
 };
 
 /* Inheritance */
diff --git a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js 
b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js
index 99db24a..f4cb219 100644
--- a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js
+++ b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js
@@ -707,7 +707,8 @@
  * @inheritdoc
  */
 ve.init.mw.DesktopArticleTarget.prototype.surfaceReady = function () {
-       var surfaceReadyTime = ve.now(),
+       var surface = this.getSurface(),
+               surfaceReadyTime = ve.now(),
                target = this;
 
        if ( !this.activating ) {
@@ -720,18 +721,19 @@
 
        // TODO: mwTocWidget should probably live in a ve.ui.MWSurface subclass
        if ( mw.config.get( 'wgVisualEditorConfig' ).enableTocWidget ) {
-               this.getSurface().mwTocWidget = new ve.ui.MWTocWidget( 
this.getSurface() );
+               surface.mwTocWidget = new ve.ui.MWTocWidget( this.getSurface() 
);
+               surface.$element.before( surface.mwTocWidget.$element );
        }
 
        // Track how long it takes for the first transaction to happen
-       this.surface.getModel().getDocument().once( 'transact', function () {
+       surface.getModel().getDocument().once( 'transact', function () {
                ve.track( 'mwtiming.behavior.firstTransaction', {
                        duration: ve.now() - surfaceReadyTime,
                        targetName: target.constructor.static.trackingName
                } );
        } );
 
-       this.getSurface().getModel().getMetaList().connect( this, {
+       surface.getModel().getMetaList().connect( this, {
                insert: 'onMetaItemInserted',
                remove: 'onMetaItemRemoved'
        } );
@@ -1022,9 +1024,6 @@
        // Update UI
        promises.push( this.teardownToolbar() );
        this.restoreDocumentTitle();
-       if ( this.getSurface().mwTocWidget ) {
-               this.getSurface().mwTocWidget.teardown();
-       }
 
        if ( this.saveDialog ) {
                if ( this.saveDialog.isOpened() ) {
@@ -1036,9 +1035,14 @@
        }
 
        return $.when.apply( null, promises ).then( function () {
+               var surface;
                // Destroy surface
                while ( target.surfaces.length ) {
-                       target.surfaces.pop().destroy();
+                       surface = target.surfaces.pop();
+                       surface.destroy();
+                       if ( surface.mwTocWidget ) {
+                               surface.mwTocWidget.$element.remove();
+                       }
                }
                target.active = false;
        } );
diff --git a/modules/ve-mw/ui/styles/widgets/ve.ui.MWTocWidget.css 
b/modules/ve-mw/ui/styles/widgets/ve.ui.MWTocWidget.css
deleted file mode 100644
index 816438a..0000000
--- a/modules/ve-mw/ui/styles/widgets/ve.ui.MWTocWidget.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/*!
- * VisualEditor MediaWiki UserInterface MWTocWidget styles.
- *
- * @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
- */
-
-.ve-ui-mwTocWidget {
-       /* Margin to mock the standard appearance of TOC */
-       margin: 1em 0 0 0;
-}
-.ve-ui-mwTocWidget .toctoggle {
-       margin: 0.25em;
-}
-.ve-ui-mwTocWidget .toctoggle:before {
-       content: ' [';
-}
-.ve-ui-mwTocWidget .toctoggle:after {
-       content: '] ';
-}
-
-.ve-ui-mwTocWidget .tocnumber:after {
-       content: ' ';
-}
-
-.ve-ui-mwTocWidget a {
-       cursor: pointer;
-}
diff --git a/modules/ve-mw/ui/widgets/ve.ui.MWTocItemWidget.js 
b/modules/ve-mw/ui/widgets/ve.ui.MWTocItemWidget.js
deleted file mode 100644
index 435d9d2..0000000
--- a/modules/ve-mw/ui/widgets/ve.ui.MWTocItemWidget.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*!
- * VisualEditor UserInterface MWTocItemWidget class.
- *
- * @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
- */
-
-/**
- * Creates an item an item for the MWTocWidget
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} config TOC Item configuration
- * @cfg {ve.ce.Node} node ContentEditable node
- * @cfg {ve.ui.MWTocItemWidget} parent Parent toc item
- * @cfg {string} sectionPrefix TOC item section number
- * @cfg {number} tocLevel Depth level of the TOC item
- * @cfg {number} tocIndex Running count of TOC items
- *
- */
-ve.ui.MWTocItemWidget = function VeUiMWTocItemWidget( config ) {
-       // Parent constructor
-       OO.ui.Widget.call( this, config );
-
-       // Mixin Constructor
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: $( 
'<ul>' ) } ) );
-
-       config = config || {};
-
-       // Properties
-       this.node = config.node || null;
-       this.parent = config.parent;
-       this.sectionPrefix = config.sectionPrefix;
-       this.tocLevel = config.tocLevel;
-       this.tocIndex = config.tocIndex;
-
-       // Allows toc items to be optionally associated to a node.
-       // For the case of the zero level parent item.
-       if ( this.node ) {
-               this.$tocNumber = $( '<span>' ).addClass( 'tocnumber' )
-                       .text( this.sectionPrefix );
-               this.$tocText = $( '<span>' ).addClass( 'toctext' )
-                       .text( this.node.$element.text() );
-               this.$element
-                       .addClass( 'toclevel-' + this.tocLevel )
-                       .addClass( 'tocsection-' + this.tocIndex )
-                       .append( $( '<a>' ).append( this.$tocNumber, 
this.$tocText ) );
-
-               // Monitor node events
-               this.node.model.connect( this, { update: 'onUpdate' } );
-       }
-       this.$element.append( this.$group );
-};
-
-/* Inheritance */
-
-OO.inheritClass( ve.ui.MWTocItemWidget, OO.ui.Widget );
-
-OO.mixinClass( ve.ui.MWTocItemWidget, OO.ui.mixin.GroupElement );
-
-/* Static Properties */
-
-ve.ui.MWTocItemWidget.static.tagName = 'li';
-
-/* Methods */
-
-/**
- * Updates the text of the toc item
- *
- */
-ve.ui.MWTocItemWidget.prototype.onUpdate = function () {
-       var widget = this;
-       // Timeout needed to let the dom element actually update
-       setTimeout( function () {
-               widget.$tocText.text( widget.node.$element.text() );
-       } );
-};
-
-/**
- * Removes this toc item from its parent
- *
- */
-ve.ui.MWTocItemWidget.prototype.remove = function () {
-       this.node.model.disconnect( this );
-       this.parent.removeItems( [ this ] );
-};
diff --git a/modules/ve-mw/ui/widgets/ve.ui.MWTocWidget.js 
b/modules/ve-mw/ui/widgets/ve.ui.MWTocWidget.js
index aa23472..98e069c 100644
--- a/modules/ve-mw/ui/widgets/ve.ui.MWTocWidget.js
+++ b/modules/ve-mw/ui/widgets/ve.ui.MWTocWidget.js
@@ -16,7 +16,6 @@
  * @param {Object} [config] Configuration options
  */
 ve.ui.MWTocWidget = function VeUiMWTocWidget( surface, config ) {
-       var widget = this;
 
        // Parent constructor
        OO.ui.Widget.call( this, config );
@@ -26,46 +25,24 @@
        this.doc = surface.getModel().getDocument();
        this.metaList = surface.getModel().metaList;
        // Topic level 0 lives inside of a toc item
-       this.topics = new ve.ui.MWTocItemWidget();
-       // Place for a cloned previous toc to live while rebuilding.
-       this.$tempTopics = $( '<ul>' );
-       // Section keyed item map
-       this.items = {};
+       this.rootLength = 0;
        this.initialized = false;
        // Page settings cache
        this.mwTOCForce = false;
        this.mwTOCDisable = false;
 
-       // TODO: fix i18n
-       this.tocToggle = {
-               hideMsg: ve.msg( 'hidetoc' ),
-               showMsg: ve.msg( 'showtoc' ),
-               $link: $( '<a class="internal" id="togglelink"></a>' ).text( 
ve.msg( 'hidetoc' ) ),
-               open: true
-       };
+       this.$tocList = $( '<ul>' );
        this.$element.addClass( 'toc ve-ui-mwTocWidget' ).append(
-               $( '<div>' ).attr( 'id', 'toctitle' ).append(
-                       $( '<h2>' ).text( ve.msg( 'toc' ) ),
-                       $( '<span>' ).addClass( 'toctoggle' ).append( 
this.tocToggle.$link )
+               $( '<div>' ).addClass( 'toctitle' ).append(
+                       $( '<h2>' ).text( ve.msg( 'toc' ) )
                ),
-               this.topics.$group, this.$tempTopics
+               this.$tocList
        );
-       // Place in bodyContent element, which is close to where the TOC 
normally lives in the dom
-       // Integration ignores hiding the TOC widget, though continues to hide 
the real page TOC
-       $( '#bodyContent' ).append( this.$element );
 
-       this.tocToggle.$link.on( 'click', function () {
-               if ( widget.tocToggle.open ) {
-                       widget.tocToggle.$link.text( widget.tocToggle.showMsg );
-                       widget.tocToggle.open = false;
-               } else {
-                       widget.tocToggle.$link.text( widget.tocToggle.hideMsg );
-                       widget.tocToggle.open = true;
-               }
-               // FIXME: We should really use CSS here
-               widget.topics.$group.add( widget.$tempTopics ).slideToggle();
-       } );
+       // Setup toggle link
+       mw.hook( 'wikipage.content' ).fire( this.$element );
 
+       // Events
        this.metaList.connect( this, {
                insert: 'onMetaListInsert',
                remove: 'onMetaListRemove'
@@ -93,7 +70,7 @@
                // hide
                this.mwTOCDisable = true;
        }
-       this.hideOrShow();
+       this.updateVisibility();
 };
 
 /**
@@ -107,7 +84,7 @@
        } else if ( metaItem instanceof ve.dm.MWTOCDisableMetaItem ) {
                this.mwTOCDisable = false;
        }
-       this.hideOrShow();
+       this.updateVisibility();
 };
 
 /**
@@ -127,160 +104,109 @@
                                this.mwTOCDisable = true;
                        }
                }
-               this.hideOrShow();
+               this.updateVisibility();
        }
 };
 
 /**
  * Hides or shows the TOC based on page and default settings
  */
-ve.ui.MWTocWidget.prototype.hideOrShow = function () {
+ve.ui.MWTocWidget.prototype.updateVisibility = function () {
        // In MediaWiki if __FORCETOC__ is anywhere TOC is always displayed
        // ... Even if there is a __NOTOC__ in the article
-       this.toggle( !this.mwTOCDisable && ( this.mwTOCForce || 
this.topics.items.length >= 3 ) );
+       this.toggle( !this.mwTOCDisable && ( this.mwTOCForce || this.rootLength 
>= 3 ) );
 };
 
 /**
  * Rebuild TOC on ve.ce.MWHeadingNode teardown or setup
+ *
  * Rebuilds on both teardown and setup of a node, so rebuild is debounced
  */
 ve.ui.MWTocWidget.prototype.rebuild = ve.debounce( function () {
-       var widget = this;
-       // Only rebuild when initialized
-       if ( this.surface.mwTocWidget.initialized ) {
-               this.$tempTopics.append( this.topics.$group.children().clone() 
);
-               this.teardownItems();
-               // Build after transactions
-               setTimeout( function () {
-                       widget.build();
-                       widget.$tempTopics.empty();
-               }, 0 );
+       if ( this.initialized ) {
+               // Wait for transactions to process
+               this.build();
        }
-}, 0 );
+} );
 
 /**
- * Teardown all of the TOC items
+ * Update the text content of a specific heading node
+ *
+ * @param {ve.ce.MWHeadingNode} viewNode Heading node
  */
-ve.ui.MWTocWidget.prototype.teardownItems = function () {
-       var item;
-       for ( item in this.items ) {
-               this.items[ item ].remove();
-               delete this.items[ item ];
+ve.ui.MWTocWidget.prototype.updateNode = function ( viewNode ) {
+       if ( viewNode.$tocText ) {
+               viewNode.$tocText.text( viewNode.$element.text() );
        }
-       this.items = {};
-};
-
-/**
- * Teardown the widget and remove it from the dom
- */
-ve.ui.MWTocWidget.prototype.teardown = function () {
-       this.teardownItems();
-       this.$element.remove();
 };
 
 /**
  * Build TOC from mwHeading dm nodes
+ *
+ * Based on generateTOC in Linker.php
  */
 ve.ui.MWTocWidget.prototype.build = function () {
-       var nodes = this.doc.selectNodes( new ve.Range( 0, 
this.doc.getDocumentNode().getLength() ), 'leaves' ),
-               i = 0,
-               headingLevel = 0,
-               previousHeadingNode = null,
-               previousHeadingLevel = 0,
-               parentHeadingLevel = 0,
-               levelSkipped = false,
-               tocNumber = 0,
-               tocLevel = 0,
-               tocSection = 0,
-               tocIndex = 0,
-               sectionPrefix = [],
-               parentSectionArray,
-               key,
-               parent,
-               config,
-               headingOuterRange,
-               ceNode;
-       for ( ; i < nodes.length; i++ ) {
-               if ( nodes[ i ].node.parent === previousHeadingNode ) {
-                       // Duplicate heading
-                       continue;
-               }
-               if ( nodes[ i ].node.parent.getType() === 'mwHeading' ) {
-                       tocIndex++;
-                       headingLevel = nodes[ i ].node.parent.getAttribute( 
'level' );
-                       // MW TOC Generation
-                       // The first heading will always be be a zero level 
topic, even heading levels > 2
-                       // If heading level is 1 then it is definitely a zero 
level topic
-                       // If heading level is 2 then it is a zero level topic, 
unless a child of a 1 level
-                       // If heading went up and skipped a number, the 
following headings of the skipped number are in the same level
-                       if ( this.topics.items.length === 0 || headingLevel === 
1 || ( headingLevel === 2 && parentHeadingLevel !== 1 ) ) {
-                               tocSection++;
-                               sectionPrefix = [ tocSection ];
-                               tocLevel = 0;
-                               // reset t
-                               levelSkipped = false;
-                               parent = this.topics;
-                               parentHeadingLevel = headingLevel;
-                       } else {
-                               // If previously skipped a level, place this 
heading in the same level as the previous higher one
-                               if ( headingLevel === previousHeadingLevel || 
headingLevel < previousHeadingLevel && levelSkipped ) {
-                                       tocNumber++;
-                                       sectionPrefix.pop();
-                                       sectionPrefix.push( tocNumber );
-                                       // Only remove the flag if the heading 
level has dropped but we skipped to a higher number previously
-                                       if ( headingLevel < 
previousHeadingLevel ) {
-                                               levelSkipped = false;
-                                       }
-                               } else {
-                                       tocNumber = 1;
-                                       // Heading not the same as before
-                                       if ( headingLevel > 
previousHeadingLevel ) {
-                                               // Did we skip a level? Flag in 
case we drop down a number
-                                               if ( headingLevel - 
previousHeadingLevel > 1 ) {
-                                                       levelSkipped = true;
-                                               }
-                                               tocLevel++;
-                                               sectionPrefix.push( tocNumber );
-                                       // Step to lower level unless we are at 
1
-                                       } else if ( headingLevel < 
previousHeadingLevel && tocLevel !== 1 ) {
-                                               tocLevel--;
-                                               sectionPrefix.pop();
-                                               tocNumber = sectionPrefix[ 
sectionPrefix.length - 1 ] + 1;
-                                               sectionPrefix.pop();
-                                               sectionPrefix.push( tocNumber );
-                                       }
-                               }
-                       }
-                       // Determine parent
-                       parentSectionArray = sectionPrefix.slice( 0 );
-                       parentSectionArray.pop();
-                       if ( parentSectionArray.length > 0 ) {
-                               key = parentSectionArray.join( '.' );
-                               parent = this.items[ key ];
-                       } else {
-                               // Topic level is zero
-                               parent = this.topics;
-                       }
-                       // TODO: Cleanup config generation, merge local vars 
into config object
-                       // Get CE node for the heading
-                       headingOuterRange = nodes[ i ].nodeOuterRange;
-                       ceNode = 
this.surface.getView().getDocument().getBranchNodeFromOffset( 
headingOuterRange.end );
-                       config = {
-                               node: ceNode,
-                               tocIndex: tocIndex,
-                               parent: parent,
-                               tocLevel: tocLevel,
-                               tocSection: tocSection,
-                               sectionPrefix: sectionPrefix.join( '.' ),
-                               insertIndex: sectionPrefix[ 
sectionPrefix.length - 1 ]
-                       };
-                       // Add item
-                       this.items[ sectionPrefix.join( '.' ) ] = new 
ve.ui.MWTocItemWidget( config );
-                       config.parent.addItems( [ this.items[ 
sectionPrefix.join( '.' ) ] ], config.insertIndex );
-                       previousHeadingLevel = headingLevel;
-                       previousHeadingNode = nodes[ i ].node.parent;
-               }
+       var i, l, level, levelDiff, tocNumber, modelNode, viewNode,
+               $list, $text, $item, $link,
+               $newTocList = $( '<ul>' ),
+               nodes = this.doc.getNodesByType( 'mwHeading', true ),
+               documentView = this.surface.getView().getDocument(),
+               lastLevel = 0,
+               stack = [];
+
+       function getItemIndex( $list, n ) {
+               return $list.children( 'li' ).length + ( n === stack.length - 1 
? 1 : 0 );
        }
+
+       function linkClickHandler( heading ) {
+               ve.init.target.goToHeading( heading );
+               return false;
+       }
+
+       for ( i = 0, l = nodes.length; i < l; i++ ) {
+               modelNode = nodes[ i ];
+               level = modelNode.getAttribute( 'level' );
+
+               if ( level > lastLevel ) {
+                       if ( stack.length ) {
+                               $list = $( '<ul>' );
+                               stack[ stack.length - 1 
].children().last().append( $list );
+                       } else {
+                               $list = $newTocList;
+                       }
+                       stack.push( $list );
+               } else if ( level < lastLevel ) {
+                       levelDiff = lastLevel - level;
+                       while ( levelDiff > 0 && stack.length > 1 ) {
+                               stack.pop();
+                               levelDiff--;
+                       }
+               }
+
+               tocNumber = stack.map( getItemIndex ).join( '.' );
+               viewNode = documentView.getBranchNodeFromOffset( 
modelNode.getRange().start );
+               $item = $( '<li>' ).addClass( 'toclevel-' + stack.length 
).addClass( 'tocsection-' + ( i + 1 ) );
+               $link = $( '<a href="#">' ).append( '<span class="tocnumber">' 
+ tocNumber + '</span> ' );
+               $text = $( '<span>' ).addClass( 'toctext' );
+
+               viewNode.$tocText = $text;
+               this.updateNode( viewNode );
+
+               stack[ stack.length - 1 ].append( $item.append( $link.append( 
$text ) ) );
+               $link.on( 'click', linkClickHandler.bind( this, viewNode ) );
+
+               lastLevel = level;
+       }
+
+       this.$tocList.replaceWith( $newTocList );
+       this.$tocList = $newTocList;
+
+       if ( nodes.length ) {
+               this.rootLength = stack[ 0 ].children().length;
+       } else {
+               this.rootLength = 0;
+       }
+
        this.initialized = true;
-       this.hideOrShow();
+       this.updateVisibility();
 };

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I5eb75c5db5ca466fd6f16a57c693c2a4458cff7c
Gerrit-PatchSet: 11
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <esand...@wikimedia.org>
Gerrit-Reviewer: Alex Monk <a...@wikimedia.org>
Gerrit-Reviewer: DLynch <dly...@wikimedia.org>
Gerrit-Reviewer: Esanders <esand...@wikimedia.org>
Gerrit-Reviewer: Jforrester <jforres...@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