diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js index e42b3dfe0..4d0b8923f 100644 --- a/builds/appchan-x.user.js +++ b/builds/appchan-x.user.js @@ -6591,20 +6591,23 @@ Linkify = { init: function() { - if (g.VIEW === 'catalog') { + if (g.VIEW === 'catalog' || !Conf['Linkify']) { return; } this.regString = Conf['Allow False Positives'] ? /(\b([a-z]+:\/\/|[a-z]{3,}\.[-a-z0-9]+\.[a-z]|[-a-z0-9]+\.[a-z]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]|[a-z]{3,}:[a-z0-9?]|[\S]+@[a-z0-9.-]+\.[a-z0-9])[^\s'"]+)/gi : /(((magnet|mailto)\:|(www\.)|(news|(ht|f)tp(s?))\:\/\/){1}\S+)/gi; if (Conf['Comment Expansion']) { ExpandComment.callbacks.push(this.node); } + if (Conf['Title Link']) { + $.sync('CachedTitles', Linkify.titleSync); + } return Post.prototype.callbacks.push({ name: 'Linkify', cb: this.node }); }, node: function() { - var data, embedder, i, len, link, links, match, node, range, snapshot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + var data, embedder, i, len, match, node, range, snapshot, _i, _j, _len, _len1, _ref, _ref1; if (this.isClone && Conf['Embedding']) { _ref = $$('.embedder', this.nodes.comment); @@ -6617,40 +6620,32 @@ snapshot = $.X('.//text()', this.nodes.comment); i = -1; len = snapshot.snapshotLength; - links = []; while (++i < len) { node = snapshot.snapshotItem(i); data = node.data; if (match = data.match(Linkify.regString)) { - links.pushArrays(Linkify.gatherLinks(match, node)); - } - } - if (Conf['Linkify']) { - for (_j = 0, _len1 = links.length; _j < _len1; _j++) { - range = links[_j]; - this.nodes.links.push(Linkify.makeLink(range)); + Linkify.gatherLinks(match, node, this); } } if (!(Conf['Embedding'] || Conf['Link Title'])) { return; } - _ref1 = this.nodes.links || links; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - range = _ref1[_k]; - if (link = Linkify.services(range)) { + _ref1 = this.nodes.links; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + range = _ref1[_j]; + if (data = Linkify.services(range)) { if (Conf['Embedding']) { - Linkify.embed(link); + Linkify.embed(data); } if (Conf['Link Title']) { - Linkify.title(link); + Linkify.title(data); } } } }, - gatherLinks: function(match, node) { - var data, i, len, len2, link, links, next, range, result; + gatherLinks: function(match, node, post) { + var data, i, len, len2, link, next, range, result; - links = []; i = 0; len = match.length; data = node.data; @@ -6658,14 +6653,14 @@ range = document.createRange(); range.setStart(node, len2 = data.indexOf(link)); range.setEnd(node, len2 + link.length); - links.push(range); + post.nodes.links.push(Linkify.makeLink(range)); } range = document.createRange(); range.setStart(node, len = data.indexOf(link)); if ((data.length - (len += link.length)) > 0) { range.setEnd(node, len); - links.push(range); - return links; + post.nodes.links.push(Linkify.makeLink(range)); + return; } while ((next = node.nextSibling) && next.nodeName.toLowerCase() !== 'br') { node = next; @@ -6680,8 +6675,7 @@ } range.setEnd(node, node.length); } - links.push(range); - return links; + post.nodes.links.push(Linkify.makeLink(range)); }, makeLink: function(range) { var a, link; @@ -6700,16 +6694,13 @@ services: function(link) { var href, key, match, type, _ref; - href = Conf['Linkify'] ? link.href : link.toString(); + href = link.href; _ref = Linkify.types; for (key in _ref) { type = _ref[key]; if (!(match = type.regExp.exec(href))) { continue; } - if (!Conf['Linkify']) { - link = Linkify.makeLink(link); - } return [key, match[1], match[2], link]; } }, @@ -6730,6 +6721,36 @@ $.on(embed, 'click', Linkify.cb.toggle); return $.after(link, [$.tn(' '), embed]); }, + title: function(data) { + var err, key, link, options, service, title, titles, uid; + + key = data[0], uid = data[1], options = data[2], link = data[3]; + service = Linkify.types[key].title; + titles = Conf['CachedTitles']; + if (title = titles[uid]) { + link.textContent = title[0]; + if (Conf['Embedding']) { + return link.nextElementSibling.dataset.title = title[0]; + } + } else { + try { + $.cache(service.api(uid), function() { + return title = Linkify.cb.title.apply(this, [data]); + }); + } catch (_error) { + err = _error; + 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; + }, cb: { toggle: function() { var el, embed; @@ -6785,39 +6806,6 @@ }).call(this); } }, - title: function(data) { - var key, link, options, service, title, titles, uid; - - key = data[0], uid = data[1], options = data[2], link = data[3]; - titles = {}; - service = Linkify.types[key].title; - title = ""; - return $.get('CachedTitles', {}, function(item) { - var err; - - titles = item['CachedTitles']; - if (title = titles[uid]) { - link.textContent = title[0]; - if (Conf['Embedding']) { - link.nextElementSibling.dataset.title = title[0]; - } - } else { - try { - $.cache(service.api(uid), function() { - return title = Linkify.cb.title.apply(this, [data]); - }); - } catch (_error) { - err = _error; - link.innerHTML = "[" + key + "] Title Link Blocked (are you using NoScript?)"; - return; - } - if (title) { - titles[uid] = [title, Date.now()]; - return $.set('CachedTitles', titles); - } - } - }); - }, types: { YouTube: { regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, @@ -14549,7 +14537,8 @@ 'Enabled Mascots nsfw': [], 'Deleted Mascots': [], 'Hidden Categories': ["Questionable"], - 'selectedArchives': {} + 'selectedArchives': {}, + 'CachedTitles': {} }); return $.get(Conf, Main.initFeatures); }, @@ -14557,10 +14546,6 @@ var init, pathname, _ref; Conf = items; - if (Conf['Post Form Style'] === 'transparent fade') { - $.set('Post Form Style', Conf['Post Form Style'] = 'fixed'); - $.set('Transparent Post Form', Conf['Transparent Post Form'] = true); - } pathname = location.pathname.split('/'); g.BOARD = new Board(pathname[1]); g.VIEW = (function() { diff --git a/builds/crx/script.js b/builds/crx/script.js index e53526221..05e52c410 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -6594,20 +6594,23 @@ Linkify = { init: function() { - if (g.VIEW === 'catalog') { + if (g.VIEW === 'catalog' || !Conf['Linkify']) { return; } this.regString = Conf['Allow False Positives'] ? /(\b([a-z]+:\/\/|[a-z]{3,}\.[-a-z0-9]+\.[a-z]|[-a-z0-9]+\.[a-z]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]|[a-z]{3,}:[a-z0-9?]|[\S]+@[a-z0-9.-]+\.[a-z0-9])[^\s'"]+)/gi : /(((magnet|mailto)\:|(www\.)|(news|(ht|f)tp(s?))\:\/\/){1}\S+)/gi; if (Conf['Comment Expansion']) { ExpandComment.callbacks.push(this.node); } + if (Conf['Title Link']) { + $.sync('CachedTitles', Linkify.titleSync); + } return Post.prototype.callbacks.push({ name: 'Linkify', cb: this.node }); }, node: function() { - var data, embedder, i, len, link, links, match, node, range, snapshot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + var data, embedder, i, len, match, node, range, snapshot, _i, _j, _len, _len1, _ref, _ref1; if (this.isClone && Conf['Embedding']) { _ref = $$('.embedder', this.nodes.comment); @@ -6620,40 +6623,32 @@ snapshot = $.X('.//text()', this.nodes.comment); i = -1; len = snapshot.snapshotLength; - links = []; while (++i < len) { node = snapshot.snapshotItem(i); data = node.data; if (match = data.match(Linkify.regString)) { - links.pushArrays(Linkify.gatherLinks(match, node)); - } - } - if (Conf['Linkify']) { - for (_j = 0, _len1 = links.length; _j < _len1; _j++) { - range = links[_j]; - this.nodes.links.push(Linkify.makeLink(range)); + Linkify.gatherLinks(match, node, this); } } if (!(Conf['Embedding'] || Conf['Link Title'])) { return; } - _ref1 = this.nodes.links || links; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - range = _ref1[_k]; - if (link = Linkify.services(range)) { + _ref1 = this.nodes.links; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + range = _ref1[_j]; + if (data = Linkify.services(range)) { if (Conf['Embedding']) { - Linkify.embed(link); + Linkify.embed(data); } if (Conf['Link Title']) { - Linkify.title(link); + Linkify.title(data); } } } }, - gatherLinks: function(match, node) { - var data, i, len, len2, link, links, next, range, result; + gatherLinks: function(match, node, post) { + var data, i, len, len2, link, next, range, result; - links = []; i = 0; len = match.length; data = node.data; @@ -6661,14 +6656,14 @@ range = document.createRange(); range.setStart(node, len2 = data.indexOf(link)); range.setEnd(node, len2 + link.length); - links.push(range); + post.nodes.links.push(Linkify.makeLink(range)); } range = document.createRange(); range.setStart(node, len = data.indexOf(link)); if ((data.length - (len += link.length)) > 0) { range.setEnd(node, len); - links.push(range); - return links; + post.nodes.links.push(Linkify.makeLink(range)); + return; } while ((next = node.nextSibling) && next.nodeName.toLowerCase() !== 'br') { node = next; @@ -6683,8 +6678,7 @@ } range.setEnd(node, node.length); } - links.push(range); - return links; + post.nodes.links.push(Linkify.makeLink(range)); }, makeLink: function(range) { var a, link; @@ -6703,16 +6697,13 @@ services: function(link) { var href, key, match, type, _ref; - href = Conf['Linkify'] ? link.href : link.toString(); + href = link.href; _ref = Linkify.types; for (key in _ref) { type = _ref[key]; if (!(match = type.regExp.exec(href))) { continue; } - if (!Conf['Linkify']) { - link = Linkify.makeLink(link); - } return [key, match[1], match[2], link]; } }, @@ -6733,6 +6724,36 @@ $.on(embed, 'click', Linkify.cb.toggle); return $.after(link, [$.tn(' '), embed]); }, + title: function(data) { + var err, key, link, options, service, title, titles, uid; + + key = data[0], uid = data[1], options = data[2], link = data[3]; + service = Linkify.types[key].title; + titles = Conf['CachedTitles']; + if (title = titles[uid]) { + link.textContent = title[0]; + if (Conf['Embedding']) { + return link.nextElementSibling.dataset.title = title[0]; + } + } else { + try { + $.cache(service.api(uid), function() { + return title = Linkify.cb.title.apply(this, [data]); + }); + } catch (_error) { + err = _error; + 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; + }, cb: { toggle: function() { var el, embed; @@ -6788,39 +6809,6 @@ }).call(this); } }, - title: function(data) { - var key, link, options, service, title, titles, uid; - - key = data[0], uid = data[1], options = data[2], link = data[3]; - titles = {}; - service = Linkify.types[key].title; - title = ""; - return $.get('CachedTitles', {}, function(item) { - var err; - - titles = item['CachedTitles']; - if (title = titles[uid]) { - link.textContent = title[0]; - if (Conf['Embedding']) { - link.nextElementSibling.dataset.title = title[0]; - } - } else { - try { - $.cache(service.api(uid), function() { - return title = Linkify.cb.title.apply(this, [data]); - }); - } catch (_error) { - err = _error; - link.innerHTML = "[" + key + "] Title Link Blocked (are you using NoScript?)"; - return; - } - if (title) { - titles[uid] = [title, Date.now()]; - return $.set('CachedTitles', titles); - } - } - }); - }, types: { YouTube: { regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, @@ -14526,7 +14514,8 @@ 'Enabled Mascots nsfw': [], 'Deleted Mascots': [], 'Hidden Categories': ["Questionable"], - 'selectedArchives': {} + 'selectedArchives': {}, + 'CachedTitles': {} }); return $.get(Conf, Main.initFeatures); }, @@ -14534,10 +14523,6 @@ var init, pathname, _ref; Conf = items; - if (Conf['Post Form Style'] === 'transparent fade') { - $.set('Post Form Style', Conf['Post Form Style'] = 'fixed'); - $.set('Transparent Post Form', Conf['Transparent Post Form'] = true); - } pathname = location.pathname.split('/'); g.BOARD = new Board(pathname[1]); g.VIEW = (function() { diff --git a/src/General/Main.coffee b/src/General/Main.coffee index dbd263591..959783d66 100644 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -27,18 +27,13 @@ Main = 'Deleted Mascots': [] 'Hidden Categories': ["Questionable"] 'selectedArchives': {} + 'CachedTitles': {} $.get Conf, Main.initFeatures initFeatures: (items) -> Conf = items - if Conf['Post Form Style'] is 'transparent fade' - # XXX Compatibility to break old option into new option(s) - # Remove by 2.2.x - $.set 'Post Form Style', Conf['Post Form Style'] = 'fixed' - $.set 'Transparent Post Form', Conf['Transparent Post Form'] = true - pathname = location.pathname.split '/' g.BOARD = new Board pathname[1] g.VIEW = diff --git a/src/Linkification/Linkify.coffee b/src/Linkification/Linkify.coffee index 3dbd06adb..84a1deda9 100644 --- a/src/Linkification/Linkify.coffee +++ b/src/Linkification/Linkify.coffee @@ -1,6 +1,6 @@ Linkify = init: -> - return if g.VIEW is 'catalog' + return if g.VIEW is 'catalog' or not Conf['Linkify'] @regString = if Conf['Allow False Positives'] ///( @@ -25,6 +25,9 @@ Linkify = if Conf['Comment Expansion'] ExpandComment.callbacks.push @node + if Conf['Title Link'] + $.sync 'CachedTitles', Linkify.titleSync + Post::callbacks.push name: 'Linkify' cb: @node @@ -36,51 +39,43 @@ Linkify = return snapshot = $.X './/text()', @nodes.comment - i = -1 - len = snapshot.snapshotLength - links = [] + i = -1 + len = snapshot.snapshotLength while ++i < len node = snapshot.snapshotItem i data = node.data if match = data.match Linkify.regString - links.pushArrays Linkify.gatherLinks match, node - - if Conf['Linkify'] - for range in links - @nodes.links.push Linkify.makeLink range + Linkify.gatherLinks match, node, @ return unless Conf['Embedding'] or Conf['Link Title'] - - for range in @nodes.links or links - if link = Linkify.services range - if Conf['Embedding'] - Linkify.embed link - if Conf['Link Title'] - Linkify.title link + + for range in @nodes.links + if data = Linkify.services range + Linkify.embed data if Conf['Embedding'] + Linkify.title data if Conf['Link Title'] return - gatherLinks: (match, node) -> - links = [] - i = 0 - len = match.length - data = node.data + gatherLinks: (match, node, post) -> + i = 0 + len = match.length + data = node.data while (link = match[i++]) and i > len range = document.createRange(); range.setStart node, len2 = data.indexOf link range.setEnd node, len2 + link.length - links.push range + post.nodes.links.push Linkify.makeLink range range = document.createRange() range.setStart node, len = data.indexOf link if (data.length - (len += link.length)) > 0 range.setEnd node, len - links.push range - return links + post.nodes.links.push Linkify.makeLink range + return while (next = node.nextSibling) and next.nodeName.toLowerCase() isnt 'br' node = next @@ -93,8 +88,8 @@ Linkify = node = node.previousSibling range.setEnd node, node.length - links.push range - return links + post.nodes.links.push Linkify.makeLink range + return makeLink: (range) -> link = range.toString() @@ -118,14 +113,10 @@ Linkify = return a services: (link) -> - href = if Conf['Linkify'] - link.href - else - link.toString() + href = link.href for key, type of Linkify.types continue unless match = type.regExp.exec href - link = Linkify.makeLink link unless Conf['Linkify'] return [key, match[1], match[2], link] return @@ -147,34 +138,56 @@ Linkify = $.on embed, 'click', Linkify.cb.toggle $.after link, [$.tn(' '), embed] + title: (data) -> + [key, uid, options, link] = data + service = Linkify.types[key].title + titles = Conf['CachedTitles'] + if title = titles[uid] + link.textContent = title[0] + if Conf['Embedding'] + link.nextElementSibling.dataset.title = title[0] + else + try + $.cache service.api(uid), -> + title = Linkify.cb.title.apply @, [data] + catch err + 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 + cb: toggle: -> # We setup the link to be replaced by the embedded video embed = @previousElementSibling - + # Unembed. el = unless @className.contains "embedded" Linkify.cb.embed @ else Linkify.cb.unembed @ - + $.replace embed, el $.toggleClass @, 'embedded' - + embed: (a) -> # We create an element to embed el = (type = Linkify.types[a.dataset.service]).el.call a - + # Set style values. el.style.cssText = if style = type.style style else "border: 0; width: 640px; height: 390px" - + a.textContent = '(unembed)' return el - + unembed: (a) -> # Recreate the original link. el = $.el 'a', @@ -183,10 +196,10 @@ Linkify = className: 'linkify' href: url = a.dataset.originalurl textContent: a.dataset.title or url - + a.textContent = '(embed)' $.addClass el, "#{a.dataset.service}" - + return el title: (data) -> @@ -205,30 +218,6 @@ Linkify = else "[#{key}] #{@status}'d" - title: (data) -> - [key, uid, options, link] = data - titles = {} - service = Linkify.types[key].title - title = "" - - $.get 'CachedTitles', {}, (item) -> - titles = item['CachedTitles'] - if title = titles[uid] - link.textContent = title[0] - if Conf['Embedding'] - link.nextElementSibling.dataset.title = title[0] - return - else - try - $.cache service.api(uid), -> - title = Linkify.cb.title.apply @, [data] - catch err - link.innerHTML = "[#{key}] Title Link Blocked (are you using NoScript?)" - return - if title - titles[uid] = [title, Date.now()] - $.set 'CachedTitles', titles - types: YouTube: regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/