From af34b16310086aea5f6e6f852e9b41b54316d67d Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 16 Feb 2012 21:14:53 +0100 Subject: [PATCH] Use Mutation Observers instead of Mutation Events for inserted elements in the threads on Chrome 18+ and other browsers once they support it. It is 330% faster to expand the 1200 replies sticky on /a/ using this method. --- 4chan_x.user.js | 56 ++++++++++++++++++++++++++++++------------------- script.coffee | 36 +++++++++++++++++++------------ 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 75e570313..7ffab04c6 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3594,7 +3594,7 @@ return $.ready(Main.ready); }, ready: function() { - var callback, form, node, nodes, _i, _j, _len, _len2, _ref; + var MutationObserver, form, nodes, observer; if (d.title === '4chan - 404') { redirect.init(); return; @@ -3622,19 +3622,16 @@ } form = $('body > form'); nodes = $$('.op, a + table', form); - _ref = g.callbacks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - callback = _ref[_i]; - try { - for (_j = 0, _len2 = nodes.length; _j < _len2; _j++) { - node = nodes[_j]; - callback(node); - } - } catch (err) { - alert(err); - } + Main.node(nodes, true); + if (MutationObserver = window.WebKitMutationObserver || window.MozMutationObserver || window.OMutationObserver || window.MutationObserver) { + observer = new MutationObserver(Main.observer); + return observer.observe(form, { + childList: true, + subtree: true + }); + } else { + return $.on(form, 'DOMNodeInserted', Main.listener); } - return $.on(form, 'DOMNodeInserted', Main.node); }, addStyle: function() { $.off(d, 'DOMNodeInserted', Main.addStyle); @@ -3654,21 +3651,38 @@ return window.location = "https://raw.github.com/mayhemydg/4chan-x/" + version + "/4chan_x.user.js"; } }, - node: function(e) { - var callback, target, _i, _len, _ref, _results; - target = e.target; - if (target.nodeName !== 'TABLE') return; + node: function(nodes, notify) { + var callback, node, _i, _j, _len, _len2, _ref; _ref = g.callbacks; - _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { callback = _ref[_i]; try { - _results.push(callback(target)); + for (_j = 0, _len2 = nodes.length; _j < _len2; _j++) { + node = nodes[_j]; + callback(node); + } } catch (err) { - + if (notify) alert(err.message); } } - return _results; + }, + observer: function(mutations) { + var addedNode, mutation, nodes, _i, _j, _len, _len2, _ref; + nodes = []; + for (_i = 0, _len = mutations.length; _i < _len; _i++) { + mutation = mutations[_i]; + _ref = mutation.addedNodes; + for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) { + addedNode = _ref[_j]; + if (addedNode.nodeName === 'TABLE') nodes.push(addedNode); + } + } + if (nodes.length) return Main.node(nodes); + }, + listener: function(e) { + var target; + target = e.target; + if (target.nodeName === 'TABLE') return Main.node([target]); }, css: '\ /* dialog styling */\ diff --git a/script.coffee b/script.coffee index aa739a01e..dc38b3353 100644 --- a/script.coffee +++ b/script.coffee @@ -2738,7 +2738,7 @@ imgExpand = Main = init: -> - pathname = location.pathname[1..].split('/') + pathname = location.pathname[1..].split '/' [g.BOARD, temp] = pathname if temp is 'res' g.REPLY = true @@ -2898,13 +2898,15 @@ Main = form = $ 'body > form' nodes = $$ '.op, a + table', form - for callback in g.callbacks - try - for node in nodes - callback node - catch err - alert err - $.on form, 'DOMNodeInserted', Main.node + Main.node nodes, true + + if MutationObserver = window.WebKitMutationObserver or window.MozMutationObserver or window.OMutationObserver or window.MutationObserver + observer = new MutationObserver Main.observer + observer.observe form, + childList: true + subtree: true + else + $.on form, 'DOMNodeInserted', Main.listener addStyle: -> $.off d, 'DOMNodeInserted', Main.addStyle @@ -2921,14 +2923,22 @@ Main = else if version and version isnt VERSION and confirm 'An updated version of 4chan X is available, would you like to install it now?' window.location = "https://raw.github.com/mayhemydg/4chan-x/#{version}/4chan_x.user.js" - node: (e) -> - {target} = e - return unless target.nodeName is 'TABLE' + node: (nodes, notify) -> for callback in g.callbacks try - callback target + callback node for node in nodes catch err - #nothing + alert err.message if notify + return + observer: (mutations) -> + nodes = [] + for mutation in mutations + for addedNode in mutation.addedNodes + nodes.push addedNode if addedNode.nodeName is 'TABLE' + Main.node nodes if nodes.length + listener: (e) -> + {target} = e + Main.node [target] if target.nodeName is 'TABLE' css: ' /* dialog styling */