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

Change subject: Improve moving of infoboxes to end of first paragraph.
......................................................................


Improve moving of infoboxes to end of first paragraph.

Reusing transform code from iOS, where we search for the first <p> tag
that is nonempty, and move it up to the top, instead of moving tables and
images down.

Solves issues with some articles' infobox overlapping with the edit
pencil. (Examples for testing: [[Westham]], [[Sparta]], [[Russia]])
Mostly applies to articles with hidden geo coordinates.

Also solves issue where an infobox might become embedded into another
existing infobox. (as in [[Barack Obama]])

Also solves issue where text blocks were reordered (example: [[Snark
(graph theory)]].

Factored out some commonly used utility functions into a separate "util"
module.

Bug: T77802
Change-Id: I39c038f09e7d807d4876cbcbb49c0fc2ea9093f2
---
M wikipedia/assets/bundle-test.js
M wikipedia/assets/bundle.js
M wikipedia/assets/preview.js
M www/Gruntfile.js
M www/js/actions.js
M www/js/bridge.js
M www/js/night.js
M www/js/sections.js
M www/js/transforms.js
A www/js/util.js
10 files changed, 210 insertions(+), 195 deletions(-)

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



diff --git a/wikipedia/assets/bundle-test.js b/wikipedia/assets/bundle-test.js
index 21ae720..e7569ba 100644
--- a/wikipedia/assets/bundle-test.js
+++ b/wikipedia/assets/bundle-test.js
@@ -32,7 +32,7 @@
 };
 
 module.exports = new Bridge();
-// FIXME: Move this to somwehere else, eh?
+// FIXME: Move this to somewhere else, eh?
 window.onload = function() {
     module.exports.sendMessage( "DOMLoaded", {} );
 };
diff --git a/wikipedia/assets/bundle.js b/wikipedia/assets/bundle.js
index cf692d7..a4e6f13 100644
--- a/wikipedia/assets/bundle.js
+++ b/wikipedia/assets/bundle.js
@@ -1,5 +1,6 @@
 (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof 
require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw 
new Error("Cannot find module '"+o+"'")}var 
f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return 
s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof 
require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return 
s})({1:[function(require,module,exports){
 var bridge = require('./bridge');
+var util = require('./util');
 
 function ActionsHandler() {
 }
@@ -17,21 +18,6 @@
 bridge.registerListener( "handleReference", function( payload ) {
     handleReference( payload.anchor, false );
 });
-
-function ancestorContainsClass( element, className ) {
-    var contains = false;
-    var curNode = element;
-    while (curNode) {
-        if ((typeof curNode.classList !== "undefined")) {
-            if (curNode.classList.contains(className)) {
-                contains = true;
-                break;
-            }
-        }
-        curNode = curNode.parentNode;
-    }
-    return contains;
-}
 
 function handleReference( targetId, backlink ) {
     var targetElem = document.getElementById( targetId );
@@ -82,7 +68,7 @@
                 } else if ( "disambig" === targetId ) {
                     disambigClicked( sourceNode );
                 } else {
-                    handleReference( targetId, ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
+                    handleReference( targetId, util.ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
                 }
             } else if (sourceNode.classList.contains( 'image' )) {
                 bridge.sendMessage( 'imageClicked', { "href": href } );
@@ -132,7 +118,7 @@
 
 module.exports = new ActionsHandler();
 
-},{"./bridge":2}],2:[function(require,module,exports){
+},{"./bridge":2,"./util":13}],2:[function(require,module,exports){
 function Bridge() {
 }
 
@@ -166,7 +152,7 @@
 };
 
 module.exports = new Bridge();
-// FIXME: Move this to somwehere else, eh?
+// FIXME: Move this to somewhere else, eh?
 window.onload = function() {
     module.exports.sendMessage( "DOMLoaded", {} );
 };
@@ -301,6 +287,7 @@
 var parseCSSColor = require("../lib/js/css-color-parser");
 var bridge = require("./bridge");
 var loader = require("./loader");
+var util = require("./util");
 
 function invertColorProperty( el, propertyName ) {
        var property = el.style[propertyName];
@@ -314,21 +301,9 @@
        el.style[propertyName] = 'rgb(' + (255 - r) + ', ' + (255 - g) + ', ' + 
(255 - b ) + ')';
 }
 
-function hasAncestor( el, tagName ) {
-       if ( el.tagName === tagName) {
-               return true;
-       } else {
-               if ( el.parentNode !== null && el.parentNode.tagName !== 'BODY' 
) {
-                       return hasAncestor( el.parentNode, tagName );
-               } else {
-                       return false;
-               }
-       }
-}
-
 var invertProperties = [ 'color', 'background-color', 'border-color' ];
 function invertOneElement( el ) {
-       var shouldStrip = hasAncestor( el, 'TABLE' );
+       var shouldStrip = util.hasAncestor( el, 'TABLE' );
        for ( var i = 0; i < invertProperties.length; i++ ) {
                if ( el.style[invertProperties[i]] ) {
                        if ( shouldStrip ) {
@@ -390,7 +365,7 @@
        invertElement: invertElement
 };
 
-},{"../lib/js/css-color-parser":14,"./bridge":2,"./loader":6}],9:[function(require,module,exports){
+},{"../lib/js/css-color-parser":15,"./bridge":2,"./loader":6,"./util":13}],9:[function(require,module,exports){
 var bridge = require("./bridge");
 
 bridge.registerListener( "setDirectionality", function( payload ) {
@@ -445,7 +420,7 @@
 
     var content = document.createElement( "div" );
     content.setAttribute( "dir", window.directionality );
-    content.innerHTML = editButton.outerHTML + payload.section.text;
+    content.innerHTML = payload.section.text;
     content.id = "content_block_0";
 
     window.apiLevel = payload.apiLevel;
@@ -456,10 +431,17 @@
     window.pageTitle = payload.title;
     window.isMainPage = payload.isMainPage;
 
+    // append the content to the DOM now, so that we can obtain
+    // dimension measurements for items.
+    document.getElementById( "content" ).appendChild( content );
+
     content = transformer.transform( "leadSection", content );
     content = transformer.transform( "section", content );
     content = transformer.transform( "hideTables", content );
     content = transformer.transform( "hideIPA", content );
+
+    // insert the edit pencil
+    content.insertBefore( editButton, content.firstChild );
 
     content = transformer.transform("displayDisambigLink", content);
     content = transformer.transform("displayIssuesLink", content);
@@ -485,8 +467,6 @@
         separator.className = 'issues_separator';
         issuesContainer.insertBefore(separator, issuesBtn.parentNode);
     }
-
-    document.getElementById( "content" ).appendChild( content );
 
     document.getElementById( "loading_sections").className = "loading";
     scrolledOnLoad = false;
@@ -630,59 +610,48 @@
 var night = require("./night");
 var bridge = require( "./bridge" );
 
-// Move any tables to the bottom of the lead section
+// Move the first non-empty paragraph of text to the top of the section.
+// This will have the effect of shifting the infobox and/or any images at the 
top of the page
+// below the first paragraph, allowing the user to start reading the page 
right away.
 transformer.register( "leadSection", function( leadContent ) {
     if (window.isMainPage) {
         // don't do anything if this is the main page, since many wikis
         // arrange the main page in a series of tables.
         return leadContent;
     }
-    var leadTables = leadContent.querySelectorAll( "table" );
-    var pTags, i;
-    for ( i = 0; i < leadTables.length; i++ ) {
-        /*
-        If the table itself sits within a table or series of tables,
-        move the most distant ancestor table instead of just moving this
-        table. Otherwise you end up with table(s) with a hole where the
-        child table had been. World War II article on enWiki has this issue.
-        Note that we need to stop checking ancestor tables when we hit
-        content_block_0.
-        */
-        var tableEl = leadTables[i];
-        var parentTable = null;
-        var tempEl = tableEl;
-        while (tempEl.parentNode) {
-            tempEl = tempEl.parentNode;
-            if (tempEl.id === 'content_block_0') {
-                break;
-            }
-            if (tempEl.tagName === 'TABLE') {
-                parentTable = tempEl;
-            }
+    var block_0 = document.getElementById( "content_block_0" );
+    if (!block_0) {
+        return leadContent;
+    }
+
+    var allPs = block_0.getElementsByTagName( "p" );
+    if (!allPs) {
+        return leadContent;
+    }
+
+    for ( var i = 0; i < allPs.length; i++ ) {
+        var p = allPs[i];
+        // Narrow down to first P which is direct child of content_block_0 DIV.
+        // (Don't want to yank P from somewhere in the middle of a table!)
+        if (p.parentNode !== block_0) {
+            continue;
         }
-        if (parentTable) {
-            tableEl = parentTable;
+        // Ensure the P being pulled up has at least a couple lines of text.
+        // Otherwise silly things like a empty P or P which only contains a
+        // BR tag will get pulled up (see articles on "Chemical Reaction" and
+        // "Hawaii").
+        // Trick for quickly determining element height:
+        // 
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.offsetHeight
+        // http://stackoverflow.com/a/1343350/135557
+        var minHeight = 40;
+        if (p.offsetHeight < minHeight){
+            continue;
         }
 
-        tableEl.parentNode.removeChild( tableEl );
-        pTags = leadContent.getElementsByTagName( "p" );
-        if ( pTags.length ) {
-            pTags[0].appendChild( tableEl );
-        } else {
-            leadContent.appendChild( tableEl );
-        }
-    }
-    //also move any thumbnail images to the bottom of the section,
-    //since we have a lead image, and we want the content to appear at the 
very beginning.
-    var thumbs = leadContent.querySelectorAll( "div.thumb" );
-    for ( i = 0; i < thumbs.length; i++ ) {
-        thumbs[i].parentNode.removeChild( thumbs[i] );
-        pTags = leadContent.getElementsByTagName( "p" );
-        if ( pTags.length ) {
-            pTags[pTags.length - 1].appendChild( thumbs[i] );
-        } else {
-            leadContent.appendChild( thumbs[i] );
-        }
+        // Move the P!
+        block_0.insertBefore(p.parentNode.removeChild(p), block_0.firstChild);
+        // But only move one P!
+        break;
     }
     return leadContent;
 } );
@@ -966,6 +935,40 @@
 } );
 
 
},{"./bridge":2,"./night":8,"./transformer":11}],13:[function(require,module,exports){
+
+function hasAncestor( el, tagName ) {
+    if ( el !== null && el.tagName === tagName) {
+        return true;
+    } else {
+        if ( el.parentNode !== null && el.parentNode.tagName !== 'BODY' ) {
+            return hasAncestor( el.parentNode, tagName );
+        } else {
+            return false;
+        }
+    }
+}
+
+function ancestorContainsClass( element, className ) {
+    var contains = false;
+    var curNode = element;
+    while (curNode) {
+        if ((typeof curNode.classList !== "undefined")) {
+            if (curNode.classList.contains(className)) {
+                contains = true;
+                break;
+            }
+        }
+        curNode = curNode.parentNode;
+    }
+    return contains;
+}
+
+module.exports = {
+    hasAncestor: hasAncestor,
+    ancestorContainsClass: ancestorContainsClass
+};
+
+},{}],14:[function(require,module,exports){
 /**
  * MIT LICENSCE
  * From: https://github.com/remy/polyfills
@@ -1042,7 +1045,7 @@
 
 })();
 
-},{}],14:[function(require,module,exports){
+},{}],15:[function(require,module,exports){
 // (c) Dean McNamee <[email protected]>, 2012.
 //
 // https://github.com/deanm/css-color-parser-js
@@ -1244,4 +1247,4 @@
 
 try { module.exports = parseCSSColor } catch(e) { }
 
-},{}]},{},[6,14,7,8,11,12,2,1,4,5,3,10,9,13])
\ No newline at end of file
+},{}]},{},[6,15,7,8,11,12,2,1,4,5,3,10,9,13,14])
\ No newline at end of file
diff --git a/wikipedia/assets/preview.js b/wikipedia/assets/preview.js
index 5d95a59..55b05b3 100644
--- a/wikipedia/assets/preview.js
+++ b/wikipedia/assets/preview.js
@@ -1,5 +1,6 @@
 (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof 
require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw 
new Error("Cannot find module '"+o+"'")}var 
f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return 
s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof 
require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return 
s})({1:[function(require,module,exports){
 var bridge = require('./bridge');
+var util = require('./util');
 
 function ActionsHandler() {
 }
@@ -17,21 +18,6 @@
 bridge.registerListener( "handleReference", function( payload ) {
     handleReference( payload.anchor, false );
 });
-
-function ancestorContainsClass( element, className ) {
-    var contains = false;
-    var curNode = element;
-    while (curNode) {
-        if ((typeof curNode.classList !== "undefined")) {
-            if (curNode.classList.contains(className)) {
-                contains = true;
-                break;
-            }
-        }
-        curNode = curNode.parentNode;
-    }
-    return contains;
-}
 
 function handleReference( targetId, backlink ) {
     var targetElem = document.getElementById( targetId );
@@ -82,7 +68,7 @@
                 } else if ( "disambig" === targetId ) {
                     disambigClicked( sourceNode );
                 } else {
-                    handleReference( targetId, ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
+                    handleReference( targetId, util.ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
                 }
             } else if (sourceNode.classList.contains( 'image' )) {
                 bridge.sendMessage( 'imageClicked', { "href": href } );
@@ -132,7 +118,7 @@
 
 module.exports = new ActionsHandler();
 
-},{"./bridge":2}],2:[function(require,module,exports){
+},{"./bridge":2,"./util":7}],2:[function(require,module,exports){
 function Bridge() {
 }
 
@@ -166,7 +152,7 @@
 };
 
 module.exports = new Bridge();
-// FIXME: Move this to somwehere else, eh?
+// FIXME: Move this to somewhere else, eh?
 window.onload = function() {
     module.exports.sendMessage( "DOMLoaded", {} );
 };
@@ -196,6 +182,7 @@
 var parseCSSColor = require("../lib/js/css-color-parser");
 var bridge = require("./bridge");
 var loader = require("./loader");
+var util = require("./util");
 
 function invertColorProperty( el, propertyName ) {
        var property = el.style[propertyName];
@@ -209,21 +196,9 @@
        el.style[propertyName] = 'rgb(' + (255 - r) + ', ' + (255 - g) + ', ' + 
(255 - b ) + ')';
 }
 
-function hasAncestor( el, tagName ) {
-       if ( el.tagName === tagName) {
-               return true;
-       } else {
-               if ( el.parentNode !== null && el.parentNode.tagName !== 'BODY' 
) {
-                       return hasAncestor( el.parentNode, tagName );
-               } else {
-                       return false;
-               }
-       }
-}
-
 var invertProperties = [ 'color', 'background-color', 'border-color' ];
 function invertOneElement( el ) {
-       var shouldStrip = hasAncestor( el, 'TABLE' );
+       var shouldStrip = util.hasAncestor( el, 'TABLE' );
        for ( var i = 0; i < invertProperties.length; i++ ) {
                if ( el.style[invertProperties[i]] ) {
                        if ( shouldStrip ) {
@@ -285,7 +260,7 @@
        invertElement: invertElement
 };
 
-},{"../lib/js/css-color-parser":8,"./bridge":2,"./loader":3}],5:[function(require,module,exports){
+},{"../lib/js/css-color-parser":9,"./bridge":2,"./loader":3,"./util":7}],5:[function(require,module,exports){
 var bridge = require("./bridge");
 
 bridge.registerListener( "displayPreviewHTML", function( payload ) {
@@ -305,6 +280,40 @@
 } );
 
 },{"./bridge":2}],7:[function(require,module,exports){
+
+function hasAncestor( el, tagName ) {
+    if ( el !== null && el.tagName === tagName) {
+        return true;
+    } else {
+        if ( el.parentNode !== null && el.parentNode.tagName !== 'BODY' ) {
+            return hasAncestor( el.parentNode, tagName );
+        } else {
+            return false;
+        }
+    }
+}
+
+function ancestorContainsClass( element, className ) {
+    var contains = false;
+    var curNode = element;
+    while (curNode) {
+        if ((typeof curNode.classList !== "undefined")) {
+            if (curNode.classList.contains(className)) {
+                contains = true;
+                break;
+            }
+        }
+        curNode = curNode.parentNode;
+    }
+    return contains;
+}
+
+module.exports = {
+    hasAncestor: hasAncestor,
+    ancestorContainsClass: ancestorContainsClass
+};
+
+},{}],8:[function(require,module,exports){
 /**
  * MIT LICENSCE
  * From: https://github.com/remy/polyfills
@@ -381,7 +390,7 @@
 
 })();
 
-},{}],8:[function(require,module,exports){
+},{}],9:[function(require,module,exports){
 // (c) Dean McNamee <[email protected]>, 2012.
 //
 // https://github.com/deanm/css-color-parser-js
@@ -583,4 +592,4 @@
 
 try { module.exports = parseCSSColor } catch(e) { }
 
-},{}]},{},[3,2,4,1,5,6,7])
\ No newline at end of file
+},{}]},{},[3,2,4,1,5,6,7,8])
\ No newline at end of file
diff --git a/www/Gruntfile.js b/www/Gruntfile.js
index 5d313f6..c13d762 100644
--- a/www/Gruntfile.js
+++ b/www/Gruntfile.js
@@ -40,7 +40,8 @@
                         "js/issues.js",
                         "js/disambig.js",
                         "js/sections.js",
-                        "js/rtlsupport.js"
+                        "js/rtlsupport.js",
+                        "js/util.js"
                     ].concat( oldDroidPolyfills ),
                     "bundle-test.js": [
                         "js/loader.js",
@@ -54,7 +55,8 @@
                         "js/night.js",
                         "js/actions.js",
                         "js/preview.js",
-                        "js/rtlsupport.js"
+                        "js/rtlsupport.js",
+                        "js/util.js"
                     ].concat( oldDroidPolyfills )
                 }
             }
diff --git a/www/js/actions.js b/www/js/actions.js
index 11b84e1..0b41eed 100644
--- a/www/js/actions.js
+++ b/www/js/actions.js
@@ -1,4 +1,5 @@
 var bridge = require('./bridge');
+var util = require('./util');
 
 function ActionsHandler() {
 }
@@ -16,21 +17,6 @@
 bridge.registerListener( "handleReference", function( payload ) {
     handleReference( payload.anchor, false );
 });
-
-function ancestorContainsClass( element, className ) {
-    var contains = false;
-    var curNode = element;
-    while (curNode) {
-        if ((typeof curNode.classList !== "undefined")) {
-            if (curNode.classList.contains(className)) {
-                contains = true;
-                break;
-            }
-        }
-        curNode = curNode.parentNode;
-    }
-    return contains;
-}
 
 function handleReference( targetId, backlink ) {
     var targetElem = document.getElementById( targetId );
@@ -81,7 +67,7 @@
                 } else if ( "disambig" === targetId ) {
                     disambigClicked( sourceNode );
                 } else {
-                    handleReference( targetId, ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
+                    handleReference( targetId, util.ancestorContainsClass( 
sourceNode, "mw-cite-backlink" ) );
                 }
             } else if (sourceNode.classList.contains( 'image' )) {
                 bridge.sendMessage( 'imageClicked', { "href": href } );
diff --git a/www/js/bridge.js b/www/js/bridge.js
index bc5a437..8b4cba2 100644
--- a/www/js/bridge.js
+++ b/www/js/bridge.js
@@ -31,7 +31,7 @@
 };
 
 module.exports = new Bridge();
-// FIXME: Move this to somwehere else, eh?
+// FIXME: Move this to somewhere else, eh?
 window.onload = function() {
     module.exports.sendMessage( "DOMLoaded", {} );
 };
\ No newline at end of file
diff --git a/www/js/night.js b/www/js/night.js
index f558a6d..a2f8b08 100644
--- a/www/js/night.js
+++ b/www/js/night.js
@@ -1,6 +1,7 @@
 var parseCSSColor = require("../lib/js/css-color-parser");
 var bridge = require("./bridge");
 var loader = require("./loader");
+var util = require("./util");
 
 function invertColorProperty( el, propertyName ) {
        var property = el.style[propertyName];
@@ -14,21 +15,9 @@
        el.style[propertyName] = 'rgb(' + (255 - r) + ', ' + (255 - g) + ', ' + 
(255 - b ) + ')';
 }
 
-function hasAncestor( el, tagName ) {
-       if ( el.tagName === tagName) {
-               return true;
-       } else {
-               if ( el.parentNode !== null && el.parentNode.tagName !== 'BODY' 
) {
-                       return hasAncestor( el.parentNode, tagName );
-               } else {
-                       return false;
-               }
-       }
-}
-
 var invertProperties = [ 'color', 'background-color', 'border-color' ];
 function invertOneElement( el ) {
-       var shouldStrip = hasAncestor( el, 'TABLE' );
+       var shouldStrip = util.hasAncestor( el, 'TABLE' );
        for ( var i = 0; i < invertProperties.length; i++ ) {
                if ( el.style[invertProperties[i]] ) {
                        if ( shouldStrip ) {
diff --git a/www/js/sections.js b/www/js/sections.js
index f632ea7..abb9f92 100644
--- a/www/js/sections.js
+++ b/www/js/sections.js
@@ -42,7 +42,7 @@
 
     var content = document.createElement( "div" );
     content.setAttribute( "dir", window.directionality );
-    content.innerHTML = editButton.outerHTML + payload.section.text;
+    content.innerHTML = payload.section.text;
     content.id = "content_block_0";
 
     window.apiLevel = payload.apiLevel;
@@ -53,10 +53,17 @@
     window.pageTitle = payload.title;
     window.isMainPage = payload.isMainPage;
 
+    // append the content to the DOM now, so that we can obtain
+    // dimension measurements for items.
+    document.getElementById( "content" ).appendChild( content );
+
     content = transformer.transform( "leadSection", content );
     content = transformer.transform( "section", content );
     content = transformer.transform( "hideTables", content );
     content = transformer.transform( "hideIPA", content );
+
+    // insert the edit pencil
+    content.insertBefore( editButton, content.firstChild );
 
     content = transformer.transform("displayDisambigLink", content);
     content = transformer.transform("displayIssuesLink", content);
@@ -82,8 +89,6 @@
         separator.className = 'issues_separator';
         issuesContainer.insertBefore(separator, issuesBtn.parentNode);
     }
-
-    document.getElementById( "content" ).appendChild( content );
 
     document.getElementById( "loading_sections").className = "loading";
     scrolledOnLoad = false;
diff --git a/www/js/transforms.js b/www/js/transforms.js
index 2964241..0b527f2 100644
--- a/www/js/transforms.js
+++ b/www/js/transforms.js
@@ -2,59 +2,48 @@
 var night = require("./night");
 var bridge = require( "./bridge" );
 
-// Move any tables to the bottom of the lead section
+// Move the first non-empty paragraph of text to the top of the section.
+// This will have the effect of shifting the infobox and/or any images at the 
top of the page
+// below the first paragraph, allowing the user to start reading the page 
right away.
 transformer.register( "leadSection", function( leadContent ) {
     if (window.isMainPage) {
         // don't do anything if this is the main page, since many wikis
         // arrange the main page in a series of tables.
         return leadContent;
     }
-    var leadTables = leadContent.querySelectorAll( "table" );
-    var pTags, i;
-    for ( i = 0; i < leadTables.length; i++ ) {
-        /*
-        If the table itself sits within a table or series of tables,
-        move the most distant ancestor table instead of just moving this
-        table. Otherwise you end up with table(s) with a hole where the
-        child table had been. World War II article on enWiki has this issue.
-        Note that we need to stop checking ancestor tables when we hit
-        content_block_0.
-        */
-        var tableEl = leadTables[i];
-        var parentTable = null;
-        var tempEl = tableEl;
-        while (tempEl.parentNode) {
-            tempEl = tempEl.parentNode;
-            if (tempEl.id === 'content_block_0') {
-                break;
-            }
-            if (tempEl.tagName === 'TABLE') {
-                parentTable = tempEl;
-            }
+    var block_0 = document.getElementById( "content_block_0" );
+    if (!block_0) {
+        return leadContent;
+    }
+
+    var allPs = block_0.getElementsByTagName( "p" );
+    if (!allPs) {
+        return leadContent;
+    }
+
+    for ( var i = 0; i < allPs.length; i++ ) {
+        var p = allPs[i];
+        // Narrow down to first P which is direct child of content_block_0 DIV.
+        // (Don't want to yank P from somewhere in the middle of a table!)
+        if (p.parentNode !== block_0) {
+            continue;
         }
-        if (parentTable) {
-            tableEl = parentTable;
+        // Ensure the P being pulled up has at least a couple lines of text.
+        // Otherwise silly things like a empty P or P which only contains a
+        // BR tag will get pulled up (see articles on "Chemical Reaction" and
+        // "Hawaii").
+        // Trick for quickly determining element height:
+        // 
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.offsetHeight
+        // http://stackoverflow.com/a/1343350/135557
+        var minHeight = 40;
+        if (p.offsetHeight < minHeight){
+            continue;
         }
 
-        tableEl.parentNode.removeChild( tableEl );
-        pTags = leadContent.getElementsByTagName( "p" );
-        if ( pTags.length ) {
-            pTags[0].appendChild( tableEl );
-        } else {
-            leadContent.appendChild( tableEl );
-        }
-    }
-    //also move any thumbnail images to the bottom of the section,
-    //since we have a lead image, and we want the content to appear at the 
very beginning.
-    var thumbs = leadContent.querySelectorAll( "div.thumb" );
-    for ( i = 0; i < thumbs.length; i++ ) {
-        thumbs[i].parentNode.removeChild( thumbs[i] );
-        pTags = leadContent.getElementsByTagName( "p" );
-        if ( pTags.length ) {
-            pTags[pTags.length - 1].appendChild( thumbs[i] );
-        } else {
-            leadContent.appendChild( thumbs[i] );
-        }
+        // Move the P!
+        block_0.insertBefore(p.parentNode.removeChild(p), block_0.firstChild);
+        // But only move one P!
+        break;
     }
     return leadContent;
 } );
diff --git a/www/js/util.js b/www/js/util.js
new file mode 100644
index 0000000..404d055
--- /dev/null
+++ b/www/js/util.js
@@ -0,0 +1,32 @@
+
+function hasAncestor( el, tagName ) {
+    if ( el !== null && el.tagName === tagName) {
+        return true;
+    } else {
+        if ( el.parentNode !== null && el.parentNode.tagName !== 'BODY' ) {
+            return hasAncestor( el.parentNode, tagName );
+        } else {
+            return false;
+        }
+    }
+}
+
+function ancestorContainsClass( element, className ) {
+    var contains = false;
+    var curNode = element;
+    while (curNode) {
+        if ((typeof curNode.classList !== "undefined")) {
+            if (curNode.classList.contains(className)) {
+                contains = true;
+                break;
+            }
+        }
+        curNode = curNode.parentNode;
+    }
+    return contains;
+}
+
+module.exports = {
+    hasAncestor: hasAncestor,
+    ancestorContainsClass: ancestorContainsClass
+};

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I39c038f09e7d807d4876cbcbb49c0fc2ea9093f2
Gerrit-PatchSet: 7
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Dbrant <[email protected]>
Gerrit-Reviewer: BearND <[email protected]>
Gerrit-Reviewer: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Dbrant <[email protected]>
Gerrit-Reviewer: Mhurd <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to