From 3b611160ac694429bcb10893e07aea5322ce9ba3 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Thu, 20 Mar 2014 09:03:56 -0700 Subject: [PATCH] Eliminate title cacheing for the time being. Causing too many problems. Also attempt to optimize Linkify. --- LICENSE | 2 +- builds/appchan-x.user.js | 124 ++++++++++++++----------------- builds/crx/script.js | 124 ++++++++++++++----------------- src/Linkification/Linkify.coffee | 118 +++++++++++++---------------- 4 files changed, 163 insertions(+), 205 deletions(-) diff --git a/LICENSE b/LICENSE index ffd6593de..ac7e286c4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* appchan x - Version 2.9.6 - 2014-03-19 +* appchan x - Version 2.9.6 - 2014-03-20 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js index 75bed633e..cc32286fd 100644 --- a/builds/appchan-x.user.js +++ b/builds/appchan-x.user.js @@ -25,7 +25,7 @@ // ==/UserScript== /* -* appchan x - Version 2.9.6 - 2014-03-19 +* appchan x - Version 2.9.6 - 2014-03-20 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE @@ -8120,20 +8120,21 @@ cb: this.node }); }, - node: function() { - var data, el, end, endNode, i, index, items, length, link, links, node, result, saved, snapshot, space, test, word, _i, _len, _ref; - if (this.isClone) { - if (Conf['Embedding']) { - i = 0; - items = $$('.embedder', this.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Linkify.cb.toggle); - if ($.hasClass(el, 'embedded')) { - Linkify.cb.toggle.call(el); - } - } + events: function(post) { + var el, i, items; + i = 0; + items = $$('.embedder', post.nodes.comment); + while (el = items[i++]) { + $.on(el, 'click', Linkify.cb.toggle); + if ($.hasClass(el, 'embedded')) { + Linkify.cb.toggle.call(el); } - return; + } + }, + node: function() { + var data, end, endNode, i, index, length, link, links, node, result, saved, snapshot, space, test, word; + if (this.isClone) { + return (Conf['Embedding'] ? Linkify.events(this) : null); } if (!Linkify.regString.test(this.info.comment)) { return; @@ -8145,7 +8146,7 @@ links = []; while (node = snapshot.snapshotItem(i++)) { data = node.data; - if (node.parentElement.nodeName === "A" || !data) { + if (!data || node.parentElement.nodeName === "A") { continue; } while (result = test.exec(data)) { @@ -8177,25 +8178,20 @@ } } } - _ref = links.reverse(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - this.nodes.links.push(Linkify.makeLink(link, this)); - link.detach(); + i = links.length; + while (i--) { + link = links[i]; + Linkify.embedProcess(Linkify.makeLink(link, this)); } - if (!(Conf['Embedding'] || Conf['Link Title'])) { - return; - } - links = this.nodes.links; - i = 0; - while (link = links[i++]) { - if (data = Linkify.services(link)) { - if (Conf['Embedding']) { - Linkify.embed(data); - } - if (Conf['Link Title']) { - Linkify.title(data); - } + }, + embedProcess: function(link) { + var data; + if (data = Linkify.services(link)) { + if (Conf['Embedding']) { + Linkify.embed(data); + } + if (Conf['Link Title']) { + return Linkify.title(data); } } }, @@ -8250,6 +8246,7 @@ }); $.add(a, range.extractContents()); range.insertNode(a); + range.detach(); return a; }, services: function(link) { @@ -8258,10 +8255,9 @@ _ref = Linkify.types; for (key in _ref) { type = _ref[key]; - if (!(match = type.regExp.exec(href))) { - continue; + if (match = type.regExp.exec(href)) { + return [key, match[1], match[2], link]; } - return [key, match[1], match[2], link]; } }, embed: function(data) { @@ -8290,7 +8286,7 @@ if (Conf['Auto-embed']) { Linkify.cb.toggle.call(embed); } - data.push(embed); + return data.push(embed); }, title: function(data) { var embed, err, key, link, options, service, title, titles, uid; @@ -8308,9 +8304,9 @@ } } else { try { - $.cache(service.api(uid), function() { - return title = Linkify.cb.title(this, data); - }, { + return $.cache(service.api(uid), (function() { + return Linkify.cb.title(this, data); + }), { responseType: 'json' }); } catch (_error) { @@ -8318,23 +8314,15 @@ if (link) { link.innerHTML = "[" + key + "] Title Link Blocked (are you using NoScript?)"; } - return; - } - if (title) { - titles[uid] = [title, Date.now()]; - return $.set('CachedTitles', titles); } } }, - titleSync: function(value) { - return Conf['CachedTitles'] = value; - }, clean: function() { - var age, name, pruned, uid, _ref, _ref1; + var age, pruned, uid, _, _ref, _ref1; pruned = false; _ref = Conf['CachedTitles']; for (uid in _ref) { - _ref1 = _ref[uid], name = _ref1[0], age = _ref1[1]; + _ref1 = _ref[uid], _ = _ref1[0], age = _ref1[1]; if (!(age + $.DAY > Date.now())) { continue; } @@ -8370,26 +8358,26 @@ $.addClass(el, a.dataset.key); return el; }, - title: function(response, data) { - var embed, key, link, options, service, text, uid; + title: function(req, data) { + var embed, key, link, options, service, status, text, uid; key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; + status = req.status; service = Linkify.types[key].title; - switch (response.status) { - case 200: - case 304: - text = "" + (service.text(response.response)); - if (Conf['Embedding']) { - embed.dataset.title = text; - } - break; - case 404: - text = "[" + key + "] Not Found"; - break; - case 403: - text = "[" + key + "] Forbidden or Private"; - break; - default: - text = "[" + key + "] " + this.status + "'d"; + text = "[" + key + "] " + ((function() { + switch (status) { + case 200: + case 304: + return service.text(req.response); + case 404: + return "Not Found"; + case 403: + return "Forbidden or Private"; + default: + return "" + status + "'d"; + } + })()); + if (Conf['Embedding'] && (status === 200 || status === 304)) { + embed.dataset.title = text; } if (link) { return link.textContent = text; diff --git a/builds/crx/script.js b/builds/crx/script.js index fe43a1dd1..0248c5650 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* appchan x - Version 2.9.6 - 2014-03-19 +* appchan x - Version 2.9.6 - 2014-03-20 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE @@ -8171,20 +8171,21 @@ cb: this.node }); }, - node: function() { - var data, el, end, endNode, i, index, items, length, link, links, node, result, saved, snapshot, space, test, word, _i, _len, _ref; - if (this.isClone) { - if (Conf['Embedding']) { - i = 0; - items = $$('.embedder', this.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Linkify.cb.toggle); - if ($.hasClass(el, 'embedded')) { - Linkify.cb.toggle.call(el); - } - } + events: function(post) { + var el, i, items; + i = 0; + items = $$('.embedder', post.nodes.comment); + while (el = items[i++]) { + $.on(el, 'click', Linkify.cb.toggle); + if ($.hasClass(el, 'embedded')) { + Linkify.cb.toggle.call(el); } - return; + } + }, + node: function() { + var data, end, endNode, i, index, length, link, links, node, result, saved, snapshot, space, test, word; + if (this.isClone) { + return (Conf['Embedding'] ? Linkify.events(this) : null); } if (!Linkify.regString.test(this.info.comment)) { return; @@ -8196,7 +8197,7 @@ links = []; while (node = snapshot.snapshotItem(i++)) { data = node.data; - if (node.parentElement.nodeName === "A" || !data) { + if (!data || node.parentElement.nodeName === "A") { continue; } while (result = test.exec(data)) { @@ -8228,25 +8229,20 @@ } } } - _ref = links.reverse(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - this.nodes.links.push(Linkify.makeLink(link, this)); - link.detach(); + i = links.length; + while (i--) { + link = links[i]; + Linkify.embedProcess(Linkify.makeLink(link, this)); } - if (!(Conf['Embedding'] || Conf['Link Title'])) { - return; - } - links = this.nodes.links; - i = 0; - while (link = links[i++]) { - if (data = Linkify.services(link)) { - if (Conf['Embedding']) { - Linkify.embed(data); - } - if (Conf['Link Title']) { - Linkify.title(data); - } + }, + embedProcess: function(link) { + var data; + if (data = Linkify.services(link)) { + if (Conf['Embedding']) { + Linkify.embed(data); + } + if (Conf['Link Title']) { + return Linkify.title(data); } } }, @@ -8301,6 +8297,7 @@ }); $.add(a, range.extractContents()); range.insertNode(a); + range.detach(); return a; }, services: function(link) { @@ -8309,10 +8306,9 @@ _ref = Linkify.types; for (key in _ref) { type = _ref[key]; - if (!(match = type.regExp.exec(href))) { - continue; + if (match = type.regExp.exec(href)) { + return [key, match[1], match[2], link]; } - return [key, match[1], match[2], link]; } }, embed: function(data) { @@ -8341,7 +8337,7 @@ if (Conf['Auto-embed']) { Linkify.cb.toggle.call(embed); } - data.push(embed); + return data.push(embed); }, title: function(data) { var embed, err, key, link, options, service, title, titles, uid; @@ -8359,9 +8355,9 @@ } } else { try { - $.cache(service.api(uid), function() { - return title = Linkify.cb.title(this, data); - }, { + return $.cache(service.api(uid), (function() { + return Linkify.cb.title(this, data); + }), { responseType: 'json' }); } catch (_error) { @@ -8369,23 +8365,15 @@ if (link) { link.innerHTML = "[" + key + "] Title Link Blocked (are you using NoScript?)"; } - return; - } - if (title) { - titles[uid] = [title, Date.now()]; - return $.set('CachedTitles', titles); } } }, - titleSync: function(value) { - return Conf['CachedTitles'] = value; - }, clean: function() { - var age, name, pruned, uid, _ref, _ref1; + var age, pruned, uid, _, _ref, _ref1; pruned = false; _ref = Conf['CachedTitles']; for (uid in _ref) { - _ref1 = _ref[uid], name = _ref1[0], age = _ref1[1]; + _ref1 = _ref[uid], _ = _ref1[0], age = _ref1[1]; if (!(age + $.DAY > Date.now())) { continue; } @@ -8421,26 +8409,26 @@ $.addClass(el, a.dataset.key); return el; }, - title: function(response, data) { - var embed, key, link, options, service, text, uid; + title: function(req, data) { + var embed, key, link, options, service, status, text, uid; key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; + status = req.status; service = Linkify.types[key].title; - switch (response.status) { - case 200: - case 304: - text = "" + (service.text(response.response)); - if (Conf['Embedding']) { - embed.dataset.title = text; - } - break; - case 404: - text = "[" + key + "] Not Found"; - break; - case 403: - text = "[" + key + "] Forbidden or Private"; - break; - default: - text = "[" + key + "] " + this.status + "'d"; + text = "[" + key + "] " + ((function() { + switch (status) { + case 200: + case 304: + return service.text(req.response); + case 404: + return "Not Found"; + case 403: + return "Forbidden or Private"; + default: + return "" + status + "'d"; + } + })()); + if (Conf['Embedding'] && (status === 200 || status === 304)) { + embed.dataset.title = text; } if (link) { return link.textContent = text; diff --git a/src/Linkification/Linkify.coffee b/src/Linkification/Linkify.coffee index 1a1c1e807..86f691e75 100755 --- a/src/Linkification/Linkify.coffee +++ b/src/Linkification/Linkify.coffee @@ -13,28 +13,26 @@ Linkify = name: 'Linkify' cb: @node + events: (post) -> + i = 0 + items = $$ '.embedder', post.nodes.comment + while el = items[i++] + $.on el, 'click', Linkify.cb.toggle + Linkify.cb.toggle.call el if $.hasClass el, 'embedded' + return + node: -> - if @isClone - if Conf['Embedding'] - i = 0 - items = $$ '.embedder', @nodes.comment - while el = items[i++] - $.on el, 'click', Linkify.cb.toggle - Linkify.cb.toggle.call el if $.hasClass el, 'embedded' - - return - + return (if Conf['Embedding'] then Linkify.events @ else null) if @isClone return unless Linkify.regString.test @info.comment - test = /[^\s'"]+/g - space = /[\s'"]/ - + test = /[^\s'"]+/g + space = /[\s'"]/ snapshot = $.X './/br|.//text()', @nodes.comment i = 0 links = [] while node = snapshot.snapshotItem i++ {data} = node - continue if node.parentElement.nodeName is "A" or not data + continue if !data or node.parentElement.nodeName is "A" while result = test.exec data {index} = result @@ -59,41 +57,33 @@ Linkify = i-- break - if Linkify.regString.exec word - links.push Linkify.makeRange node, endNode, index, length + links.push Linkify.makeRange node, endNode, index, length if Linkify.regString.exec word break unless test.lastIndex and node is endNode - for link in links.reverse() - @nodes.links.push Linkify.makeLink link, @ - link.detach() - - return unless Conf['Embedding'] or Conf['Link Title'] - - {links} = @nodes - i = 0 - while link = links[i++] - if data = Linkify.services link - Linkify.embed data if Conf['Embedding'] - Linkify.title data if Conf['Link Title'] - + i = links.length + while i-- + link = links[i] + Linkify.embedProcess Linkify.makeLink link, @ return + embedProcess: (link) -> + if data = Linkify.services link + Linkify.embed data if Conf['Embedding'] + Linkify.title data if Conf['Link Title'] + regString: ///( # http, magnet, ftp, etc (https?|mailto|git|magnet|ftp|irc):( [a-z\d%/] ) - | - # This should account for virtually all links posted without http: + | # This should account for virtually all links posted without http: [-a-z\d]+[.]( aero|asia|biz|cat|com|coop|info|int|jobs|mobi|museum|name|net|org|post|pro|tel|travel|xxx|edu|gov|mil|[a-z]{2} )(/|(?!.)) - | - # IPv4 Addresses + | # IPv4 Addresses [\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3} - | - # E-mails + | # E-mails [-\w\d.@]+@[a-z\d.-]+\.[a-z\d] )///i @@ -106,7 +96,7 @@ Linkify = makeLink: (range) -> text = range.toString() - # Clean leading brackets, > + # Clean start of range i = 0 i++ while /[(\[{<>]/.test text.charAt i @@ -116,7 +106,7 @@ Linkify = range.setStart range.startContainer, range.startOffset + i if i - # Clean hanging brackets, commas, periods + # Clean end of range i = 0 while /[)\]}>.,]/.test t = text.charAt text.length - (1 + i) break unless /[.,]/.test(t) or (text.match /[()\[\]{}<>]/g).length % 2 @@ -129,6 +119,7 @@ Linkify = if i range.setEnd range.endContainer, range.endOffset - i + # Make our link 'valid' if it is formatted incorrectly. unless /(https?|mailto|git|magnet|ftp|irc):/.test text text = ( if /@/.test text @@ -142,15 +133,17 @@ Linkify = rel: 'nofollow noreferrer' target: '_blank' href: text + + # Insert the range into the anchor, the anchor into the range's DOM location, and destroy the range. $.add a, range.extractContents() range.insertNode a + range.detach() + a services: (link) -> - href = link.href - - for key, type of Linkify.types - continue unless match = type.regExp.exec href + {href} = link + for key, type of Linkify.types when match = type.regExp.exec href return [key, match[1], match[2], link] return @@ -162,9 +155,7 @@ Linkify = href: 'javascript:;' textContent: '(embed)' - for name, value of {key, href, uid, options} - embed.dataset[name] = value - + embed.dataset[name] = value for name, value of {key, href, uid, options} embed.dataset.nodedata = link.innerHTML $.addClass link, "#{embed.dataset.key}" @@ -172,13 +163,10 @@ Linkify = $.on embed, 'click', Linkify.cb.toggle $.after link, [$.tn(' '), embed] - if Conf['Auto-embed'] - Linkify.cb.toggle.call embed + Linkify.cb.toggle.call embed if Conf['Auto-embed'] data.push embed - return - title: (data) -> [key, uid, options, link, embed] = data return unless service = Linkify.types[key].title @@ -191,24 +179,15 @@ Linkify = embed.dataset.title = title[0] else try - $.cache service.api(uid), - -> title = Linkify.cb.title @, data - , - responseType: 'json' + $.cache service.api(uid), (-> Linkify.cb.title @, data), responseType: 'json' catch err if link link.innerHTML = "[#{key}] Title Link Blocked (are you using NoScript?)" return - if title - titles[uid] = [title, Date.now()] - $.set 'CachedTitles', titles - - titleSync: (value) -> - Conf['CachedTitles'] = value clean: -> pruned = false - for uid, [name, age] of Conf['CachedTitles'] when age + $.DAY > Date.now() + for uid, [_, age] of Conf['CachedTitles'] when age + $.DAY > Date.now() pruned = true delete Conf['CachedTitles'][uid] $.set 'CachedTitles', Conf['CachedTitles'] if pruned @@ -247,21 +226,24 @@ Linkify = return el - title: (response, data) -> + title: (req, data) -> [key, uid, options, link, embed] = data + {status} = req service = Linkify.types[key].title - switch response.status + + text = "[#{key}] #{switch status when 200, 304 - text = "#{service.text response.response}" - if Conf['Embedding'] - embed.dataset.title = text + service.text req.response when 404 - text = "[#{key}] Not Found" + "Not Found" when 403 - text = "[#{key}] Forbidden or Private" + "Forbidden or Private" else - text = "[#{key}] #{@status}'d" - link.textContent = text if link + "#{status}'d" + }" + + embed.dataset.title = text if Conf['Embedding'] and status in [200, 304] + link.textContent = text if link types: audio: