diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d3a5420e..82f83c038 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ -Sometimes the changelog has notes (not comprehensive) acknowledging people's work. This does not mean the changes are their fault, only that their code was used. All changes to the script are chosen by and the fault of the maintainer (ccd0). +### v1.13.2 + +**v1.13.2.0** *(2016-11-27)* - [[Userscript](https://raw.githubusercontent.com/ccd0/4chan-x/1.13.2.0/builds/4chan-X-noupdate.user.js)] [[Chrome extension](https://raw.githubusercontent.com/ccd0/4chan-x/1.13.2.0/builds/4chan-X-noupdate.crx)] +- Based on v1.13.1.12. +- (ihavenoface) Add `Cover Preview` function: Show preview of supported links on hover. + - Currently supported: Youtube and Dailymotion. +- (ihavenoface) Keep floating embeds visible while moving the window. +- Various embedding-related bugfixes, including performance issue from v1.13.0.0 when switching to catalog. +- Make floating updater draggable by any edge so it doesn't get stuck at the top. #1031 + ### v1.13.1 **v1.13.1.12** *(2016-11-27)* - [[Userscript](https://raw.githubusercontent.com/ccd0/4chan-x/1.13.1.12/builds/4chan-X-noupdate.user.js)] [[Chrome extension](https://raw.githubusercontent.com/ccd0/4chan-x/1.13.1.12/builds/4chan-X-noupdate.crx)] diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index 88d108297..ab9216926 100644 Binary files a/builds/4chan-X-beta.crx and b/builds/4chan-X-beta.crx differ diff --git a/builds/4chan-X-beta.meta.js b/builds/4chan-X-beta.meta.js index 0f4f037ec..5d55b3c77 100644 --- a/builds/4chan-X-beta.meta.js +++ b/builds/4chan-X-beta.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X beta -// @version 1.13.1.12 +// @version 1.13.2.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X-beta.user.js b/builds/4chan-X-beta.user.js index 73f0caca0..885ec5c39 100644 --- a/builds/4chan-X-beta.user.js +++ b/builds/4chan-X-beta.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X beta -// @version 1.13.1.12 +// @version 1.13.2.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -147,7 +147,7 @@ docSet = function() { }; g = { - VERSION: '1.13.1.12', + VERSION: '1.13.2.0', NAMESPACE: '4chan X.', boards: {} }; @@ -224,6 +224,7 @@ Config = (function() { 'Linkification': { 'Linkify': [true, 'Convert text into links where applicable.'], 'Link Title': [true, 'Replace the link of a supported site with its actual title.', 1], + 'Cover Preview': [true, 'Show preview of supported links on hover.', 1], 'Embedding': [true, 'Embed supported services. Note: Some services don\'t work on HTTPS.', 1], 'Auto-embed': [false, 'Auto-embed Linkify Embeds.', 2], 'Floating Embeds': [false, 'Embed content in a frame that remains in place when the page is scrolled.', 2] @@ -2201,10 +2202,11 @@ span.hide-announcement {\n\ }\n\ #updater > .move {\n\ position: absolute;\n\ - left: 0;\n\ top: -5px;\n\ - width: 100%;\n\ - height: 5px;\n\ + bottom: -5px;\n\ + left: -5px;\n\ + right: -5px;\n\ + z-index: -1;\n\ }\n\ #updater > div:last-child {\n\ text-align: center;\n\ @@ -3203,9 +3205,7 @@ a:only-of-type > .remove {\n\ cursor: text !important;\n\ }\n\ /* Embedding */\n\ -.embedder:not(.embedded) > span,\n\ -:root.catalog-mode .embedder > span,\n\ -:root.catalog-mode .board .media-embed {\n\ +.embedder:not(.embedded) > span {\n\ display: none;\n\ }\n\ #embedding {\n\ @@ -6107,7 +6107,8 @@ Post = (function() { fileRoot: $('.file', post), comment: $('.postMessage', post), quotelinks: [], - archivelinks: [] + archivelinks: [], + embedlinks: [] }; if ($.engine === 'edge') { Object.defineProperty(nodes, 'backlinks', { @@ -9294,6 +9295,7 @@ Index = (function() { if (!Conf['JSON Index']) { return; } + this.enabled = true; Callbacks.Post.push({ name: 'Index Page Numbers', cb: this.node @@ -13959,18 +13961,19 @@ Volume = (function() { }).call(this); Embedding = (function() { - var Embedding; + var Embedding, + slice = [].slice; Embedding = { init: function() { - var j, len, ref, type; - if (!(Conf['Embedding'] || Conf['Link Title'])) { + var j, len, ref, ref1, type; + if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Linkify'] && (Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview']))) { return; } this.types = {}; - ref = this.ordered_types; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; + ref1 = this.ordered_types; + for (j = 0, len = ref1.length; j < len; j++) { + type = ref1[j]; this.types[type.key] = type; } if (Conf['Embedding']) { @@ -13979,14 +13982,28 @@ Embedding = (function() { }); this.media = $('#media-embed', this.dialog); $.one(d, '4chanXInitFinished', this.ready); + $.on(d, 'IndexRefreshInternal', function() { + return g.posts.forEach(function(post) { + var embed, k, l, len1, len2, ref2, ref3; + ref2 = [post].concat(slice.call(post.clones)); + for (k = 0, len1 = ref2.length; k < len1; k++) { + post = ref2[k]; + ref3 = post.nodes.embedlinks; + for (l = 0, len2 = ref3.length; l < len2; l++) { + embed = ref3[l]; + Embedding.cb.catalogRemove.call(embed); + } + } + }); + }); } if (Conf['Link Title']) { return $.on(d, '4chanXInitFinished PostsInserted', function() { - var key, ref1, ref2, service; - ref1 = Embedding.types; - for (key in ref1) { - service = ref1[key]; - if ((ref2 = service.title) != null ? ref2.batchSize : void 0) { + var key, ref2, ref3, service; + ref2 = Embedding.types; + for (key in ref2) { + service = ref2[key]; + if ((ref3 = service.title) != null ? ref3.batchSize : void 0) { Embedding.flushTitles(service.title); } } @@ -13994,22 +14011,29 @@ Embedding = (function() { } }, events: function(post) { - var el, i, items; - if (!Conf['Embedding']) { - return; + var data, el, i, items; + if (Conf['Embedding']) { + i = 0; + items = post.nodes.embedlinks = $$('.embedder', post.nodes.comment); + while (el = items[i++]) { + $.on(el, 'click', Embedding.cb.click); + if ($.hasClass(el, 'embedded')) { + Embedding.cb.toggle.call(el); + } + } } - i = 0; - items = $$('.embedder', post.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Embedding.cb.click); - if ($.hasClass(el, 'embedded')) { - Embedding.cb.toggle.call(el); + if (Conf['Cover Preview']) { + i = 0; + items = $$('.linkify', post.nodes.comment); + while (el = items[i++]) { + data = Embedding.services(el); + Embedding.preview(data); } } }, process: function(link, post) { var data; - if (!(Conf['Embedding'] || Conf['Link Title'])) { + if (!(Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview'])) { return; } if ($.x('ancestor::pre', link)) { @@ -14021,7 +14045,10 @@ Embedding = (function() { Embedding.embed(data); } if (Conf['Link Title']) { - return Embedding.title(data); + Embedding.title(data); + } + if (Conf['Cover Preview']) { + return Embedding.preview(data); } } }, @@ -14042,7 +14069,7 @@ Embedding = (function() { } }, embed: function(data) { - var autoEmbed, embed, href, key, link, name, options, post, ref, uid, value; + var embed, href, key, link, name, options, post, ref, uid, value; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; href = link.href; if (Embedding.types[key].httpOnly && location.protocol !== 'http:') { @@ -14067,15 +14094,13 @@ Embedding = (function() { } $.on(embed, 'click', Embedding.cb.click); $.after(link, [$.tn(' '), embed]); + post.nodes.embedlinks.push(embed); if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) { - autoEmbed = function() { - if (doc.contains(embed) && !$.hasClass(doc, 'catalog-mode')) { - $.off(d, 'PostsInserted', autoEmbed); - return Embedding.cb.toggle.call(embed); - } - }; - $.on(d, 'PostsInserted', autoEmbed); - return autoEmbed(); + if ($.hasClass(doc, 'catalog-mode')) { + return $.addClass(embed, 'embed-removed'); + } else { + return Embedding.cb.toggle.call(embed); + } } }, ready: function() { @@ -14103,12 +14128,12 @@ Embedding = (function() { if (Embedding.dragEmbed.mouseup) { $.off(d, 'mouseup', Embedding.dragEmbed); Embedding.dragEmbed.mouseup = false; - style.visibility = ''; + style.pointerEvents = ''; return; } $.on(d, 'mouseup', Embedding.dragEmbed); Embedding.dragEmbed.mouseup = true; - return style.visibility = 'hidden'; + return style.pointerEvents = 'none'; }, title: function(data) { var key, link, options, post, service, uid; @@ -14167,11 +14192,35 @@ Embedding = (function() { } } }, + preview: function(data) { + var key, link, service, uid; + key = data.key, uid = data.uid, link = data.link; + if (!(service = Embedding.types[key].preview)) { + return; + } + return $.on(link, 'mouseover', function(e) { + var el, height, src; + src = service.url(uid); + height = service.height; + el = $.el('img', { + src: src, + id: 'ihover' + }); + $.add(d.body, el); + return UI.hover({ + root: link, + el: el, + latestEvent: e, + endEvents: 'mouseout click', + height: height + }); + }); + }, cb: { click: function(e) { var div; e.preventDefault(); - if (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode')) { + if (!$.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode'))) { if (!(div = Embedding.media.firstChild)) { return; } @@ -14199,6 +14248,14 @@ Embedding = (function() { el.style.cssText = type.style != null ? type.style : 'border: none; width: 640px; height: 360px;'; return container; }, + catalogRemove: function() { + var isCatalog; + isCatalog = $.hasClass(doc, 'catalog-mode'); + if ((isCatalog && $.hasClass(this, 'embedded')) || (!isCatalog && $.hasClass(this, 'embed-removed'))) { + Embedding.cb.toggle.call(this); + return $.toggleClass(this, 'embed-removed'); + } + }, title: function(req, data) { var base1, j, k, key, len, len1, link, link2, options, post, post2, ref, ref1, service, status, text, uid; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; @@ -14312,6 +14369,12 @@ Embedding = (function() { text: function(_) { return _.title; } + }, + preview: { + url: function(uid) { + return "https://www.dailymotion.com/thumbnail/video/" + uid; + }, + height: 240 } }, { key: 'Gfycat', @@ -14527,10 +14590,25 @@ Embedding = (function() { }, { key: 'Twitter', regExp: /^\w+:\/\/(?:www\.)?twitter\.com\/(\w+\/status\/\d+)/, + style: 'border: none; width: 550px; height: 250px; max-height: 80vh;', el: function(a) { - return $.el('iframe', { - src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid + var el, onMessage; + el = $.el('iframe'); + $.on(el, 'load', function() { + return this.contentWindow.postMessage({ + element: 't', + query: 'height' + }, 'https://twitframe.com'); }); + onMessage = function(e) { + if (e.source === el.contentWindow && e.origin === 'https://twitframe.com') { + $.off(window, 'message', onMessage); + return el.style.height = (+e.data.height) + "px"; + } + }; + $.on(window, 'message', onMessage); + el.src = "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid; + return el; } }, { key: 'Vimeo', @@ -14612,6 +14690,12 @@ Embedding = (function() { } return 'Not Found'; } + }, + preview: { + url: function(uid) { + return "https://img.youtube.com/vi/" + uid + "/0.jpg"; + }, + height: 360 } } ] @@ -14685,6 +14769,9 @@ Linkify = (function() { break; } } + if (saved.parentElement.nodeName === "A" && !Linkify.regString.test(word)) { + break; + } endNode = saved; data = saved.data; if (end = space.exec(data)) { @@ -17859,7 +17946,7 @@ ThreadUpdater = (function() { Header.addShortcut('updater', sc, 100); } else { this.dialog = sc = UI.dialog('updater', { - innerHTML: "
" + innerHTML: "" }); $.addClass(doc, 'float'); $.ready(function() { diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index b06ea58c6..835ae3c31 100644 Binary files a/builds/4chan-X-noupdate.crx and b/builds/4chan-X-noupdate.crx differ diff --git a/builds/4chan-X-noupdate.user.js b/builds/4chan-X-noupdate.user.js index 94392c5be..873788b3e 100644 --- a/builds/4chan-X-noupdate.user.js +++ b/builds/4chan-X-noupdate.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.13.1.12 +// @version 1.13.2.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -147,7 +147,7 @@ docSet = function() { }; g = { - VERSION: '1.13.1.12', + VERSION: '1.13.2.0', NAMESPACE: '4chan X.', boards: {} }; @@ -224,6 +224,7 @@ Config = (function() { 'Linkification': { 'Linkify': [true, 'Convert text into links where applicable.'], 'Link Title': [true, 'Replace the link of a supported site with its actual title.', 1], + 'Cover Preview': [true, 'Show preview of supported links on hover.', 1], 'Embedding': [true, 'Embed supported services. Note: Some services don\'t work on HTTPS.', 1], 'Auto-embed': [false, 'Auto-embed Linkify Embeds.', 2], 'Floating Embeds': [false, 'Embed content in a frame that remains in place when the page is scrolled.', 2] @@ -2201,10 +2202,11 @@ span.hide-announcement {\n\ }\n\ #updater > .move {\n\ position: absolute;\n\ - left: 0;\n\ top: -5px;\n\ - width: 100%;\n\ - height: 5px;\n\ + bottom: -5px;\n\ + left: -5px;\n\ + right: -5px;\n\ + z-index: -1;\n\ }\n\ #updater > div:last-child {\n\ text-align: center;\n\ @@ -3203,9 +3205,7 @@ a:only-of-type > .remove {\n\ cursor: text !important;\n\ }\n\ /* Embedding */\n\ -.embedder:not(.embedded) > span,\n\ -:root.catalog-mode .embedder > span,\n\ -:root.catalog-mode .board .media-embed {\n\ +.embedder:not(.embedded) > span {\n\ display: none;\n\ }\n\ #embedding {\n\ @@ -6107,7 +6107,8 @@ Post = (function() { fileRoot: $('.file', post), comment: $('.postMessage', post), quotelinks: [], - archivelinks: [] + archivelinks: [], + embedlinks: [] }; if ($.engine === 'edge') { Object.defineProperty(nodes, 'backlinks', { @@ -9294,6 +9295,7 @@ Index = (function() { if (!Conf['JSON Index']) { return; } + this.enabled = true; Callbacks.Post.push({ name: 'Index Page Numbers', cb: this.node @@ -13959,18 +13961,19 @@ Volume = (function() { }).call(this); Embedding = (function() { - var Embedding; + var Embedding, + slice = [].slice; Embedding = { init: function() { - var j, len, ref, type; - if (!(Conf['Embedding'] || Conf['Link Title'])) { + var j, len, ref, ref1, type; + if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Linkify'] && (Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview']))) { return; } this.types = {}; - ref = this.ordered_types; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; + ref1 = this.ordered_types; + for (j = 0, len = ref1.length; j < len; j++) { + type = ref1[j]; this.types[type.key] = type; } if (Conf['Embedding']) { @@ -13979,14 +13982,28 @@ Embedding = (function() { }); this.media = $('#media-embed', this.dialog); $.one(d, '4chanXInitFinished', this.ready); + $.on(d, 'IndexRefreshInternal', function() { + return g.posts.forEach(function(post) { + var embed, k, l, len1, len2, ref2, ref3; + ref2 = [post].concat(slice.call(post.clones)); + for (k = 0, len1 = ref2.length; k < len1; k++) { + post = ref2[k]; + ref3 = post.nodes.embedlinks; + for (l = 0, len2 = ref3.length; l < len2; l++) { + embed = ref3[l]; + Embedding.cb.catalogRemove.call(embed); + } + } + }); + }); } if (Conf['Link Title']) { return $.on(d, '4chanXInitFinished PostsInserted', function() { - var key, ref1, ref2, service; - ref1 = Embedding.types; - for (key in ref1) { - service = ref1[key]; - if ((ref2 = service.title) != null ? ref2.batchSize : void 0) { + var key, ref2, ref3, service; + ref2 = Embedding.types; + for (key in ref2) { + service = ref2[key]; + if ((ref3 = service.title) != null ? ref3.batchSize : void 0) { Embedding.flushTitles(service.title); } } @@ -13994,22 +14011,29 @@ Embedding = (function() { } }, events: function(post) { - var el, i, items; - if (!Conf['Embedding']) { - return; + var data, el, i, items; + if (Conf['Embedding']) { + i = 0; + items = post.nodes.embedlinks = $$('.embedder', post.nodes.comment); + while (el = items[i++]) { + $.on(el, 'click', Embedding.cb.click); + if ($.hasClass(el, 'embedded')) { + Embedding.cb.toggle.call(el); + } + } } - i = 0; - items = $$('.embedder', post.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Embedding.cb.click); - if ($.hasClass(el, 'embedded')) { - Embedding.cb.toggle.call(el); + if (Conf['Cover Preview']) { + i = 0; + items = $$('.linkify', post.nodes.comment); + while (el = items[i++]) { + data = Embedding.services(el); + Embedding.preview(data); } } }, process: function(link, post) { var data; - if (!(Conf['Embedding'] || Conf['Link Title'])) { + if (!(Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview'])) { return; } if ($.x('ancestor::pre', link)) { @@ -14021,7 +14045,10 @@ Embedding = (function() { Embedding.embed(data); } if (Conf['Link Title']) { - return Embedding.title(data); + Embedding.title(data); + } + if (Conf['Cover Preview']) { + return Embedding.preview(data); } } }, @@ -14042,7 +14069,7 @@ Embedding = (function() { } }, embed: function(data) { - var autoEmbed, embed, href, key, link, name, options, post, ref, uid, value; + var embed, href, key, link, name, options, post, ref, uid, value; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; href = link.href; if (Embedding.types[key].httpOnly && location.protocol !== 'http:') { @@ -14067,15 +14094,13 @@ Embedding = (function() { } $.on(embed, 'click', Embedding.cb.click); $.after(link, [$.tn(' '), embed]); + post.nodes.embedlinks.push(embed); if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) { - autoEmbed = function() { - if (doc.contains(embed) && !$.hasClass(doc, 'catalog-mode')) { - $.off(d, 'PostsInserted', autoEmbed); - return Embedding.cb.toggle.call(embed); - } - }; - $.on(d, 'PostsInserted', autoEmbed); - return autoEmbed(); + if ($.hasClass(doc, 'catalog-mode')) { + return $.addClass(embed, 'embed-removed'); + } else { + return Embedding.cb.toggle.call(embed); + } } }, ready: function() { @@ -14103,12 +14128,12 @@ Embedding = (function() { if (Embedding.dragEmbed.mouseup) { $.off(d, 'mouseup', Embedding.dragEmbed); Embedding.dragEmbed.mouseup = false; - style.visibility = ''; + style.pointerEvents = ''; return; } $.on(d, 'mouseup', Embedding.dragEmbed); Embedding.dragEmbed.mouseup = true; - return style.visibility = 'hidden'; + return style.pointerEvents = 'none'; }, title: function(data) { var key, link, options, post, service, uid; @@ -14167,11 +14192,35 @@ Embedding = (function() { } } }, + preview: function(data) { + var key, link, service, uid; + key = data.key, uid = data.uid, link = data.link; + if (!(service = Embedding.types[key].preview)) { + return; + } + return $.on(link, 'mouseover', function(e) { + var el, height, src; + src = service.url(uid); + height = service.height; + el = $.el('img', { + src: src, + id: 'ihover' + }); + $.add(d.body, el); + return UI.hover({ + root: link, + el: el, + latestEvent: e, + endEvents: 'mouseout click', + height: height + }); + }); + }, cb: { click: function(e) { var div; e.preventDefault(); - if (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode')) { + if (!$.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode'))) { if (!(div = Embedding.media.firstChild)) { return; } @@ -14199,6 +14248,14 @@ Embedding = (function() { el.style.cssText = type.style != null ? type.style : 'border: none; width: 640px; height: 360px;'; return container; }, + catalogRemove: function() { + var isCatalog; + isCatalog = $.hasClass(doc, 'catalog-mode'); + if ((isCatalog && $.hasClass(this, 'embedded')) || (!isCatalog && $.hasClass(this, 'embed-removed'))) { + Embedding.cb.toggle.call(this); + return $.toggleClass(this, 'embed-removed'); + } + }, title: function(req, data) { var base1, j, k, key, len, len1, link, link2, options, post, post2, ref, ref1, service, status, text, uid; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; @@ -14312,6 +14369,12 @@ Embedding = (function() { text: function(_) { return _.title; } + }, + preview: { + url: function(uid) { + return "https://www.dailymotion.com/thumbnail/video/" + uid; + }, + height: 240 } }, { key: 'Gfycat', @@ -14527,10 +14590,25 @@ Embedding = (function() { }, { key: 'Twitter', regExp: /^\w+:\/\/(?:www\.)?twitter\.com\/(\w+\/status\/\d+)/, + style: 'border: none; width: 550px; height: 250px; max-height: 80vh;', el: function(a) { - return $.el('iframe', { - src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid + var el, onMessage; + el = $.el('iframe'); + $.on(el, 'load', function() { + return this.contentWindow.postMessage({ + element: 't', + query: 'height' + }, 'https://twitframe.com'); }); + onMessage = function(e) { + if (e.source === el.contentWindow && e.origin === 'https://twitframe.com') { + $.off(window, 'message', onMessage); + return el.style.height = (+e.data.height) + "px"; + } + }; + $.on(window, 'message', onMessage); + el.src = "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid; + return el; } }, { key: 'Vimeo', @@ -14612,6 +14690,12 @@ Embedding = (function() { } return 'Not Found'; } + }, + preview: { + url: function(uid) { + return "https://img.youtube.com/vi/" + uid + "/0.jpg"; + }, + height: 360 } } ] @@ -14685,6 +14769,9 @@ Linkify = (function() { break; } } + if (saved.parentElement.nodeName === "A" && !Linkify.regString.test(word)) { + break; + } endNode = saved; data = saved.data; if (end = space.exec(data)) { @@ -17859,7 +17946,7 @@ ThreadUpdater = (function() { Header.addShortcut('updater', sc, 100); } else { this.dialog = sc = UI.dialog('updater', { - innerHTML: "" + innerHTML: "" }); $.addClass(doc, 'float'); $.ready(function() { diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index 6972f59d1..cfd748ff4 100644 Binary files a/builds/4chan-X.crx and b/builds/4chan-X.crx differ diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index 0f3861dcd..dfd646c42 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.13.1.12 +// @version 1.13.2.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 8508c2cf3..b84599e1e 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.13.1.12 +// @version 1.13.2.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -147,7 +147,7 @@ docSet = function() { }; g = { - VERSION: '1.13.1.12', + VERSION: '1.13.2.0', NAMESPACE: '4chan X.', boards: {} }; @@ -224,6 +224,7 @@ Config = (function() { 'Linkification': { 'Linkify': [true, 'Convert text into links where applicable.'], 'Link Title': [true, 'Replace the link of a supported site with its actual title.', 1], + 'Cover Preview': [true, 'Show preview of supported links on hover.', 1], 'Embedding': [true, 'Embed supported services. Note: Some services don\'t work on HTTPS.', 1], 'Auto-embed': [false, 'Auto-embed Linkify Embeds.', 2], 'Floating Embeds': [false, 'Embed content in a frame that remains in place when the page is scrolled.', 2] @@ -2201,10 +2202,11 @@ span.hide-announcement {\n\ }\n\ #updater > .move {\n\ position: absolute;\n\ - left: 0;\n\ top: -5px;\n\ - width: 100%;\n\ - height: 5px;\n\ + bottom: -5px;\n\ + left: -5px;\n\ + right: -5px;\n\ + z-index: -1;\n\ }\n\ #updater > div:last-child {\n\ text-align: center;\n\ @@ -3203,9 +3205,7 @@ a:only-of-type > .remove {\n\ cursor: text !important;\n\ }\n\ /* Embedding */\n\ -.embedder:not(.embedded) > span,\n\ -:root.catalog-mode .embedder > span,\n\ -:root.catalog-mode .board .media-embed {\n\ +.embedder:not(.embedded) > span {\n\ display: none;\n\ }\n\ #embedding {\n\ @@ -6107,7 +6107,8 @@ Post = (function() { fileRoot: $('.file', post), comment: $('.postMessage', post), quotelinks: [], - archivelinks: [] + archivelinks: [], + embedlinks: [] }; if ($.engine === 'edge') { Object.defineProperty(nodes, 'backlinks', { @@ -9294,6 +9295,7 @@ Index = (function() { if (!Conf['JSON Index']) { return; } + this.enabled = true; Callbacks.Post.push({ name: 'Index Page Numbers', cb: this.node @@ -13959,18 +13961,19 @@ Volume = (function() { }).call(this); Embedding = (function() { - var Embedding; + var Embedding, + slice = [].slice; Embedding = { init: function() { - var j, len, ref, type; - if (!(Conf['Embedding'] || Conf['Link Title'])) { + var j, len, ref, ref1, type; + if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Linkify'] && (Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview']))) { return; } this.types = {}; - ref = this.ordered_types; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; + ref1 = this.ordered_types; + for (j = 0, len = ref1.length; j < len; j++) { + type = ref1[j]; this.types[type.key] = type; } if (Conf['Embedding']) { @@ -13979,14 +13982,28 @@ Embedding = (function() { }); this.media = $('#media-embed', this.dialog); $.one(d, '4chanXInitFinished', this.ready); + $.on(d, 'IndexRefreshInternal', function() { + return g.posts.forEach(function(post) { + var embed, k, l, len1, len2, ref2, ref3; + ref2 = [post].concat(slice.call(post.clones)); + for (k = 0, len1 = ref2.length; k < len1; k++) { + post = ref2[k]; + ref3 = post.nodes.embedlinks; + for (l = 0, len2 = ref3.length; l < len2; l++) { + embed = ref3[l]; + Embedding.cb.catalogRemove.call(embed); + } + } + }); + }); } if (Conf['Link Title']) { return $.on(d, '4chanXInitFinished PostsInserted', function() { - var key, ref1, ref2, service; - ref1 = Embedding.types; - for (key in ref1) { - service = ref1[key]; - if ((ref2 = service.title) != null ? ref2.batchSize : void 0) { + var key, ref2, ref3, service; + ref2 = Embedding.types; + for (key in ref2) { + service = ref2[key]; + if ((ref3 = service.title) != null ? ref3.batchSize : void 0) { Embedding.flushTitles(service.title); } } @@ -13994,22 +14011,29 @@ Embedding = (function() { } }, events: function(post) { - var el, i, items; - if (!Conf['Embedding']) { - return; + var data, el, i, items; + if (Conf['Embedding']) { + i = 0; + items = post.nodes.embedlinks = $$('.embedder', post.nodes.comment); + while (el = items[i++]) { + $.on(el, 'click', Embedding.cb.click); + if ($.hasClass(el, 'embedded')) { + Embedding.cb.toggle.call(el); + } + } } - i = 0; - items = $$('.embedder', post.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Embedding.cb.click); - if ($.hasClass(el, 'embedded')) { - Embedding.cb.toggle.call(el); + if (Conf['Cover Preview']) { + i = 0; + items = $$('.linkify', post.nodes.comment); + while (el = items[i++]) { + data = Embedding.services(el); + Embedding.preview(data); } } }, process: function(link, post) { var data; - if (!(Conf['Embedding'] || Conf['Link Title'])) { + if (!(Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview'])) { return; } if ($.x('ancestor::pre', link)) { @@ -14021,7 +14045,10 @@ Embedding = (function() { Embedding.embed(data); } if (Conf['Link Title']) { - return Embedding.title(data); + Embedding.title(data); + } + if (Conf['Cover Preview']) { + return Embedding.preview(data); } } }, @@ -14042,7 +14069,7 @@ Embedding = (function() { } }, embed: function(data) { - var autoEmbed, embed, href, key, link, name, options, post, ref, uid, value; + var embed, href, key, link, name, options, post, ref, uid, value; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; href = link.href; if (Embedding.types[key].httpOnly && location.protocol !== 'http:') { @@ -14067,15 +14094,13 @@ Embedding = (function() { } $.on(embed, 'click', Embedding.cb.click); $.after(link, [$.tn(' '), embed]); + post.nodes.embedlinks.push(embed); if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) { - autoEmbed = function() { - if (doc.contains(embed) && !$.hasClass(doc, 'catalog-mode')) { - $.off(d, 'PostsInserted', autoEmbed); - return Embedding.cb.toggle.call(embed); - } - }; - $.on(d, 'PostsInserted', autoEmbed); - return autoEmbed(); + if ($.hasClass(doc, 'catalog-mode')) { + return $.addClass(embed, 'embed-removed'); + } else { + return Embedding.cb.toggle.call(embed); + } } }, ready: function() { @@ -14103,12 +14128,12 @@ Embedding = (function() { if (Embedding.dragEmbed.mouseup) { $.off(d, 'mouseup', Embedding.dragEmbed); Embedding.dragEmbed.mouseup = false; - style.visibility = ''; + style.pointerEvents = ''; return; } $.on(d, 'mouseup', Embedding.dragEmbed); Embedding.dragEmbed.mouseup = true; - return style.visibility = 'hidden'; + return style.pointerEvents = 'none'; }, title: function(data) { var key, link, options, post, service, uid; @@ -14167,11 +14192,35 @@ Embedding = (function() { } } }, + preview: function(data) { + var key, link, service, uid; + key = data.key, uid = data.uid, link = data.link; + if (!(service = Embedding.types[key].preview)) { + return; + } + return $.on(link, 'mouseover', function(e) { + var el, height, src; + src = service.url(uid); + height = service.height; + el = $.el('img', { + src: src, + id: 'ihover' + }); + $.add(d.body, el); + return UI.hover({ + root: link, + el: el, + latestEvent: e, + endEvents: 'mouseout click', + height: height + }); + }); + }, cb: { click: function(e) { var div; e.preventDefault(); - if (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode')) { + if (!$.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode'))) { if (!(div = Embedding.media.firstChild)) { return; } @@ -14199,6 +14248,14 @@ Embedding = (function() { el.style.cssText = type.style != null ? type.style : 'border: none; width: 640px; height: 360px;'; return container; }, + catalogRemove: function() { + var isCatalog; + isCatalog = $.hasClass(doc, 'catalog-mode'); + if ((isCatalog && $.hasClass(this, 'embedded')) || (!isCatalog && $.hasClass(this, 'embed-removed'))) { + Embedding.cb.toggle.call(this); + return $.toggleClass(this, 'embed-removed'); + } + }, title: function(req, data) { var base1, j, k, key, len, len1, link, link2, options, post, post2, ref, ref1, service, status, text, uid; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; @@ -14312,6 +14369,12 @@ Embedding = (function() { text: function(_) { return _.title; } + }, + preview: { + url: function(uid) { + return "https://www.dailymotion.com/thumbnail/video/" + uid; + }, + height: 240 } }, { key: 'Gfycat', @@ -14527,10 +14590,25 @@ Embedding = (function() { }, { key: 'Twitter', regExp: /^\w+:\/\/(?:www\.)?twitter\.com\/(\w+\/status\/\d+)/, + style: 'border: none; width: 550px; height: 250px; max-height: 80vh;', el: function(a) { - return $.el('iframe', { - src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid + var el, onMessage; + el = $.el('iframe'); + $.on(el, 'load', function() { + return this.contentWindow.postMessage({ + element: 't', + query: 'height' + }, 'https://twitframe.com'); }); + onMessage = function(e) { + if (e.source === el.contentWindow && e.origin === 'https://twitframe.com') { + $.off(window, 'message', onMessage); + return el.style.height = (+e.data.height) + "px"; + } + }; + $.on(window, 'message', onMessage); + el.src = "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid; + return el; } }, { key: 'Vimeo', @@ -14612,6 +14690,12 @@ Embedding = (function() { } return 'Not Found'; } + }, + preview: { + url: function(uid) { + return "https://img.youtube.com/vi/" + uid + "/0.jpg"; + }, + height: 360 } } ] @@ -14685,6 +14769,9 @@ Linkify = (function() { break; } } + if (saved.parentElement.nodeName === "A" && !Linkify.regString.test(word)) { + break; + } endNode = saved; data = saved.data; if (end = space.exec(data)) { @@ -17859,7 +17946,7 @@ ThreadUpdater = (function() { Header.addShortcut('updater', sc, 100); } else { this.dialog = sc = UI.dialog('updater', { - innerHTML: "" + innerHTML: "" }); $.addClass(doc, 'float'); $.ready(function() { diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index 612c3247b..326beaf77 100644 Binary files a/builds/4chan-X.zip and b/builds/4chan-X.zip differ diff --git a/builds/updates-beta.xml b/builds/updates-beta.xml index 6fb69cd1c..c5e8f14ed 100644 --- a/builds/updates-beta.xml +++ b/builds/updates-beta.xml @@ -1,7 +1,7 @@