Dbrant has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/165605

Change subject: [WIP] Make infoboxes (and other tables) collapsible.
......................................................................

[WIP] Make infoboxes (and other tables) collapsible.

(and collapsed by default)
(and be smart about it)

Change-Id: Id0ab8550e1d2bd165a68a29a9551aee1e6d8e748
---
M wikipedia/assets/bundle.js
M wikipedia/assets/styles.css
A wikipedia/assets/t1.png
A wikipedia/assets/t2.png
M www/js/sections.js
M www/js/transforms.js
6 files changed, 221 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/05/165605/1

diff --git a/wikipedia/assets/bundle.js b/wikipedia/assets/bundle.js
index 2db1f57..0c254b7 100644
--- a/wikipedia/assets/bundle.js
+++ b/wikipedia/assets/bundle.js
@@ -435,6 +435,7 @@
     content.id = "#content_block_0";
     content = transformer.transform( "leadSection", content );
     content = transformer.transform( "section", content );
+    content = transformer.transform( "hideTables", content );
 
     content = transformer.transform("displayDisambigLink", content);
     content = transformer.transform("displayIssuesLink", content);
@@ -491,6 +492,7 @@
     content.innerHTML = section.text;
     content.id = "content_block_" + section.id;
     content = transformer.transform( "section", content );
+    content = transformer.transform( "hideTables", content );
 
     return [ heading, content ];
 }
@@ -601,6 +603,99 @@
     return leadContent;
 } );
 
+/*
+Tries to get the text contents of the first table header (TH)
+element of a given TABLE element. If there are no TH elements in the table,
+then null is returned.
+*/
+function getTableHeader( element ) {
+    if (element.children === null) {
+        return;
+    }
+    for (var i = 0; i < element.children.length; i++) {
+        if (element.children[i].tagName === "TH") {
+            return element.children[i].innerText;
+        }
+        //if it's a table within a table, don't worry about it
+        if (element.children[i].tagName === "TABLE") {
+            continue;
+        }
+        var ret = getTableHeader(element.children[i]);
+        if (ret !== null) {
+            return ret;
+        }
+    }
+    return null;
+}
+
+transformer.register( "hideTables", function( content ) {
+    var tables = content.querySelectorAll( "table" );
+    for (var i = 0; i < tables.length; i++) {
+        //is the table already hidden? if so, don't worry about it
+        if (tables[i].style.display === 'none'
+            || tables[i].classList.contains( 'navbox' )
+            || tables[i].classList.contains( 'vertical-navbox' )
+            || tables[i].classList.contains( 'navbox-inner' )) {
+            continue;
+        }
+
+        var isInfobox = tables[i].classList.contains( 'infobox' );
+        var headerText = getTableHeader(tables[i]);
+        if (headerText === null) {
+            continue;
+        }
+        console.log( "Rewriting table: " + headerText );
+        var caption = "<strong>" + (isInfobox ? "Infobox" : "Table") + 
"</strong>: ";
+        caption += headerText;
+
+        //create the container div that will contain both the original table
+        //and the collapsed version, as well as the button.
+        var containerDiv = document.createElement( 'div' );
+        tables[i].parentNode.insertBefore(containerDiv, tables[i]);
+        tables[i].parentNode.removeChild(tables[i]);
+        containerDiv.appendChild(tables[i]);
+        containerDiv.className = 'table_container';
+
+        //create the collapsed notification, and add it to the container
+        var collapsedDiv = document.createElement( 'div' );
+        collapsedDiv.className = 'table_collapsed_container';
+        collapsedDiv.innerHTML = caption;
+        containerDiv.appendChild(collapsedDiv);
+
+        //set initial visibility
+        tables[i].style.display = 'none';
+        collapsedDiv.style.display = 'block';
+
+        //create and add the button
+        var buttonDiv = document.createElement( 'div' );
+        buttonDiv.classList.add('table_collapse_button');
+        buttonDiv.classList.add('table_collapse_button_open');
+        containerDiv.appendChild(buttonDiv);
+
+        //give the button a click handler
+        buttonDiv.onclick = function() {
+            var container = this.parentNode;
+            var tableFull = container.children[0];
+            var tableCollapsed = container.children[1];
+            var tableButton = container.children[2];
+            if (tableFull.style.display !== 'none') {
+                console.log( "Hiding table..." );
+                tableFull.style.display = 'none';
+                tableCollapsed.style.display = 'block';
+                buttonDiv.classList.remove('table_collapse_button_close');
+                buttonDiv.classList.add('table_collapse_button_open');
+            } else {
+                console.log( "Showing table..." );
+                tableFull.style.display = 'block';
+                tableCollapsed.style.display = 'none';
+                buttonDiv.classList.remove('table_collapse_button_open');
+                buttonDiv.classList.add('table_collapse_button_close');
+            }
+        };
+    }
+    return content;
+} );
+
 transformer.register( "section", function( content ) {
        if ( window.isNightMode ) {
                night.invertElement ( content );
diff --git a/wikipedia/assets/styles.css b/wikipedia/assets/styles.css
index 4bd2c97..9676f6c 100644
--- a/wikipedia/assets/styles.css
+++ b/wikipedia/assets/styles.css
@@ -638,6 +638,37 @@
   color: #b0b0b0;
 }
 
+.table_container {
+    position: relative;
+}
+.table_collapse_button {
+  position: absolute;
+  left: 100%;
+  top: 0;
+  margin-left: -24px;
+  margin-top: 0px;
+  height: 24px;
+  width: 24px;
+}
+.table_collapse_button_open {
+  background-image: url('t1.png');
+  background-size: 24px 24px;
+}
+.table_collapse_button_close {
+  background-image: url('t2.png');
+  background-size: 24px 24px;
+}
+.table_collapsed_container {
+    max-width: 50%;
+    float: right;
+    margin: 10px;
+    padding: 8px;
+    border: solid 2px #808080;
+    border-radius: 4px 4px 4px 4px;
+    background-color: #f0f0f0;
+}
+
+
 /* FIXME: Copied over from 
http://en.wikipedia.org/w/index.php?title=MediaWiki:Mobile.css&oldid=609508028
    This fixes some styling issues in the app, primarily hlists.
    Eventually fix this by supporting loading Mobile.css in the app
diff --git a/wikipedia/assets/t1.png b/wikipedia/assets/t1.png
new file mode 100644
index 0000000..ef423ca
--- /dev/null
+++ b/wikipedia/assets/t1.png
Binary files differ
diff --git a/wikipedia/assets/t2.png b/wikipedia/assets/t2.png
new file mode 100644
index 0000000..76f8888
--- /dev/null
+++ b/wikipedia/assets/t2.png
Binary files differ
diff --git a/www/js/sections.js b/www/js/sections.js
index 4fed3f7..78dbf87 100644
--- a/www/js/sections.js
+++ b/www/js/sections.js
@@ -39,6 +39,7 @@
     content.id = "#content_block_0";
     content = transformer.transform( "leadSection", content );
     content = transformer.transform( "section", content );
+    content = transformer.transform( "hideTables", content );
 
     content = transformer.transform("displayDisambigLink", content);
     content = transformer.transform("displayIssuesLink", content);
@@ -95,6 +96,7 @@
     content.innerHTML = section.text;
     content.id = "content_block_" + section.id;
     content = transformer.transform( "section", content );
+    content = transformer.transform( "hideTables", content );
 
     return [ heading, content ];
 }
diff --git a/www/js/transforms.js b/www/js/transforms.js
index c7783c9..e6a7db8 100644
--- a/www/js/transforms.js
+++ b/www/js/transforms.js
@@ -16,6 +16,99 @@
     return leadContent;
 } );
 
+/*
+Tries to get the text contents of the first table header (TH)
+element of a given TABLE element. If there are no TH elements in the table,
+then null is returned.
+*/
+function getTableHeader( element ) {
+    if (element.children === null) {
+        return;
+    }
+    for (var i = 0; i < element.children.length; i++) {
+        if (element.children[i].tagName === "TH") {
+            return element.children[i].innerText;
+        }
+        //if it's a table within a table, don't worry about it
+        if (element.children[i].tagName === "TABLE") {
+            continue;
+        }
+        var ret = getTableHeader(element.children[i]);
+        if (ret !== null) {
+            return ret;
+        }
+    }
+    return null;
+}
+
+transformer.register( "hideTables", function( content ) {
+    var tables = content.querySelectorAll( "table" );
+    for (var i = 0; i < tables.length; i++) {
+        //is the table already hidden? if so, don't worry about it
+        if (tables[i].style.display === 'none'
+            || tables[i].classList.contains( 'navbox' )
+            || tables[i].classList.contains( 'vertical-navbox' )
+            || tables[i].classList.contains( 'navbox-inner' )) {
+            continue;
+        }
+
+        var isInfobox = tables[i].classList.contains( 'infobox' );
+        var headerText = getTableHeader(tables[i]);
+        if (headerText === null) {
+            continue;
+        }
+        console.log( "Rewriting table: " + headerText );
+        var caption = "<strong>" + (isInfobox ? "Infobox" : "Table") + 
"</strong>: ";
+        caption += headerText;
+
+        //create the container div that will contain both the original table
+        //and the collapsed version, as well as the button.
+        var containerDiv = document.createElement( 'div' );
+        tables[i].parentNode.insertBefore(containerDiv, tables[i]);
+        tables[i].parentNode.removeChild(tables[i]);
+        containerDiv.appendChild(tables[i]);
+        containerDiv.className = 'table_container';
+
+        //create the collapsed notification, and add it to the container
+        var collapsedDiv = document.createElement( 'div' );
+        collapsedDiv.className = 'table_collapsed_container';
+        collapsedDiv.innerHTML = caption;
+        containerDiv.appendChild(collapsedDiv);
+
+        //set initial visibility
+        tables[i].style.display = 'none';
+        collapsedDiv.style.display = 'block';
+
+        //create and add the button
+        var buttonDiv = document.createElement( 'div' );
+        buttonDiv.classList.add('table_collapse_button');
+        buttonDiv.classList.add('table_collapse_button_open');
+        containerDiv.appendChild(buttonDiv);
+
+        //give the button a click handler
+        buttonDiv.onclick = function() {
+            var container = this.parentNode;
+            var tableFull = container.children[0];
+            var tableCollapsed = container.children[1];
+            var tableButton = container.children[2];
+            if (tableFull.style.display !== 'none') {
+                console.log( "Hiding table..." );
+                tableFull.style.display = 'none';
+                tableCollapsed.style.display = 'block';
+                buttonDiv.classList.remove('table_collapse_button_close');
+                buttonDiv.classList.add('table_collapse_button_open');
+            } else {
+                console.log( "Showing table..." );
+                tableFull.style.display = 'block';
+                tableCollapsed.style.display = 'none';
+                buttonDiv.classList.remove('table_collapse_button_open');
+                buttonDiv.classList.add('table_collapse_button_close');
+            }
+        };
+    }
+    return content;
+} );
+
 transformer.register( "section", function( content ) {
        if ( window.isNightMode ) {
                night.invertElement ( content );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id0ab8550e1d2bd165a68a29a9551aee1e6d8e748
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Dbrant <[email protected]>

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

Reply via email to