Brion VIBBER has submitted this change and it was merged. Change subject: Add classList polyfill ......................................................................
Add classList polyfill Is unconditionally loaded for now, should be only 2.3 later on. Change-Id: Ida62cee03cf92b17c5d1ac2c35765388d449dea7 --- M wikipedia/assets/abusefilter.js M wikipedia/assets/bundle-test.js M wikipedia/assets/bundle.js M wikipedia/assets/preview.js M www/Gruntfile.js D www/abusefilter.js A www/js/polyfill/classList.js D www/preview.js 8 files changed, 404 insertions(+), 207 deletions(-) Approvals: Brion VIBBER: Verified; Looks good to me, approved diff --git a/wikipedia/assets/abusefilter.js b/wikipedia/assets/abusefilter.js index 12fc2ea..d82f5c3 100644 --- a/wikipedia/assets/abusefilter.js +++ b/wikipedia/assets/abusefilter.js @@ -21,7 +21,7 @@ content.appendChild( warning ); } ); -},{"./bridge":2,"./transformer":4}],2:[function(require,module,exports){ +},{"./bridge":2,"./transformer":5}],2:[function(require,module,exports){ function Bridge() { } @@ -60,6 +60,83 @@ module.exports.sendMessage( "DOMLoaded", {} ); }; },{}],3:[function(require,module,exports){ +/** + * MIT LICENSCE + * From: https://github.com/remy/polyfills + * FIXME: Don't copy paste libraries, use a dep management system. + */ +(function () { + +if (typeof window.Element === "undefined" || "classList" in document.documentElement) return; + +var prototype = Array.prototype, + push = prototype.push, + splice = prototype.splice, + join = prototype.join; + +function DOMTokenList(el) { + this.el = el; + // The className needs to be trimmed and split on whitespace + // to retrieve a list of classes. + var classes = el.className.replace(/^\s+|\s+$/g,'').split(/\s+/); + for (var i = 0; i < classes.length; i++) { + push.call(this, classes[i]); + } +}; + +DOMTokenList.prototype = { + add: function(token) { + if(this.contains(token)) return; + push.call(this, token); + this.el.className = this.toString(); + }, + contains: function(token) { + return this.el.className.indexOf(token) != -1; + }, + item: function(index) { + return this[index] || null; + }, + remove: function(token) { + if (!this.contains(token)) return; + for (var i = 0; i < this.length; i++) { + if (this[i] == token) break; + } + splice.call(this, i, 1); + this.el.className = this.toString(); + }, + toString: function() { + return join.call(this, ' '); + }, + toggle: function(token) { + if (!this.contains(token)) { + this.add(token); + } else { + this.remove(token); + } + + return this.contains(token); + } +}; + +window.DOMTokenList = DOMTokenList; + +function defineElementGetter (obj, prop, getter) { + if (Object.defineProperty) { + Object.defineProperty(obj, prop,{ + get : getter + }); + } else { + obj.__defineGetter__(prop, getter); + } +} + +defineElementGetter(Element.prototype, 'classList', function () { + return new DOMTokenList(this); +}); + +})(); + +},{}],4:[function(require,module,exports){ var bridge = require("./bridge"); bridge.registerListener( "setDirectionality", function( payload ) { @@ -69,7 +146,7 @@ html.classList.add( "ui-" + payload.uiDirection ); } ); -},{"./bridge":2}],4:[function(require,module,exports){ +},{"./bridge":2}],5:[function(require,module,exports){ function Transformer() { } @@ -93,4 +170,4 @@ module.exports = new Transformer(); -},{}]},{},[2,1,3]) \ No newline at end of file +},{}]},{},[2,1,4,3]) \ No newline at end of file diff --git a/wikipedia/assets/bundle-test.js b/wikipedia/assets/bundle-test.js index b5b27b0..998db1f 100644 --- a/wikipedia/assets/bundle-test.js +++ b/wikipedia/assets/bundle-test.js @@ -60,15 +60,92 @@ } ); },{"./bridge":1}],3:[function(require,module,exports){ +/** + * MIT LICENSCE + * From: https://github.com/remy/polyfills + * FIXME: Don't copy paste libraries, use a dep management system. + */ +(function () { + +if (typeof window.Element === "undefined" || "classList" in document.documentElement) return; + +var prototype = Array.prototype, + push = prototype.push, + splice = prototype.splice, + join = prototype.join; + +function DOMTokenList(el) { + this.el = el; + // The className needs to be trimmed and split on whitespace + // to retrieve a list of classes. + var classes = el.className.replace(/^\s+|\s+$/g,'').split(/\s+/); + for (var i = 0; i < classes.length; i++) { + push.call(this, classes[i]); + } +}; + +DOMTokenList.prototype = { + add: function(token) { + if(this.contains(token)) return; + push.call(this, token); + this.el.className = this.toString(); + }, + contains: function(token) { + return this.el.className.indexOf(token) != -1; + }, + item: function(index) { + return this[index] || null; + }, + remove: function(token) { + if (!this.contains(token)) return; + for (var i = 0; i < this.length; i++) { + if (this[i] == token) break; + } + splice.call(this, i, 1); + this.el.className = this.toString(); + }, + toString: function() { + return join.call(this, ' '); + }, + toggle: function(token) { + if (!this.contains(token)) { + this.add(token); + } else { + this.remove(token); + } + + return this.contains(token); + } +}; + +window.DOMTokenList = DOMTokenList; + +function defineElementGetter (obj, prop, getter) { + if (Object.defineProperty) { + Object.defineProperty(obj, prop,{ + get : getter + }); + } else { + obj.__defineGetter__(prop, getter); + } +} + +defineElementGetter(Element.prototype, 'classList', function () { + return new DOMTokenList(this); +}); + +})(); + +},{}],4:[function(require,module,exports){ var bridge = require("../js/bridge"); bridge.registerListener( "injectScript", function( payload ) { require(payload.src); }); -},{"../js/bridge":1}],4:[function(require,module,exports){ +},{"../js/bridge":1}],5:[function(require,module,exports){ var bridge = require("../js/bridge"); console.log("Something!"); bridge.registerListener( "ping", function( payload ) { bridge.sendMessage( "pong", payload ); }); -},{"../js/bridge":1}]},{},[2,1,3,4]) \ No newline at end of file +},{"../js/bridge":1}]},{},[2,1,4,5,3]) \ No newline at end of file diff --git a/wikipedia/assets/bundle.js b/wikipedia/assets/bundle.js index 77ae0ce..25f47ca 100644 --- a/wikipedia/assets/bundle.js +++ b/wikipedia/assets/bundle.js @@ -108,6 +108,83 @@ } ); },{"./bridge":2}],5:[function(require,module,exports){ +/** + * MIT LICENSCE + * From: https://github.com/remy/polyfills + * FIXME: Don't copy paste libraries, use a dep management system. + */ +(function () { + +if (typeof window.Element === "undefined" || "classList" in document.documentElement) return; + +var prototype = Array.prototype, + push = prototype.push, + splice = prototype.splice, + join = prototype.join; + +function DOMTokenList(el) { + this.el = el; + // The className needs to be trimmed and split on whitespace + // to retrieve a list of classes. + var classes = el.className.replace(/^\s+|\s+$/g,'').split(/\s+/); + for (var i = 0; i < classes.length; i++) { + push.call(this, classes[i]); + } +}; + +DOMTokenList.prototype = { + add: function(token) { + if(this.contains(token)) return; + push.call(this, token); + this.el.className = this.toString(); + }, + contains: function(token) { + return this.el.className.indexOf(token) != -1; + }, + item: function(index) { + return this[index] || null; + }, + remove: function(token) { + if (!this.contains(token)) return; + for (var i = 0; i < this.length; i++) { + if (this[i] == token) break; + } + splice.call(this, i, 1); + this.el.className = this.toString(); + }, + toString: function() { + return join.call(this, ' '); + }, + toggle: function(token) { + if (!this.contains(token)) { + this.add(token); + } else { + this.remove(token); + } + + return this.contains(token); + } +}; + +window.DOMTokenList = DOMTokenList; + +function defineElementGetter (obj, prop, getter) { + if (Object.defineProperty) { + Object.defineProperty(obj, prop,{ + get : getter + }); + } else { + obj.__defineGetter__(prop, getter); + } +} + +defineElementGetter(Element.prototype, 'classList', function () { + return new DOMTokenList(this); +}); + +})(); + +},{}],6:[function(require,module,exports){ var bridge = require("./bridge"); bridge.registerListener( "setDirectionality", function( payload ) { @@ -117,7 +194,7 @@ html.classList.add( "ui-" + payload.uiDirection ); } ); -},{"./bridge":2}],6:[function(require,module,exports){ +},{"./bridge":2}],7:[function(require,module,exports){ var bridge = require("./bridge"); var transformer = require("./transformer"); @@ -229,7 +306,7 @@ bridge.sendMessage( "currentSectionResponse", { sectionID: getCurrentSection() } ); } ); -},{"./bridge":2,"./transformer":7}],7:[function(require,module,exports){ +},{"./bridge":2,"./transformer":8}],8:[function(require,module,exports){ function Transformer() { } @@ -253,7 +330,7 @@ module.exports = new Transformer(); -},{}],8:[function(require,module,exports){ +},{}],9:[function(require,module,exports){ var bridge = require("./bridge"); var transformer = require("./transformer"); @@ -291,4 +368,4 @@ return content; } ); -},{"./bridge":2,"./transformer":7}]},{},[4,7,8,2,1,3,6,5]) \ No newline at end of file +},{"./bridge":2,"./transformer":8}]},{},[4,8,9,2,1,3,7,6,5]) \ No newline at end of file diff --git a/wikipedia/assets/preview.js b/wikipedia/assets/preview.js index 065b5db..798f8c2 100644 --- a/wikipedia/assets/preview.js +++ b/wikipedia/assets/preview.js @@ -76,6 +76,83 @@ module.exports.sendMessage( "DOMLoaded", {} ); }; },{}],3:[function(require,module,exports){ +/** + * MIT LICENSCE + * From: https://github.com/remy/polyfills + * FIXME: Don't copy paste libraries, use a dep management system. + */ +(function () { + +if (typeof window.Element === "undefined" || "classList" in document.documentElement) return; + +var prototype = Array.prototype, + push = prototype.push, + splice = prototype.splice, + join = prototype.join; + +function DOMTokenList(el) { + this.el = el; + // The className needs to be trimmed and split on whitespace + // to retrieve a list of classes. + var classes = el.className.replace(/^\s+|\s+$/g,'').split(/\s+/); + for (var i = 0; i < classes.length; i++) { + push.call(this, classes[i]); + } +}; + +DOMTokenList.prototype = { + add: function(token) { + if(this.contains(token)) return; + push.call(this, token); + this.el.className = this.toString(); + }, + contains: function(token) { + return this.el.className.indexOf(token) != -1; + }, + item: function(index) { + return this[index] || null; + }, + remove: function(token) { + if (!this.contains(token)) return; + for (var i = 0; i < this.length; i++) { + if (this[i] == token) break; + } + splice.call(this, i, 1); + this.el.className = this.toString(); + }, + toString: function() { + return join.call(this, ' '); + }, + toggle: function(token) { + if (!this.contains(token)) { + this.add(token); + } else { + this.remove(token); + } + + return this.contains(token); + } +}; + +window.DOMTokenList = DOMTokenList; + +function defineElementGetter (obj, prop, getter) { + if (Object.defineProperty) { + Object.defineProperty(obj, prop,{ + get : getter + }); + } else { + obj.__defineGetter__(prop, getter); + } +} + +defineElementGetter(Element.prototype, 'classList', function () { + return new DOMTokenList(this); +}); + +})(); + +},{}],4:[function(require,module,exports){ var bridge = require("./bridge"); bridge.registerListener( "displayPreviewHTML", function( payload ) { @@ -83,7 +160,7 @@ content.innerHTML = payload.html; } ); -},{"./bridge":2}],4:[function(require,module,exports){ +},{"./bridge":2}],5:[function(require,module,exports){ var bridge = require("./bridge"); bridge.registerListener( "setDirectionality", function( payload ) { @@ -93,4 +170,4 @@ html.classList.add( "ui-" + payload.uiDirection ); } ); -},{"./bridge":2}]},{},[2,1,3,4]) \ No newline at end of file +},{"./bridge":2}]},{},[2,1,4,5,3]) \ No newline at end of file diff --git a/www/Gruntfile.js b/www/Gruntfile.js index 3f89e9b..ce9212f 100644 --- a/www/Gruntfile.js +++ b/www/Gruntfile.js @@ -8,6 +8,7 @@ "js/editaction.js", "js/sections.js", "js/rtlsupport.js", + "js/polyfill/classList.js", "tests/*.js" ]; var allStyleFiles = [ @@ -17,6 +18,11 @@ "index.html", "tests/index.html" ]; + // FIXME: Unconditionally included polyfills. Should be included only for Android 2.3 + var oldDroidPolyfills = [ + "js/polyfill/classList.js" + ]; + grunt.initConfig( { pkg: grunt.file.readJSON( "package.json" ), browserify: { @@ -31,23 +37,23 @@ "js/editaction.js", "js/sections.js", "js/rtlsupport.js" - ], + ].concat( oldDroidPolyfills ), "bundle-test.js": [ "js/main.js", "js/bridge.js", "tests/*.js" - ], + ].concat( oldDroidPolyfills ), "abusefilter.js": [ "js/bridge.js", "js/abusefilter.js", "js/rtlsupport.js" - ], + ].concat( oldDroidPolyfills ), "preview.js": [ "js/bridge.js", "js/actions.js", "js/preview.js", "js/rtlsupport.js" - ] + ].concat( oldDroidPolyfills ) } } }, diff --git a/www/abusefilter.js b/www/abusefilter.js deleted file mode 100644 index 12fc2ea..0000000 --- a/www/abusefilter.js +++ /dev/null @@ -1,96 +0,0 @@ -(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 transformer = require('./transformer'); - -transformer.register( 'clearInlineStyling', function( content ) { - var styledElements = content.querySelectorAll( "*[style]" ); - for ( var i = 0; i < styledElements.length; i++ ) { - styledElements[i].removeAttribute( "style" ); - } - return content; -} ); - -bridge.registerListener( 'displayWarning', function( payload ) { - var content = document.getElementById( 'content' ); - - var warning = document.createElement( 'div' ); - warning.innerHTML = payload.html; - - warning = transformer.transform( 'clearInlineStyling', warning ); - - content.appendChild( warning ); -} ); - -},{"./bridge":2,"./transformer":4}],2:[function(require,module,exports){ -function Bridge() { -} - -var eventHandlers = {}; - -// This is called directly from Java -window.handleMessage = function( type, msgPointer ) { - var that = this; - var payload = JSON.parse( marshaller.getPayload( msgPointer ) ); - if ( eventHandlers.hasOwnProperty( type ) ) { - eventHandlers[type].forEach( function( callback ) { - callback.call( that, payload ); - } ); - } -}; - -Bridge.prototype.registerListener = function( messageType, callback ) { - if ( eventHandlers.hasOwnProperty( messageType ) ) { - eventHandlers[messageType].push( callback ); - } else { - eventHandlers[messageType] = [ callback ]; - } -}; - -Bridge.prototype.sendMessage = function( messageType, payload ) { - var messagePack = { type: messageType, payload: payload }; - var ret = window.prompt( JSON.stringify( messagePack) ); - if ( ret ) { - return JSON.parse( ret ); - } -}; - -module.exports = new Bridge(); -// FIXME: Move this to somwehere else, eh? -window.onload = function() { - module.exports.sendMessage( "DOMLoaded", {} ); -}; -},{}],3:[function(require,module,exports){ -var bridge = require("./bridge"); - -bridge.registerListener( "setDirectionality", function( payload ) { - var html = document.getElementsByTagName( "html" )[0]; - html.setAttribute( "dir", payload.contentDirection ); - html.classList.add( "content-" + payload.contentDirection ); - html.classList.add( "ui-" + payload.uiDirection ); -} ); - -},{"./bridge":2}],4:[function(require,module,exports){ -function Transformer() { -} - -var transforms = {}; - -Transformer.prototype.register = function( transform, fun ) { - if ( transform in transforms ) { - transforms[transform].append( fun ); - } else { - transforms[transform] = [ fun ]; - } -}; - -Transformer.prototype.transform = function( transform, element ) { - var functions = transforms[transform]; - for ( var i = 0; i < functions.length; i++ ) { - element = functions[i](element); - } - return element; -}; - -module.exports = new Transformer(); - -},{}]},{},[2,1,3]) \ No newline at end of file diff --git a/www/js/polyfill/classList.js b/www/js/polyfill/classList.js new file mode 100644 index 0000000..d41e033 --- /dev/null +++ b/www/js/polyfill/classList.js @@ -0,0 +1,75 @@ +/** + * MIT LICENSCE + * From: https://github.com/remy/polyfills + * FIXME: Don't copy paste libraries, use a dep management system. + */ +(function () { + +if (typeof window.Element === "undefined" || "classList" in document.documentElement) return; + +var prototype = Array.prototype, + push = prototype.push, + splice = prototype.splice, + join = prototype.join; + +function DOMTokenList(el) { + this.el = el; + // The className needs to be trimmed and split on whitespace + // to retrieve a list of classes. + var classes = el.className.replace(/^\s+|\s+$/g,'').split(/\s+/); + for (var i = 0; i < classes.length; i++) { + push.call(this, classes[i]); + } +}; + +DOMTokenList.prototype = { + add: function(token) { + if(this.contains(token)) return; + push.call(this, token); + this.el.className = this.toString(); + }, + contains: function(token) { + return this.el.className.indexOf(token) != -1; + }, + item: function(index) { + return this[index] || null; + }, + remove: function(token) { + if (!this.contains(token)) return; + for (var i = 0; i < this.length; i++) { + if (this[i] == token) break; + } + splice.call(this, i, 1); + this.el.className = this.toString(); + }, + toString: function() { + return join.call(this, ' '); + }, + toggle: function(token) { + if (!this.contains(token)) { + this.add(token); + } else { + this.remove(token); + } + + return this.contains(token); + } +}; + +window.DOMTokenList = DOMTokenList; + +function defineElementGetter (obj, prop, getter) { + if (Object.defineProperty) { + Object.defineProperty(obj, prop,{ + get : getter + }); + } else { + obj.__defineGetter__(prop, getter); + } +} + +defineElementGetter(Element.prototype, 'classList', function () { + return new DOMTokenList(this); +}); + +})(); diff --git a/www/preview.js b/www/preview.js deleted file mode 100644 index 065b5db..0000000 --- a/www/preview.js +++ /dev/null @@ -1,96 +0,0 @@ -(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'); - -function ActionsHandler() { -} - -var actionHandlers = {}; - -ActionsHandler.prototype.register = function( action, fun ) { - if ( action in actionHandlers ) { - actionHandlers[action].push( fun ); - } else { - actionHandlers[action] = [ fun ]; - } -}; - -document.onclick = function() { - if ( event.target.tagName === "A" ) { - if ( event.target.hasAttribute( "data-action" ) ) { - var action = event.target.getAttribute( "data-action" ); - var handlers = actionHandlers[ action ]; - for ( var i = 0; i < handlers.length; i++ ) { - handlers[i]( event.target, event ); - } - } else { - var href = event.target.getAttribute( "href" ); - if ( href[0] === "#" ) { - // If it is a link to an anchor in the current page, just scroll to it - document.getElementById( href.substring( 1 ) ).scrollIntoView(); - } else { - bridge.sendMessage( 'linkClicked', { "href": href } ); - } - event.preventDefault(); - } - } -}; - -module.exports = new ActionsHandler(); - -},{"./bridge":2}],2:[function(require,module,exports){ -function Bridge() { -} - -var eventHandlers = {}; - -// This is called directly from Java -window.handleMessage = function( type, msgPointer ) { - var that = this; - var payload = JSON.parse( marshaller.getPayload( msgPointer ) ); - if ( eventHandlers.hasOwnProperty( type ) ) { - eventHandlers[type].forEach( function( callback ) { - callback.call( that, payload ); - } ); - } -}; - -Bridge.prototype.registerListener = function( messageType, callback ) { - if ( eventHandlers.hasOwnProperty( messageType ) ) { - eventHandlers[messageType].push( callback ); - } else { - eventHandlers[messageType] = [ callback ]; - } -}; - -Bridge.prototype.sendMessage = function( messageType, payload ) { - var messagePack = { type: messageType, payload: payload }; - var ret = window.prompt( JSON.stringify( messagePack) ); - if ( ret ) { - return JSON.parse( ret ); - } -}; - -module.exports = new Bridge(); -// FIXME: Move this to somwehere else, eh? -window.onload = function() { - module.exports.sendMessage( "DOMLoaded", {} ); -}; -},{}],3:[function(require,module,exports){ -var bridge = require("./bridge"); - -bridge.registerListener( "displayPreviewHTML", function( payload ) { - var content = document.getElementById( "content" ); - content.innerHTML = payload.html; -} ); - -},{"./bridge":2}],4:[function(require,module,exports){ -var bridge = require("./bridge"); - -bridge.registerListener( "setDirectionality", function( payload ) { - var html = document.getElementsByTagName( "html" )[0]; - html.setAttribute( "dir", payload.contentDirection ); - html.classList.add( "content-" + payload.contentDirection ); - html.classList.add( "ui-" + payload.uiDirection ); -} ); - -},{"./bridge":2}]},{},[2,1,3,4]) \ No newline at end of file -- To view, visit https://gerrit.wikimedia.org/r/123798 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ida62cee03cf92b17c5d1ac2c35765388d449dea7 Gerrit-PatchSet: 5 Gerrit-Project: apps/android/wikipedia Gerrit-Branch: master Gerrit-Owner: Yuvipanda <yuvipa...@gmail.com> Gerrit-Reviewer: Brion VIBBER <br...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits