diff --git a/CHANGELOG.md b/CHANGELOG.md index ccb189b43..068002fc1 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ +### v1.8.1 +*2014-06-19* + +**MayhemYDG** +- More API changes: + - `ThreadUpdate`: + - `thread` field replaced with `threadID` containing `fullID` of thread (e.g. `"g.39894014"`) + - `newPosts` field changed from list of `Post` objects to list of post `fullID`s. + - `deletedPosts` and `deletedFiles` removed + - `QRPostSuccessful`: + - `board` field replaced with `boardID` containing name of board (e.g. `"g"`) + - `QRPostSuccessful_`: + - `boardID` added; is now identical to `QRPostSuccessful` + +## v1.8.0 +*2014-06-18* + +**ccd0** +- Add compatibility with Greasemonkey 2.0. +- Much of Mayhem's [API](https://github.com/MayhemYDG/4chan-x/wiki) has been removed due to issues with Greasemonkey 2.0. + - The `AddCallback`, `QRPostSelection`, `QRGetSelectedPost`, and `QRAddPreSubmitHook` events are removed. + - Callback functions can no longer be passed via the `AddMenuEntry` and `CreateNotification` events. + - The information sent with `QRPostSuccessful` and `ThreadUpdate` events has been reduced: + - Board objects have been reduced to the form `{ID: "g"}`. + - Thread and post objects have been reduced to the form `{ID: 39894014, fullID: "g.39894014"}`. + - More fields may be added if requested. + - The `AddMenuEntry` and `AddSettingsSection` events continue to not work in Chromium should be considered deprecated. They are provided for backwards compatibility with existing scripts. Suggestions for replacements are welcome. + - The `4chanXInitFinished`, `CloseMenu`, `QRDialogCreation`, and `OpenSettings` events are unchanged, as is the undocumented `QRPostSuccessful_` (`QRPostSuccessful` without the board object, used by Name Sync on Chromium). + ### v1.7.63 *2014-06-16* diff --git a/Gruntfile.coffee b/Gruntfile.coffee index ed5a9ef8d..c3ad155bf 100755 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -124,6 +124,9 @@ module.exports = (grunt) -> command: """ git commit -am "Release <%= pkg.meta.name %> v<%= pkg.version %>." git tag -a <%= pkg.version %> -m "<%= pkg.meta.name %> v<%= pkg.version %>." + """ + stable: + command: """ git tag -af stable -m "<%= pkg.meta.name %> v<%= pkg.version %>." git checkout gh-pages git merge --ff-only stable @@ -204,6 +207,16 @@ module.exports = (grunt) -> 'clean:tmpuserscript' ] + grunt.registerTask 'testing', [ + 'build' + 'shell:pack' + 'compress:crx' + 'concat:meta' + 'copy:builds' + 'shell:commit' + 'shell:push' + ] + grunt.registerTask 'release', [ 'build' 'shell:pack' @@ -211,6 +224,7 @@ module.exports = (grunt) -> 'concat:meta' 'copy:builds' 'shell:commit' + 'shell:stable' 'shell:push' ] diff --git a/LICENSE b/LICENSE index 46c33356a..3b722e4d4 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.7.63 - 2014-06-16 +* 4chan X - Version 1.8.1 - 2014-06-19 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE diff --git a/README.md b/README.md index def0e3af8..02995e31d 100755 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@ Fork of [Spittie's 4chan X](https://github.com/Spittie/4chan-x) (itself a fork o Note: If you're looking for a maintained fork of OneeChan, try https://github.com/Nebukazar/OneeChan -#### [Why 4chan X needs to access data on every site?](https://github.com/ccd0/4chan-x/wiki/Why-4chan-X-needs-to-access-data-from-every-website%3F) - ## [Install](https://ccd0.github.io/4chan-x/builds/4chan-X.user.js) (Firefox) Install [Greasemonkey](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/), then click the link above to install. @@ -25,29 +23,7 @@ This fork of 4chan X is not guaranteed to work correctly in other browsers, but 5. Download 4chanX with `wget https://ccd0.github.io/4chan-x/builds/4chan-X.user.js` 6. Start dwb -## If you have any problems, try resetting your 4chan X settings +## [Frequently Asked Questions](https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions) -## Forking - -### Get started - -- Get started by reading through the [Help link](https://help.github.com/) on how to fork a Github project. -- Click the "Fork" button on this page. -- Install [node.js](http://nodejs.org/). -- Install [Grunt's CLI](http://gruntjs.com/) with `npm install -g grunt-cli`. -- Clone your fork of 4chan X. -- `cd` into it. -- Install/Update 4chan X dependencies with `npm install`. - -### Build - -- Build with `grunt`. -- Continuously build with `grunt watch`. - -### Release - -- Update the version with `grunt patch`, `grunt minor` or `grunt major`. -- Release with `grunt release`. - -Note: this is only used to release new 4chan X versions, ignore as you see fit. +## [Reporting Bugs and Contributing](https://github.com/ccd0/4chan-x/blob/master/CONTRIBUTING.md) diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index ac51c6127..58ef9261d 100755 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.7.63 +// @version 1.8.1 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 39936cb89..a1c01916b 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.7.63 +// @version 1.8.1 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -24,7 +24,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.7.63 - 2014-06-16 +* 4chan X - Version 1.8.1 - 2014-06-19 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -374,7 +374,7 @@ doc = d.documentElement; g = { - VERSION: '1.7.63', + VERSION: '1.8.1', NAMESPACE: '4chan X.', boards: {} }; @@ -386,16 +386,6 @@ return root.querySelector(selector); }; - $.extend = function(obj, prop) { - var key, val; - for (key in prop) { - val = prop[key]; - if (prop.hasOwnProperty(key)) { - obj[key] = val; - } - } - }; - $.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000))); $.id = function(id) { @@ -659,6 +649,9 @@ if (root == null) { root = d; } + if ((detail != null) && typeof cloneInto === 'function') { + detail = cloneInto(detail, document.defaultView); + } return root.dispatchEvent(new CustomEvent(event, { bubbles: true, detail: detail @@ -840,36 +833,19 @@ Callbacks.prototype.push = function(_arg) { var cb, name; name = _arg.name, cb = _arg.cb; - if (this[name]) { - this.connect(name); - } if (!this[name]) { this.keys.push(name); } return this[name] = cb; }; - Callbacks.prototype.connect = function(name) { - if (this[name].disconnected) { - return delete this[name].disconnected; - } - }; - - Callbacks.prototype.disconnect = function(name) { - if (this[name]) { - return this[name].disconnected = true; - } - }; - Callbacks.prototype.execute = function(node) { var err, errors, name, _i, _len, _ref; _ref = this.keys; for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; try { - if (!this[name].disconnected) { - this[name].call(node); - } + this[name].call(node); } catch (_error) { err = _error; if (!errors) { @@ -1515,12 +1491,6 @@ return typeof this.sync === "function" ? this.sync() : void 0; }; - DataBoard.prototype.disconnect = function() { - $.desync(this.key); - delete this.sync; - return delete this.data; - }; - return DataBoard; })(); @@ -1843,8 +1813,7 @@ $.sync('Header auto-hide', this.setBarVisibility); $.sync('Centered links', this.setLinkJustify); this.addShortcut(menuButton); - $.event('AddMenuEntry', { - type: 'header', + this.menu.addEntry({ el: $.el('span', { textContent: 'Header' }), @@ -2251,12 +2220,9 @@ return Header.menu.toggle(e, this, g); }, createNotification: function(e) { - var cb, content, lifetime, notice, type, _ref; - _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime, cb = _ref.cb; - notice = new Notice(type, content, lifetime); - if (cb) { - return cb(notice); - } + var content, lifetime, notice, type, _ref; + _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime; + return notice = new Notice(type, content, lifetime); }, areNotificationsEnabled: false, enableDesktopNotifications: function() { @@ -2396,8 +2362,7 @@ $.on(input, 'change', this.cb.sort); } } - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: $.el('span', { textContent: 'Index Navigation' }), @@ -2922,14 +2887,12 @@ return nodes; }, buildStructure: function(nodes) { - var i, node, result; - result = $.frag(); - i = 0; - while (node = nodes[i++]) { - $.add(result, [node, $.el('hr')]); + var node, _i, _len; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + node = nodes[_i]; + $.add(Index.root, [node, $.el('hr')]); } - $.event('IndexBuild', result.children); - return $.add(Index.root, result); + return ThreadHiding.onIndexBuild(nodes); }, isSearching: false, clearSearch: function() { @@ -3107,7 +3070,7 @@ This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS). @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var E, boardID, capcode, container, date, dateUTC, email, file, fileSize, fileThumb, flagCode, flagName, h_capcodeClass, h_capcodeIcon, h_capcodeStart, h_closed, h_comment, h_emailEnd, h_emailStart, h_file, h_fileDims, h_fileInfo, h_fileTitle1, h_fileTitle2, h_flag, h_gifIcon, h_imgSrc, h_pageIcon, h_postClass, h_quoteLink, h_replyLink, h_sideArrows, h_staticPath, h_sticky, h_tripcode, h_userID, href, isClosed, isOP, isSticky, name, pageNum, postID, quote, shortFilename, spoilerRange, subject, threadID, tripcode, uniqueID, _i, _len, _ref; + var E, boardID, capcode, container, date, dateUTC, email, email_processed, file, fileSize, fileThumb, flagCode, flagName, h_capcodeClass, h_capcodeIcon, h_capcodeStart, h_closed, h_comment, h_emailEnd, h_emailStart, h_file, h_fileDims, h_fileInfo, h_fileTitle1, h_fileTitle2, h_flag, h_gifIcon, h_imgSrc, h_pageIcon, h_postClass, h_quoteLink, h_replyLink, h_sideArrows, h_staticPath, h_sticky, h_tripcode, h_userID, href, isClosed, isOP, isSticky, name, pageNum, postID, quote, shortFilename, spoilerRange, subject, threadID, tripcode, uniqueID, _i, _len, _ref; E = Build.h_escape; postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, h_comment = o.h_comment, file = o.file; name || (name = ''); @@ -3125,8 +3088,9 @@ } else { h_tripcode = ''; } + email_processed = encodeURIComponent(email).replace(/%40/g, '@'); if (email) { - h_emailStart = ""; + h_emailStart = ""; h_emailEnd = ''; } else { h_emailStart = ''; @@ -3573,7 +3537,7 @@ }; UI = (function() { - var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove; + var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, menus, touchend, touchmove; dialog = function(id, position, properties) { var child, el, move, _i, _len, _ref; el = $.el('div', { @@ -3599,6 +3563,7 @@ } return el; }; + menus = {}; Menu = (function() { var currentMenu, lastToggledButton; @@ -3608,14 +3573,23 @@ function Menu(type) { this.type = type; - this.rmEntry = __bind(this.rmEntry, this); this.addEntry = __bind(this.addEntry, this); this.onFocus = __bind(this.onFocus, this); this.keybinds = __bind(this.keybinds, this); this.close = __bind(this.close, this); - $.on(d, 'AddMenuEntry', this.addEntry); - $.on(d, 'rmMenuEntry', this.rmEntry); + $.on(d, 'AddMenuEntry', (function(_this) { + return function(_arg) { + var detail; + detail = _arg.detail; + if (detail.type !== _this.type) { + return; + } + delete detail.open; + return _this.addEntry(detail); + }; + })(this)); this.entries = []; + menus[this.type] = this; } Menu.prototype.makeMenu = function() { @@ -3806,26 +3780,11 @@ return style.right = right; }; - Menu.prototype.addEntry = function(e) { - var entry; - entry = e.detail; - if (entry.type !== this.type) { - return; - } + Menu.prototype.addEntry = function(entry) { this.parseEntry(entry); return this.entries.push(entry); }; - Menu.prototype.rmEntry = function(e) { - var entry, index; - entry = e.detail; - if (entry.type !== this.type) { - return; - } - index = this.entries.indexOf(entry); - return this.entries.splice(index, 1); - }; - Menu.prototype.parseEntry = function(entry) { var el, subEntries, subEntry, _i, _len; el = entry.el, subEntries = entry.subEntries; @@ -4295,7 +4254,6 @@ textContent: 'Filter' }); entry = { - type: 'post', el: div, order: 50, open: function(post) { @@ -4309,7 +4267,7 @@ type = _ref[_i]; entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])); } - return $.event('AddMenuEntry', entry); + return Menu.menu.addEntry(entry); }, createSubEntry: function(text, type) { var el; @@ -4415,8 +4373,7 @@ thisPost = UI.checkbox('thisPost', ' This post', true); replies = UI.checkbox('replies', ' Hide replies', Conf['Recursive Hiding']); makeStub = UI.checkbox('makeStub', ' Make stub', Conf['Stubs']); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(post) { @@ -4454,8 +4411,7 @@ href: 'javascript:;' }); $.on(hideStubLink, 'click', PostHiding.menu.hideStub); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(post) { @@ -4485,8 +4441,7 @@ } ] }); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: hideStubLink, order: 15, open: function(post) { @@ -4723,7 +4678,6 @@ } this.db = new DataBoard('hiddenThreads'); this.syncCatalog(); - $.on(d, 'IndexBuild', this.onIndexBuild); return Thread.callbacks.push({ name: 'Thread Hiding', cb: this.node @@ -4742,16 +4696,12 @@ } return $.prepend(this.OP.nodes.root, ThreadHiding.makeButton(this, 'hide')); }, - onIndexBuild: function(_arg) { - var i, nodes, root, thread, _i, _len; - nodes = _arg.detail; - for (i = _i = 0, _len = nodes.length; _i < _len; i = _i += 2) { - root = nodes[i]; + onIndexBuild: function(nodes) { + var root, thread, _i, _len; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + root = nodes[_i]; thread = Get.threadFromRoot(root); - if (!thread.isHidden) { - continue; - } - if (thread.stub && root.contains(thread.stub)) { + if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { ThreadHiding.makeStub(thread, root); } } @@ -4822,8 +4772,7 @@ }); $.on(apply, 'click', ThreadHiding.menu.hide); makeStub = UI.checkbox('Stubs', ' Make stub'); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(_arg) { @@ -4849,8 +4798,7 @@ href: 'javascript:;' }); $.on(div, 'click', ThreadHiding.menu.show); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(_arg) { @@ -4868,8 +4816,7 @@ href: 'javascript:;' }); $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: hideStubLink, order: 15, open: function(_arg) { @@ -5396,8 +5343,7 @@ }); input = $('input', this.controls); $.on(input, 'change', this.toggle); - $.event('AddMenuEntry', this.entry = { - type: 'header', + Header.menu.addEntry(this.entry = { el: this.controls, order: 98 }); @@ -5409,19 +5355,6 @@ cb: this.node }); }, - disconnect: function() { - var input; - if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { - return; - } - input = $('input', this.controls); - $.off(input, 'change', this.toggle); - $.event('rmMenuEntry', this.entry); - delete this.enabled; - delete this.controls; - delete this.entry; - return Post.callbacks.disconnect('Quote Threading'); - }, ready: function() { $.off(d, '4chanXInitFinished', QuoteThreading.ready); return QuoteThreading.force(); @@ -5824,16 +5757,6 @@ $.prepend($('.navLinksBot'), linkBot); } $.before($.id('togglePostFormLink'), link); - $.on(d, 'QRGetSelectedPost', function(_arg) { - var cb; - cb = _arg.detail; - return cb(QR.selected); - }); - $.on(d, 'QRAddPreSubmitHook', function(_arg) { - var cb; - cb = _arg.detail; - return QR.preSubmitHooks.push(cb); - }); $.on(d, 'paste', QR.paste); $.on(d, 'dragover', QR.dragOver); $.on(d, 'drop', QR.dropFile); @@ -6455,9 +6378,8 @@ return $.add(nodes.form, flag); } }, - preSubmitHooks: [], submit: function(e) { - var challenge, err, extra, filetag, formData, hook, options, post, response, textOnly, thread, threadID, _i, _len, _ref, _ref1; + var challenge, err, extra, filetag, formData, options, post, response, textOnly, thread, threadID, _ref; if (e != null) { e.preventDefault(); } @@ -6490,17 +6412,9 @@ err = 'No file selected.'; } else if (post.file && thread.fileLimit) { err = 'Max limit of image replies has been reached.'; - } else { - _ref = QR.preSubmitHooks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - hook = _ref[_i]; - if (err = hook(post, thread)) { - break; - } - } } if (QR.captcha.isEnabled && !err) { - _ref1 = QR.captcha.getOne(), challenge = _ref1.challenge, response = _ref1.response; + _ref = QR.captcha.getOne(), challenge = _ref.challenge, response = _ref.response; if (!response) { err = 'No valid captcha.'; } @@ -6633,11 +6547,12 @@ }); ThreadUpdater.postID = postID; $.event('QRPostSuccessful', { - board: g.BOARD, + boardID: g.BOARD.ID, threadID: threadID, postID: postID }); $.event('QRPostSuccessful_', { + boardID: g.BOARD.ID, threadID: threadID, postID: postID }); @@ -7260,8 +7175,7 @@ rectEl = this.nodes.el.getBoundingClientRect(); rectList = this.nodes.el.parentNode.getBoundingClientRect(); this.nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width / 2 - rectList.left - rectList.width / 2; - this.load(); - return $.event('QRPostSelection', this); + return this.load(); }; _Class.prototype.load = function() { @@ -7533,8 +7447,7 @@ el.title = "" + type + " Tyme"; FappeTyme[lc] = input = el.firstElementChild; $.on(input, 'change', FappeTyme.cb.toggle.bind(input)); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: el, order: 97 }); @@ -7633,8 +7546,7 @@ createSubEntry = Gallery.menu.createSubEntry; for (name in Config.gallery) { el = createSubEntry(name).el; - $.event('AddMenuEntry', { - type: 'gallery', + nodes.menu.addEntry({ el: el, order: 0 }); @@ -7868,8 +7780,7 @@ for (name in Config.gallery) { subEntries.push(createSubEntry(name)); } - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: el, order: 105, subEntries: subEntries @@ -8213,8 +8124,7 @@ conf = _ref[name]; subEntries.push(createSubEntry(name, conf[1])); } - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: el, order: 105, subEntries: subEntries @@ -8386,8 +8296,7 @@ }); this.el = prefetch.firstElementChild; $.on(this.el, 'change', this.toggle); - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: prefetch, order: 104 }); @@ -9144,7 +9053,6 @@ textContent: 'Archive' }); entry = { - type: 'post', el: div, order: 90, open: function(_arg) { @@ -9163,7 +9071,7 @@ type = _ref[_i]; entry.subEntries.push(this.createSubEntry(type[0], type[1])); } - return $.event('AddMenuEntry', entry); + return Menu.menu.addEntry(entry); }, createSubEntry: function(text, type) { var el, open; @@ -9240,8 +9148,7 @@ return true; } }; - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: div, order: 40, open: function(post) { @@ -9365,8 +9272,7 @@ }; })(this)); }); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: a, order: 100, open: function(_arg) { @@ -9434,8 +9340,7 @@ textContent: 'Report this post' }); $.on(a, 'click', ReportLink.report); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: a, order: 10, open: function(post) { @@ -9512,12 +9417,6 @@ }, node: function() { return d.title = Get.threadExcerpt(this); - }, - disconnect: function() { - if (g.VIEW !== 'thread' || !Conf['Thread Excerpt']) { - return; - } - return Thread.callbacks.disconnect('Thread Excerpt'); } }; @@ -9569,25 +9468,6 @@ ThreadStats.update(postCount, fileCount); return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate); }, - disconnect: function() { - if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { - return; - } - if (Conf['Updater and Stats in Header']) { - Header.rmShortcut(this.dialog); - } else { - $.rm(this.dialog); - } - clearTimeout(this.timeout); - delete this.timeout; - delete this.thread; - delete this.postCountEl; - delete this.fileCountEl; - delete this.pageCountEl; - delete this.dialog; - Thread.callbacks.disconnect('Thread Stats'); - return $.off(d, 'ThreadUpdate', ThreadStats.onUpdate); - }, onUpdate: function(e) { var fileCount, postCount, _ref; if (e.detail[404]) { @@ -9707,8 +9587,7 @@ subEntries.push({ el: this.settings }); - $.event('AddMenuEntry', this.entry = { - type: 'header', + Header.menu.addEntry(this.entry = { el: $.el('span', { textContent: 'Updater' }), @@ -9720,45 +9599,6 @@ cb: this.node }); }, - disconnect: function() { - var el, entry, input, name, _i, _j, _len, _len1, _ref, _ref1; - if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { - return; - } - $.off(this.timer, 'click', this.update); - $.off(this.status, 'click', this.update); - if (this.timeoutID) { - clearTimeout(this.timeoutID); - } - _ref = this.entry.subEntries; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - entry = _ref[_i]; - el = entry.el; - input = el.firstElementChild; - $.off(input, 'change', $.cb.checked); - $.off(input, 'change', this.cb.scrollBG); - $.off(input, 'change', this.cb.update); - } - $.off(this.settings, 'click', this.intervalShortcut); - $.off(window, 'online offline', this.cb.online); - $.off(d, 'QRPostSuccessful', this.cb.checkpost); - $.off(d, 'visibilitychange', this.cb.visibility); - this.set('timer', null); - this.set('status', 'Offline'); - $.event('rmMenuEntry', this.entry); - if (Conf['Updater and Stats in Header']) { - Header.rmShortcut(this.dialog); - } else { - $.rmClass(doc, 'float'); - $.rm(this.dialog); - } - _ref1 = ['checkPostCount', 'timer', 'status', 'isUpdating', 'entry', 'dialog', 'thread', 'root', 'lastPost', 'outdateCount', 'online', 'seconds', 'timeoutID']; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - name = _ref1[_j]; - delete this[name]; - } - return Thread.callbacks.disconnect('Thread Updater'); - }, node: function() { ThreadUpdater.thread = this; ThreadUpdater.root = this.OP.nodes.root.parentNode; @@ -9857,7 +9697,7 @@ ThreadUpdater.thread.kill(); $.event('ThreadUpdate', { 404: true, - thread: ThreadUpdater.thread + threadID: ThreadUpdater.thread.fullID }); break; default: @@ -9951,7 +9791,7 @@ return new Notice('info', "The thread is " + change + ".", 30); }, parse: function(postObjects) { - var OP, count, deletedFiles, deletedPosts, files, index, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1; + var OP, count, files, index, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1; OP = postObjects[0]; Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler; ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); @@ -9976,19 +9816,15 @@ node = Build.postFromObject(postObject, ThreadUpdater.thread.board.ID); posts.push(new Post(node, ThreadUpdater.thread, ThreadUpdater.thread.board)); } - deletedPosts = []; - deletedFiles = []; ThreadUpdater.thread.posts.forEach(function(post) { var ID; ID = +post.ID; if (__indexOf.call(index, ID) < 0) { post.kill(); - deletedPosts.push(post); } else if (post.isDead) { post.resurrect(); } else if (post.file && !(post.file.isDead || __indexOf.call(files, ID) >= 0)) { post.kill(true); - deletedFiles.push(post); } if (ThreadUpdater.postID && ThreadUpdater.postID === ID) { return ThreadUpdater.foundPost = true; @@ -10040,10 +9876,10 @@ } return $.event('ThreadUpdate', { 404: false, - thread: ThreadUpdater.thread, - newPosts: posts, - deletedPosts: deletedPosts, - deletedFiles: deletedFiles, + threadID: ThreadUpdater.thread.fullID, + newPosts: posts.map(function(post) { + return post.fullID; + }), postCount: OP.replies + 1, fileCount: OP.images + (!!ThreadUpdater.thread.OP.file && !ThreadUpdater.thread.OP.file.isDead) }); @@ -10070,9 +9906,6 @@ this.status = $('#watcher-status', this.dialog); this.list = this.dialog.lastElementChild; $.on(d, 'QRPostSuccessful', this.cb.post); - if (g.VIEW === 'thread') { - $.on(d, 'ThreadUpdate', this.cb.threadUpdate); - } $.on(sc, 'click', this.toggleWatcher); $.on($('.move>.close', ThreadWatcher.dialog), 'click', this.toggleWatcher); $.on(d, '4chanXInitFinished', this.ready); @@ -10181,14 +10014,14 @@ return ThreadWatcher.rm(boardID, +threadID); }, post: function(e) { - var board, postID, threadID, _ref; - _ref = e.detail, board = _ref.board, postID = _ref.postID, threadID = _ref.threadID; + var boardID, postID, threadID, _ref; + _ref = e.detail, boardID = _ref.boardID, threadID = _ref.threadID, postID = _ref.postID; if (postID === threadID) { if (Conf['Auto Watch']) { return $.set('AutoWatch', threadID); } } else if (Conf['Auto Watch Reply']) { - return ThreadWatcher.add(board.threads[threadID]); + return ThreadWatcher.add(g.threads[boardID + '.' + threadID]); } }, onIndexRefresh: function() { @@ -10218,7 +10051,7 @@ }, onThreadRefresh: function(e) { var thread; - thread = e.detail.thread; + thread = g.threads[e.detail.threadID]; if (!(e.detail[404] && ThreadWatcher.db.get({ boardID: thread.board.ID, threadID: thread.ID @@ -10430,7 +10263,7 @@ if (!Conf['Thread Watcher']) { return; } - menu = new UI.Menu('thread watcher'); + menu = this.menu = new UI.Menu('thread watcher'); $.on($('.menu-button', ThreadWatcher.dialog), 'click', function(e) { return menu.toggle(e, this, ThreadWatcher); }); @@ -10445,8 +10278,7 @@ entryEl = $.el('a', { href: 'javascript:;' }); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: entryEl, order: 60 }); @@ -10467,7 +10299,6 @@ entries.push({ cb: ThreadWatcher.cb.openAll, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Open all threads' }) @@ -10479,7 +10310,6 @@ entries.push({ cb: ThreadWatcher.cb.checkThreads, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Check 404\'d threads' }) @@ -10491,7 +10321,6 @@ entries.push({ cb: ThreadWatcher.cb.pruneDeads, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Prune 404\'d threads' }) @@ -10508,7 +10337,6 @@ } entries.push({ entry: { - type: 'thread watcher', el: $.el('span', { textContent: 'Settings' }), @@ -10526,7 +10354,7 @@ if (refresh) { this.refreshers.push(refresh.bind(entry)); } - $.event('AddMenuEntry', entry); + this.menu.addEntry(entry); } }, createSubEntry: function(name, desc) { @@ -10562,28 +10390,6 @@ cb: this.node }); }, - disconnect: function() { - var hr, name, _i, _len, _ref; - if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon'] && !Conf['Desktop Notifications']) { - return; - } - Unread.db.disconnect(); - if (hr = Unread.hr, Unread) { - $.rm(hr); - } - _ref = ['db', 'hr', 'posts', 'postsQuotingYou', 'thread', 'title', 'lastReadPost']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - delete this[name]; - } - $.off(d, '4chanXInitFinished', this.ready); - $.off(d, 'ThreadUpdate', this.onUpdate); - $.off(d, 'scroll visibilitychange', this.read); - if (Conf['Unread Line'] && !Conf['Quote Threading']) { - $.off(d, 'visibilitychange', this.setLine); - } - return Thread.callbacks.disconnect('Unread'); - }, node: function() { Unread.thread = this; Unread.title = d.title; @@ -10728,7 +10534,9 @@ if (e.detail[404]) { return Unread.update(); } else if (!QuoteThreading.enabled) { - return Unread.addPosts(e.detail.newPosts); + return Unread.addPosts(e.detail.newPosts.map(function(fullID) { + return g.posts[fullID]; + })); } else { Unread.read(); return Unread.update(); @@ -10937,7 +10745,6 @@ return; } entry = { - type: 'header', el: $.el('a', { textContent: 'Show announcement', className: 'show-announcement', @@ -10948,7 +10755,7 @@ return psa.hidden; } }; - $.event('AddMenuEntry', entry); + Header.menu.addEntry(entry); $.on(entry.el, 'click', PSAHiding.toggle); PSAHiding.btn = btn = $.el('span', { innerHTML: '[Dismiss]', @@ -11101,8 +10908,7 @@ input = $('input', el); $.on(input, 'change', this.toggle); $.sync('Header catalog links', CatalogLinks.set); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: el, order: 95 }); @@ -11599,7 +11405,7 @@ }); } if (board === 'sci') { - $.globalEval('window.addEventListener(\'jsmath\', function(e) {\n if (!jsMath) return;\n if (jsMath.loaded) {\n // process one post\n jsMath.ProcessBeforeShowing(e.detail);\n } else if (jsMath.Autoload && jsMath.Autoload.checked) {\n // load jsMath and process whole document\n jsMath.Autoload.Script.Push(\'ProcessBeforeShowing\', [null]);\n jsMath.Autoload.LoadJsMath();\n }\n}, false);'); + $.globalEval('window.addEventListener(\'jsmath\', function(e) {\n if (!jsMath) return;\n if (jsMath.loaded) {\n // process one post\n jsMath.ProcessBeforeShowing(document.getElementById(e.detail));\n } else if (jsMath.Autoload && jsMath.Autoload.checked) {\n // load jsMath and process whole document\n jsMath.Autoload.Script.Push(\'ProcessBeforeShowing\', [null]);\n jsMath.Autoload.LoadJsMath();\n }\n}, false);'); return Post.callbacks.push({ name: 'Parse /sci/ math', cb: this.math @@ -11632,7 +11438,7 @@ }; })(this)), (function(_this) { return function() { - return $.event('jsmath', _this.nodes.post, window); + return $.event('jsmath', _this.nodes.post.id, window); }; })(this)); }, @@ -12480,7 +12286,7 @@ Settings.dialog = dialog = $.el('div', { id: 'fourchanx-settings', className: 'dialog', - innerHTML: '
' + innerHTML: '
' }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); @@ -13185,7 +12991,6 @@ }); } } - $.on(d, 'AddCallback', Main.addCallback); return $.ready(Main.initReady); }, initStyle: function() { @@ -13325,7 +13130,7 @@ } if (previousversion) { el = $.el('span', { - innerHTML: '4chan X has been updated to version 1.7.63.' + innerHTML: '4chan X has been updated to version 1.8.1.' }); new Notice('info', el, 15); } else { @@ -13368,25 +13173,6 @@ }; return softTask(); }, - addCallback: function(e) { - var Klass, obj; - obj = e.detail; - if (typeof obj.callback.name !== 'string') { - throw new Error("Invalid callback name: " + obj.callback.name); - } - switch (obj.type) { - case 'Post': - Klass = Post; - break; - case 'Thread': - Klass = Thread; - break; - default: - return; - } - obj.callback.isAddon = true; - return Klass.callbacks.push(obj.callback); - }, handleErrors: function(errors) { var div, error, logs, _i, _len; if (!(errors instanceof Array)) { diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index 150a374a6..0db974ca9 100644 Binary files a/builds/4chan-X.zip and b/builds/4chan-X.zip differ diff --git a/builds/crx.crx b/builds/crx.crx index 0cfa77c54..89650ac61 100644 Binary files a/builds/crx.crx and b/builds/crx.crx differ diff --git a/builds/crx/manifest.json b/builds/crx/manifest.json index 375196003..550a82f46 100755 --- a/builds/crx/manifest.json +++ b/builds/crx/manifest.json @@ -1,6 +1,6 @@ { "name": "4chan X", - "version": "1.7.63", + "version": "1.8.1", "manifest_version": 2, "description": "Cross-browser userscript for maximum lurking on 4chan.", "icons": { diff --git a/builds/crx/script.js b/builds/crx/script.js index dadcf1dda..7adf59f4b 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.7.63 - 2014-06-16 +* 4chan X - Version 1.8.1 - 2014-06-19 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -349,7 +349,7 @@ doc = d.documentElement; g = { - VERSION: '1.7.63', + VERSION: '1.8.1', NAMESPACE: '4chan X.', boards: {} }; @@ -361,16 +361,6 @@ return root.querySelector(selector); }; - $.extend = function(obj, prop) { - var key, val; - for (key in prop) { - val = prop[key]; - if (prop.hasOwnProperty(key)) { - obj[key] = val; - } - } - }; - $.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000))); $.id = function(id) { @@ -875,36 +865,19 @@ Callbacks.prototype.push = function(_arg) { var cb, name; name = _arg.name, cb = _arg.cb; - if (this[name]) { - this.connect(name); - } if (!this[name]) { this.keys.push(name); } return this[name] = cb; }; - Callbacks.prototype.connect = function(name) { - if (this[name].disconnected) { - return delete this[name].disconnected; - } - }; - - Callbacks.prototype.disconnect = function(name) { - if (this[name]) { - return this[name].disconnected = true; - } - }; - Callbacks.prototype.execute = function(node) { var err, errors, name, _i, _len, _ref; _ref = this.keys; for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; try { - if (!this[name].disconnected) { - this[name].call(node); - } + this[name].call(node); } catch (_error) { err = _error; if (!errors) { @@ -1550,12 +1523,6 @@ return typeof this.sync === "function" ? this.sync() : void 0; }; - DataBoard.prototype.disconnect = function() { - $.desync(this.key); - delete this.sync; - return delete this.data; - }; - return DataBoard; })(); @@ -1878,8 +1845,7 @@ $.sync('Header auto-hide', this.setBarVisibility); $.sync('Centered links', this.setLinkJustify); this.addShortcut(menuButton); - $.event('AddMenuEntry', { - type: 'header', + this.menu.addEntry({ el: $.el('span', { textContent: 'Header' }), @@ -2286,12 +2252,9 @@ return Header.menu.toggle(e, this, g); }, createNotification: function(e) { - var cb, content, lifetime, notice, type, _ref; - _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime, cb = _ref.cb; - notice = new Notice(type, content, lifetime); - if (cb) { - return cb(notice); - } + var content, lifetime, notice, type, _ref; + _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime; + return notice = new Notice(type, content, lifetime); }, areNotificationsEnabled: false, enableDesktopNotifications: function() { @@ -2431,8 +2394,7 @@ $.on(input, 'change', this.cb.sort); } } - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: $.el('span', { textContent: 'Index Navigation' }), @@ -2957,14 +2919,12 @@ return nodes; }, buildStructure: function(nodes) { - var i, node, result; - result = $.frag(); - i = 0; - while (node = nodes[i++]) { - $.add(result, [node, $.el('hr')]); + var node, _i, _len; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + node = nodes[_i]; + $.add(Index.root, [node, $.el('hr')]); } - $.event('IndexBuild', result.children); - return $.add(Index.root, result); + return ThreadHiding.onIndexBuild(nodes); }, isSearching: false, clearSearch: function() { @@ -3142,7 +3102,7 @@ This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS). @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var E, boardID, capcode, container, date, dateUTC, email, file, fileSize, fileThumb, flagCode, flagName, h_capcodeClass, h_capcodeIcon, h_capcodeStart, h_closed, h_comment, h_emailEnd, h_emailStart, h_file, h_fileDims, h_fileInfo, h_fileTitle1, h_fileTitle2, h_flag, h_gifIcon, h_imgSrc, h_pageIcon, h_postClass, h_quoteLink, h_replyLink, h_sideArrows, h_staticPath, h_sticky, h_tripcode, h_userID, href, isClosed, isOP, isSticky, name, pageNum, postID, quote, shortFilename, spoilerRange, subject, threadID, tripcode, uniqueID, _i, _len, _ref; + var E, boardID, capcode, container, date, dateUTC, email, email_processed, file, fileSize, fileThumb, flagCode, flagName, h_capcodeClass, h_capcodeIcon, h_capcodeStart, h_closed, h_comment, h_emailEnd, h_emailStart, h_file, h_fileDims, h_fileInfo, h_fileTitle1, h_fileTitle2, h_flag, h_gifIcon, h_imgSrc, h_pageIcon, h_postClass, h_quoteLink, h_replyLink, h_sideArrows, h_staticPath, h_sticky, h_tripcode, h_userID, href, isClosed, isOP, isSticky, name, pageNum, postID, quote, shortFilename, spoilerRange, subject, threadID, tripcode, uniqueID, _i, _len, _ref; E = Build.h_escape; postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, h_comment = o.h_comment, file = o.file; name || (name = ''); @@ -3160,8 +3120,9 @@ } else { h_tripcode = ''; } + email_processed = encodeURIComponent(email).replace(/%40/g, '@'); if (email) { - h_emailStart = ""; + h_emailStart = ""; h_emailEnd = ''; } else { h_emailStart = ''; @@ -3608,7 +3569,7 @@ }; UI = (function() { - var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove; + var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, menus, touchend, touchmove; dialog = function(id, position, properties) { var child, el, move, _i, _len, _ref; el = $.el('div', { @@ -3634,6 +3595,7 @@ } return el; }; + menus = {}; Menu = (function() { var currentMenu, lastToggledButton; @@ -3643,14 +3605,23 @@ function Menu(type) { this.type = type; - this.rmEntry = __bind(this.rmEntry, this); this.addEntry = __bind(this.addEntry, this); this.onFocus = __bind(this.onFocus, this); this.keybinds = __bind(this.keybinds, this); this.close = __bind(this.close, this); - $.on(d, 'AddMenuEntry', this.addEntry); - $.on(d, 'rmMenuEntry', this.rmEntry); + $.on(d, 'AddMenuEntry', (function(_this) { + return function(_arg) { + var detail; + detail = _arg.detail; + if (detail.type !== _this.type) { + return; + } + delete detail.open; + return _this.addEntry(detail); + }; + })(this)); this.entries = []; + menus[this.type] = this; } Menu.prototype.makeMenu = function() { @@ -3841,26 +3812,11 @@ return style.right = right; }; - Menu.prototype.addEntry = function(e) { - var entry; - entry = e.detail; - if (entry.type !== this.type) { - return; - } + Menu.prototype.addEntry = function(entry) { this.parseEntry(entry); return this.entries.push(entry); }; - Menu.prototype.rmEntry = function(e) { - var entry, index; - entry = e.detail; - if (entry.type !== this.type) { - return; - } - index = this.entries.indexOf(entry); - return this.entries.splice(index, 1); - }; - Menu.prototype.parseEntry = function(entry) { var el, subEntries, subEntry, _i, _len; el = entry.el, subEntries = entry.subEntries; @@ -4320,7 +4276,6 @@ textContent: 'Filter' }); entry = { - type: 'post', el: div, order: 50, open: function(post) { @@ -4334,7 +4289,7 @@ type = _ref[_i]; entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])); } - return $.event('AddMenuEntry', entry); + return Menu.menu.addEntry(entry); }, createSubEntry: function(text, type) { var el; @@ -4440,8 +4395,7 @@ thisPost = UI.checkbox('thisPost', ' This post', true); replies = UI.checkbox('replies', ' Hide replies', Conf['Recursive Hiding']); makeStub = UI.checkbox('makeStub', ' Make stub', Conf['Stubs']); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(post) { @@ -4479,8 +4433,7 @@ href: 'javascript:;' }); $.on(hideStubLink, 'click', PostHiding.menu.hideStub); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(post) { @@ -4510,8 +4463,7 @@ } ] }); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: hideStubLink, order: 15, open: function(post) { @@ -4748,7 +4700,6 @@ } this.db = new DataBoard('hiddenThreads'); this.syncCatalog(); - $.on(d, 'IndexBuild', this.onIndexBuild); return Thread.callbacks.push({ name: 'Thread Hiding', cb: this.node @@ -4767,16 +4718,12 @@ } return $.prepend(this.OP.nodes.root, ThreadHiding.makeButton(this, 'hide')); }, - onIndexBuild: function(_arg) { - var i, nodes, root, thread, _i, _len; - nodes = _arg.detail; - for (i = _i = 0, _len = nodes.length; _i < _len; i = _i += 2) { - root = nodes[i]; + onIndexBuild: function(nodes) { + var root, thread, _i, _len; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + root = nodes[_i]; thread = Get.threadFromRoot(root); - if (!thread.isHidden) { - continue; - } - if (thread.stub && root.contains(thread.stub)) { + if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { ThreadHiding.makeStub(thread, root); } } @@ -4847,8 +4794,7 @@ }); $.on(apply, 'click', ThreadHiding.menu.hide); makeStub = UI.checkbox('Stubs', ' Make stub'); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(_arg) { @@ -4874,8 +4820,7 @@ href: 'javascript:;' }); $.on(div, 'click', ThreadHiding.menu.show); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(_arg) { @@ -4893,8 +4838,7 @@ href: 'javascript:;' }); $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: hideStubLink, order: 15, open: function(_arg) { @@ -5421,8 +5365,7 @@ }); input = $('input', this.controls); $.on(input, 'change', this.toggle); - $.event('AddMenuEntry', this.entry = { - type: 'header', + Header.menu.addEntry(this.entry = { el: this.controls, order: 98 }); @@ -5434,19 +5377,6 @@ cb: this.node }); }, - disconnect: function() { - var input; - if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { - return; - } - input = $('input', this.controls); - $.off(input, 'change', this.toggle); - $.event('rmMenuEntry', this.entry); - delete this.enabled; - delete this.controls; - delete this.entry; - return Post.callbacks.disconnect('Quote Threading'); - }, ready: function() { $.off(d, '4chanXInitFinished', QuoteThreading.ready); return QuoteThreading.force(); @@ -5849,16 +5779,6 @@ $.prepend($('.navLinksBot'), linkBot); } $.before($.id('togglePostFormLink'), link); - $.on(d, 'QRGetSelectedPost', function(_arg) { - var cb; - cb = _arg.detail; - return cb(QR.selected); - }); - $.on(d, 'QRAddPreSubmitHook', function(_arg) { - var cb; - cb = _arg.detail; - return QR.preSubmitHooks.push(cb); - }); $.on(d, 'paste', QR.paste); $.on(d, 'dragover', QR.dragOver); $.on(d, 'drop', QR.dropFile); @@ -6478,9 +6398,8 @@ return $.add(nodes.form, flag); } }, - preSubmitHooks: [], submit: function(e) { - var challenge, err, extra, filetag, formData, hook, options, post, response, textOnly, thread, threadID, _i, _len, _ref, _ref1; + var challenge, err, extra, filetag, formData, options, post, response, textOnly, thread, threadID, _ref; if (e != null) { e.preventDefault(); } @@ -6513,17 +6432,9 @@ err = 'No file selected.'; } else if (post.file && thread.fileLimit) { err = 'Max limit of image replies has been reached.'; - } else { - _ref = QR.preSubmitHooks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - hook = _ref[_i]; - if (err = hook(post, thread)) { - break; - } - } } if (QR.captcha.isEnabled && !err) { - _ref1 = QR.captcha.getOne(), challenge = _ref1.challenge, response = _ref1.response; + _ref = QR.captcha.getOne(), challenge = _ref.challenge, response = _ref.response; if (!response) { err = 'No valid captcha.'; } @@ -6656,11 +6567,12 @@ }); ThreadUpdater.postID = postID; $.event('QRPostSuccessful', { - board: g.BOARD, + boardID: g.BOARD.ID, threadID: threadID, postID: postID }); $.event('QRPostSuccessful_', { + boardID: g.BOARD.ID, threadID: threadID, postID: postID }); @@ -7277,8 +7189,7 @@ rectEl = this.nodes.el.getBoundingClientRect(); rectList = this.nodes.el.parentNode.getBoundingClientRect(); this.nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width / 2 - rectList.left - rectList.width / 2; - this.load(); - return $.event('QRPostSelection', this); + return this.load(); }; _Class.prototype.load = function() { @@ -7550,8 +7461,7 @@ el.title = "" + type + " Tyme"; FappeTyme[lc] = input = el.firstElementChild; $.on(input, 'change', FappeTyme.cb.toggle.bind(input)); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: el, order: 97 }); @@ -7650,8 +7560,7 @@ createSubEntry = Gallery.menu.createSubEntry; for (name in Config.gallery) { el = createSubEntry(name).el; - $.event('AddMenuEntry', { - type: 'gallery', + nodes.menu.addEntry({ el: el, order: 0 }); @@ -7885,8 +7794,7 @@ for (name in Config.gallery) { subEntries.push(createSubEntry(name)); } - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: el, order: 105, subEntries: subEntries @@ -8219,8 +8127,7 @@ conf = _ref[name]; subEntries.push(createSubEntry(name, conf[1])); } - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: el, order: 105, subEntries: subEntries @@ -8381,8 +8288,7 @@ }); this.el = prefetch.firstElementChild; $.on(this.el, 'change', this.toggle); - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: prefetch, order: 104 }); @@ -9139,7 +9045,6 @@ textContent: 'Archive' }); entry = { - type: 'post', el: div, order: 90, open: function(_arg) { @@ -9158,7 +9063,7 @@ type = _ref[_i]; entry.subEntries.push(this.createSubEntry(type[0], type[1])); } - return $.event('AddMenuEntry', entry); + return Menu.menu.addEntry(entry); }, createSubEntry: function(text, type) { var el, open; @@ -9235,8 +9140,7 @@ return true; } }; - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: div, order: 40, open: function(post) { @@ -9360,8 +9264,7 @@ }; })(this)); }); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: a, order: 100, open: function(_arg) { @@ -9429,8 +9332,7 @@ textContent: 'Report this post' }); $.on(a, 'click', ReportLink.report); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: a, order: 10, open: function(post) { @@ -9507,12 +9409,6 @@ }, node: function() { return d.title = Get.threadExcerpt(this); - }, - disconnect: function() { - if (g.VIEW !== 'thread' || !Conf['Thread Excerpt']) { - return; - } - return Thread.callbacks.disconnect('Thread Excerpt'); } }; @@ -9564,25 +9460,6 @@ ThreadStats.update(postCount, fileCount); return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate); }, - disconnect: function() { - if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { - return; - } - if (Conf['Updater and Stats in Header']) { - Header.rmShortcut(this.dialog); - } else { - $.rm(this.dialog); - } - clearTimeout(this.timeout); - delete this.timeout; - delete this.thread; - delete this.postCountEl; - delete this.fileCountEl; - delete this.pageCountEl; - delete this.dialog; - Thread.callbacks.disconnect('Thread Stats'); - return $.off(d, 'ThreadUpdate', ThreadStats.onUpdate); - }, onUpdate: function(e) { var fileCount, postCount, _ref; if (e.detail[404]) { @@ -9702,8 +9579,7 @@ subEntries.push({ el: this.settings }); - $.event('AddMenuEntry', this.entry = { - type: 'header', + Header.menu.addEntry(this.entry = { el: $.el('span', { textContent: 'Updater' }), @@ -9715,45 +9591,6 @@ cb: this.node }); }, - disconnect: function() { - var el, entry, input, name, _i, _j, _len, _len1, _ref, _ref1; - if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { - return; - } - $.off(this.timer, 'click', this.update); - $.off(this.status, 'click', this.update); - if (this.timeoutID) { - clearTimeout(this.timeoutID); - } - _ref = this.entry.subEntries; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - entry = _ref[_i]; - el = entry.el; - input = el.firstElementChild; - $.off(input, 'change', $.cb.checked); - $.off(input, 'change', this.cb.scrollBG); - $.off(input, 'change', this.cb.update); - } - $.off(this.settings, 'click', this.intervalShortcut); - $.off(window, 'online offline', this.cb.online); - $.off(d, 'QRPostSuccessful', this.cb.checkpost); - $.off(d, 'visibilitychange', this.cb.visibility); - this.set('timer', null); - this.set('status', 'Offline'); - $.event('rmMenuEntry', this.entry); - if (Conf['Updater and Stats in Header']) { - Header.rmShortcut(this.dialog); - } else { - $.rmClass(doc, 'float'); - $.rm(this.dialog); - } - _ref1 = ['checkPostCount', 'timer', 'status', 'isUpdating', 'entry', 'dialog', 'thread', 'root', 'lastPost', 'outdateCount', 'online', 'seconds', 'timeoutID']; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - name = _ref1[_j]; - delete this[name]; - } - return Thread.callbacks.disconnect('Thread Updater'); - }, node: function() { ThreadUpdater.thread = this; ThreadUpdater.root = this.OP.nodes.root.parentNode; @@ -9852,7 +9689,7 @@ ThreadUpdater.thread.kill(); $.event('ThreadUpdate', { 404: true, - thread: ThreadUpdater.thread + threadID: ThreadUpdater.thread.fullID }); break; default: @@ -9946,7 +9783,7 @@ return new Notice('info', "The thread is " + change + ".", 30); }, parse: function(postObjects) { - var OP, count, deletedFiles, deletedPosts, files, index, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1; + var OP, count, files, index, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1; OP = postObjects[0]; Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler; ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); @@ -9971,19 +9808,15 @@ node = Build.postFromObject(postObject, ThreadUpdater.thread.board.ID); posts.push(new Post(node, ThreadUpdater.thread, ThreadUpdater.thread.board)); } - deletedPosts = []; - deletedFiles = []; ThreadUpdater.thread.posts.forEach(function(post) { var ID; ID = +post.ID; if (__indexOf.call(index, ID) < 0) { post.kill(); - deletedPosts.push(post); } else if (post.isDead) { post.resurrect(); } else if (post.file && !(post.file.isDead || __indexOf.call(files, ID) >= 0)) { post.kill(true); - deletedFiles.push(post); } if (ThreadUpdater.postID && ThreadUpdater.postID === ID) { return ThreadUpdater.foundPost = true; @@ -10035,10 +9868,10 @@ } return $.event('ThreadUpdate', { 404: false, - thread: ThreadUpdater.thread, - newPosts: posts, - deletedPosts: deletedPosts, - deletedFiles: deletedFiles, + threadID: ThreadUpdater.thread.fullID, + newPosts: posts.map(function(post) { + return post.fullID; + }), postCount: OP.replies + 1, fileCount: OP.images + (!!ThreadUpdater.thread.OP.file && !ThreadUpdater.thread.OP.file.isDead) }); @@ -10065,9 +9898,6 @@ this.status = $('#watcher-status', this.dialog); this.list = this.dialog.lastElementChild; $.on(d, 'QRPostSuccessful', this.cb.post); - if (g.VIEW === 'thread') { - $.on(d, 'ThreadUpdate', this.cb.threadUpdate); - } $.on(sc, 'click', this.toggleWatcher); $.on($('.move>.close', ThreadWatcher.dialog), 'click', this.toggleWatcher); $.on(d, '4chanXInitFinished', this.ready); @@ -10176,14 +10006,14 @@ return ThreadWatcher.rm(boardID, +threadID); }, post: function(e) { - var board, postID, threadID, _ref; - _ref = e.detail, board = _ref.board, postID = _ref.postID, threadID = _ref.threadID; + var boardID, postID, threadID, _ref; + _ref = e.detail, boardID = _ref.boardID, threadID = _ref.threadID, postID = _ref.postID; if (postID === threadID) { if (Conf['Auto Watch']) { return $.set('AutoWatch', threadID); } } else if (Conf['Auto Watch Reply']) { - return ThreadWatcher.add(board.threads[threadID]); + return ThreadWatcher.add(g.threads[boardID + '.' + threadID]); } }, onIndexRefresh: function() { @@ -10213,7 +10043,7 @@ }, onThreadRefresh: function(e) { var thread; - thread = e.detail.thread; + thread = g.threads[e.detail.threadID]; if (!(e.detail[404] && ThreadWatcher.db.get({ boardID: thread.board.ID, threadID: thread.ID @@ -10425,7 +10255,7 @@ if (!Conf['Thread Watcher']) { return; } - menu = new UI.Menu('thread watcher'); + menu = this.menu = new UI.Menu('thread watcher'); $.on($('.menu-button', ThreadWatcher.dialog), 'click', function(e) { return menu.toggle(e, this, ThreadWatcher); }); @@ -10440,8 +10270,7 @@ entryEl = $.el('a', { href: 'javascript:;' }); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: entryEl, order: 60 }); @@ -10462,7 +10291,6 @@ entries.push({ cb: ThreadWatcher.cb.openAll, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Open all threads' }) @@ -10474,7 +10302,6 @@ entries.push({ cb: ThreadWatcher.cb.checkThreads, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Check 404\'d threads' }) @@ -10486,7 +10313,6 @@ entries.push({ cb: ThreadWatcher.cb.pruneDeads, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Prune 404\'d threads' }) @@ -10503,7 +10329,6 @@ } entries.push({ entry: { - type: 'thread watcher', el: $.el('span', { textContent: 'Settings' }), @@ -10521,7 +10346,7 @@ if (refresh) { this.refreshers.push(refresh.bind(entry)); } - $.event('AddMenuEntry', entry); + this.menu.addEntry(entry); } }, createSubEntry: function(name, desc) { @@ -10557,28 +10382,6 @@ cb: this.node }); }, - disconnect: function() { - var hr, name, _i, _len, _ref; - if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon'] && !Conf['Desktop Notifications']) { - return; - } - Unread.db.disconnect(); - if (hr = Unread.hr, Unread) { - $.rm(hr); - } - _ref = ['db', 'hr', 'posts', 'postsQuotingYou', 'thread', 'title', 'lastReadPost']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - delete this[name]; - } - $.off(d, '4chanXInitFinished', this.ready); - $.off(d, 'ThreadUpdate', this.onUpdate); - $.off(d, 'scroll visibilitychange', this.read); - if (Conf['Unread Line'] && !Conf['Quote Threading']) { - $.off(d, 'visibilitychange', this.setLine); - } - return Thread.callbacks.disconnect('Unread'); - }, node: function() { Unread.thread = this; Unread.title = d.title; @@ -10723,7 +10526,9 @@ if (e.detail[404]) { return Unread.update(); } else if (!QuoteThreading.enabled) { - return Unread.addPosts(e.detail.newPosts); + return Unread.addPosts(e.detail.newPosts.map(function(fullID) { + return g.posts[fullID]; + })); } else { Unread.read(); return Unread.update(); @@ -10931,7 +10736,6 @@ return; } entry = { - type: 'header', el: $.el('a', { textContent: 'Show announcement', className: 'show-announcement', @@ -10942,7 +10746,7 @@ return psa.hidden; } }; - $.event('AddMenuEntry', entry); + Header.menu.addEntry(entry); $.on(entry.el, 'click', PSAHiding.toggle); PSAHiding.btn = btn = $.el('span', { innerHTML: '[Dismiss]', @@ -11095,8 +10899,7 @@ input = $('input', el); $.on(input, 'change', this.toggle); $.sync('Header catalog links', CatalogLinks.set); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: el, order: 95 }); @@ -11593,7 +11396,7 @@ }); } if (board === 'sci') { - $.globalEval('window.addEventListener(\'jsmath\', function(e) {\n if (!jsMath) return;\n if (jsMath.loaded) {\n // process one post\n jsMath.ProcessBeforeShowing(e.detail);\n } else if (jsMath.Autoload && jsMath.Autoload.checked) {\n // load jsMath and process whole document\n jsMath.Autoload.Script.Push(\'ProcessBeforeShowing\', [null]);\n jsMath.Autoload.LoadJsMath();\n }\n}, false);'); + $.globalEval('window.addEventListener(\'jsmath\', function(e) {\n if (!jsMath) return;\n if (jsMath.loaded) {\n // process one post\n jsMath.ProcessBeforeShowing(document.getElementById(e.detail));\n } else if (jsMath.Autoload && jsMath.Autoload.checked) {\n // load jsMath and process whole document\n jsMath.Autoload.Script.Push(\'ProcessBeforeShowing\', [null]);\n jsMath.Autoload.LoadJsMath();\n }\n}, false);'); return Post.callbacks.push({ name: 'Parse /sci/ math', cb: this.math @@ -11626,7 +11429,7 @@ }; })(this)), (function(_this) { return function() { - return $.event('jsmath', _this.nodes.post, window); + return $.event('jsmath', _this.nodes.post.id, window); }; })(this)); }, @@ -12474,7 +12277,7 @@ Settings.dialog = dialog = $.el('div', { id: 'fourchanx-settings', className: 'dialog', - innerHTML: '
' + innerHTML: '
' }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); @@ -13176,7 +12979,6 @@ }); } } - $.on(d, 'AddCallback', Main.addCallback); return $.ready(Main.initReady); }, initStyle: function() { @@ -13306,7 +13108,7 @@ } if (previousversion) { el = $.el('span', { - innerHTML: '4chan X has been updated to version 1.7.63.' + innerHTML: '4chan X has been updated to version 1.8.1.' }); new Notice('info', el, 15); } else { @@ -13349,25 +13151,6 @@ }; return softTask(); }, - addCallback: function(e) { - var Klass, obj; - obj = e.detail; - if (typeof obj.callback.name !== 'string') { - throw new Error("Invalid callback name: " + obj.callback.name); - } - switch (obj.type) { - case 'Post': - Klass = Post; - break; - case 'Thread': - Klass = Thread; - break; - default: - return; - } - obj.callback.isAddon = true; - return Klass.callbacks.push(obj.callback); - }, handleErrors: function(errors) { var div, error, logs, _i, _len; if (!(errors instanceof Array)) { diff --git a/builds/updates.xml b/builds/updates.xml index 0b5556be6..1c072d72c 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/builds/wcrx/manifest.json b/builds/wcrx/manifest.json index 15d520cf8..7f914699d 100644 --- a/builds/wcrx/manifest.json +++ b/builds/wcrx/manifest.json @@ -1,6 +1,6 @@ { "name": "4chan X", - "version": "1.7.63", + "version": "1.8.1", "manifest_version": 2, "description": "Cross-browser userscript for maximum lurking on 4chan.", "icons": { diff --git a/builds/wcrx/script.js b/builds/wcrx/script.js index dadcf1dda..7adf59f4b 100644 --- a/builds/wcrx/script.js +++ b/builds/wcrx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.7.63 - 2014-06-16 +* 4chan X - Version 1.8.1 - 2014-06-19 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -349,7 +349,7 @@ doc = d.documentElement; g = { - VERSION: '1.7.63', + VERSION: '1.8.1', NAMESPACE: '4chan X.', boards: {} }; @@ -361,16 +361,6 @@ return root.querySelector(selector); }; - $.extend = function(obj, prop) { - var key, val; - for (key in prop) { - val = prop[key]; - if (prop.hasOwnProperty(key)) { - obj[key] = val; - } - } - }; - $.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000))); $.id = function(id) { @@ -875,36 +865,19 @@ Callbacks.prototype.push = function(_arg) { var cb, name; name = _arg.name, cb = _arg.cb; - if (this[name]) { - this.connect(name); - } if (!this[name]) { this.keys.push(name); } return this[name] = cb; }; - Callbacks.prototype.connect = function(name) { - if (this[name].disconnected) { - return delete this[name].disconnected; - } - }; - - Callbacks.prototype.disconnect = function(name) { - if (this[name]) { - return this[name].disconnected = true; - } - }; - Callbacks.prototype.execute = function(node) { var err, errors, name, _i, _len, _ref; _ref = this.keys; for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; try { - if (!this[name].disconnected) { - this[name].call(node); - } + this[name].call(node); } catch (_error) { err = _error; if (!errors) { @@ -1550,12 +1523,6 @@ return typeof this.sync === "function" ? this.sync() : void 0; }; - DataBoard.prototype.disconnect = function() { - $.desync(this.key); - delete this.sync; - return delete this.data; - }; - return DataBoard; })(); @@ -1878,8 +1845,7 @@ $.sync('Header auto-hide', this.setBarVisibility); $.sync('Centered links', this.setLinkJustify); this.addShortcut(menuButton); - $.event('AddMenuEntry', { - type: 'header', + this.menu.addEntry({ el: $.el('span', { textContent: 'Header' }), @@ -2286,12 +2252,9 @@ return Header.menu.toggle(e, this, g); }, createNotification: function(e) { - var cb, content, lifetime, notice, type, _ref; - _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime, cb = _ref.cb; - notice = new Notice(type, content, lifetime); - if (cb) { - return cb(notice); - } + var content, lifetime, notice, type, _ref; + _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime; + return notice = new Notice(type, content, lifetime); }, areNotificationsEnabled: false, enableDesktopNotifications: function() { @@ -2431,8 +2394,7 @@ $.on(input, 'change', this.cb.sort); } } - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: $.el('span', { textContent: 'Index Navigation' }), @@ -2957,14 +2919,12 @@ return nodes; }, buildStructure: function(nodes) { - var i, node, result; - result = $.frag(); - i = 0; - while (node = nodes[i++]) { - $.add(result, [node, $.el('hr')]); + var node, _i, _len; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + node = nodes[_i]; + $.add(Index.root, [node, $.el('hr')]); } - $.event('IndexBuild', result.children); - return $.add(Index.root, result); + return ThreadHiding.onIndexBuild(nodes); }, isSearching: false, clearSearch: function() { @@ -3142,7 +3102,7 @@ This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS). @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var E, boardID, capcode, container, date, dateUTC, email, file, fileSize, fileThumb, flagCode, flagName, h_capcodeClass, h_capcodeIcon, h_capcodeStart, h_closed, h_comment, h_emailEnd, h_emailStart, h_file, h_fileDims, h_fileInfo, h_fileTitle1, h_fileTitle2, h_flag, h_gifIcon, h_imgSrc, h_pageIcon, h_postClass, h_quoteLink, h_replyLink, h_sideArrows, h_staticPath, h_sticky, h_tripcode, h_userID, href, isClosed, isOP, isSticky, name, pageNum, postID, quote, shortFilename, spoilerRange, subject, threadID, tripcode, uniqueID, _i, _len, _ref; + var E, boardID, capcode, container, date, dateUTC, email, email_processed, file, fileSize, fileThumb, flagCode, flagName, h_capcodeClass, h_capcodeIcon, h_capcodeStart, h_closed, h_comment, h_emailEnd, h_emailStart, h_file, h_fileDims, h_fileInfo, h_fileTitle1, h_fileTitle2, h_flag, h_gifIcon, h_imgSrc, h_pageIcon, h_postClass, h_quoteLink, h_replyLink, h_sideArrows, h_staticPath, h_sticky, h_tripcode, h_userID, href, isClosed, isOP, isSticky, name, pageNum, postID, quote, shortFilename, spoilerRange, subject, threadID, tripcode, uniqueID, _i, _len, _ref; E = Build.h_escape; postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, h_comment = o.h_comment, file = o.file; name || (name = ''); @@ -3160,8 +3120,9 @@ } else { h_tripcode = ''; } + email_processed = encodeURIComponent(email).replace(/%40/g, '@'); if (email) { - h_emailStart = ""; + h_emailStart = ""; h_emailEnd = ''; } else { h_emailStart = ''; @@ -3608,7 +3569,7 @@ }; UI = (function() { - var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove; + var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, menus, touchend, touchmove; dialog = function(id, position, properties) { var child, el, move, _i, _len, _ref; el = $.el('div', { @@ -3634,6 +3595,7 @@ } return el; }; + menus = {}; Menu = (function() { var currentMenu, lastToggledButton; @@ -3643,14 +3605,23 @@ function Menu(type) { this.type = type; - this.rmEntry = __bind(this.rmEntry, this); this.addEntry = __bind(this.addEntry, this); this.onFocus = __bind(this.onFocus, this); this.keybinds = __bind(this.keybinds, this); this.close = __bind(this.close, this); - $.on(d, 'AddMenuEntry', this.addEntry); - $.on(d, 'rmMenuEntry', this.rmEntry); + $.on(d, 'AddMenuEntry', (function(_this) { + return function(_arg) { + var detail; + detail = _arg.detail; + if (detail.type !== _this.type) { + return; + } + delete detail.open; + return _this.addEntry(detail); + }; + })(this)); this.entries = []; + menus[this.type] = this; } Menu.prototype.makeMenu = function() { @@ -3841,26 +3812,11 @@ return style.right = right; }; - Menu.prototype.addEntry = function(e) { - var entry; - entry = e.detail; - if (entry.type !== this.type) { - return; - } + Menu.prototype.addEntry = function(entry) { this.parseEntry(entry); return this.entries.push(entry); }; - Menu.prototype.rmEntry = function(e) { - var entry, index; - entry = e.detail; - if (entry.type !== this.type) { - return; - } - index = this.entries.indexOf(entry); - return this.entries.splice(index, 1); - }; - Menu.prototype.parseEntry = function(entry) { var el, subEntries, subEntry, _i, _len; el = entry.el, subEntries = entry.subEntries; @@ -4320,7 +4276,6 @@ textContent: 'Filter' }); entry = { - type: 'post', el: div, order: 50, open: function(post) { @@ -4334,7 +4289,7 @@ type = _ref[_i]; entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])); } - return $.event('AddMenuEntry', entry); + return Menu.menu.addEntry(entry); }, createSubEntry: function(text, type) { var el; @@ -4440,8 +4395,7 @@ thisPost = UI.checkbox('thisPost', ' This post', true); replies = UI.checkbox('replies', ' Hide replies', Conf['Recursive Hiding']); makeStub = UI.checkbox('makeStub', ' Make stub', Conf['Stubs']); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(post) { @@ -4479,8 +4433,7 @@ href: 'javascript:;' }); $.on(hideStubLink, 'click', PostHiding.menu.hideStub); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(post) { @@ -4510,8 +4463,7 @@ } ] }); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: hideStubLink, order: 15, open: function(post) { @@ -4748,7 +4700,6 @@ } this.db = new DataBoard('hiddenThreads'); this.syncCatalog(); - $.on(d, 'IndexBuild', this.onIndexBuild); return Thread.callbacks.push({ name: 'Thread Hiding', cb: this.node @@ -4767,16 +4718,12 @@ } return $.prepend(this.OP.nodes.root, ThreadHiding.makeButton(this, 'hide')); }, - onIndexBuild: function(_arg) { - var i, nodes, root, thread, _i, _len; - nodes = _arg.detail; - for (i = _i = 0, _len = nodes.length; _i < _len; i = _i += 2) { - root = nodes[i]; + onIndexBuild: function(nodes) { + var root, thread, _i, _len; + for (_i = 0, _len = nodes.length; _i < _len; _i++) { + root = nodes[_i]; thread = Get.threadFromRoot(root); - if (!thread.isHidden) { - continue; - } - if (thread.stub && root.contains(thread.stub)) { + if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { ThreadHiding.makeStub(thread, root); } } @@ -4847,8 +4794,7 @@ }); $.on(apply, 'click', ThreadHiding.menu.hide); makeStub = UI.checkbox('Stubs', ' Make stub'); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(_arg) { @@ -4874,8 +4820,7 @@ href: 'javascript:;' }); $.on(div, 'click', ThreadHiding.menu.show); - $.event('AddMenuEntry', { - type: 'post', + Menu.menu.addEntry({ el: div, order: 20, open: function(_arg) { @@ -4893,8 +4838,7 @@ href: 'javascript:;' }); $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: hideStubLink, order: 15, open: function(_arg) { @@ -5421,8 +5365,7 @@ }); input = $('input', this.controls); $.on(input, 'change', this.toggle); - $.event('AddMenuEntry', this.entry = { - type: 'header', + Header.menu.addEntry(this.entry = { el: this.controls, order: 98 }); @@ -5434,19 +5377,6 @@ cb: this.node }); }, - disconnect: function() { - var input; - if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { - return; - } - input = $('input', this.controls); - $.off(input, 'change', this.toggle); - $.event('rmMenuEntry', this.entry); - delete this.enabled; - delete this.controls; - delete this.entry; - return Post.callbacks.disconnect('Quote Threading'); - }, ready: function() { $.off(d, '4chanXInitFinished', QuoteThreading.ready); return QuoteThreading.force(); @@ -5849,16 +5779,6 @@ $.prepend($('.navLinksBot'), linkBot); } $.before($.id('togglePostFormLink'), link); - $.on(d, 'QRGetSelectedPost', function(_arg) { - var cb; - cb = _arg.detail; - return cb(QR.selected); - }); - $.on(d, 'QRAddPreSubmitHook', function(_arg) { - var cb; - cb = _arg.detail; - return QR.preSubmitHooks.push(cb); - }); $.on(d, 'paste', QR.paste); $.on(d, 'dragover', QR.dragOver); $.on(d, 'drop', QR.dropFile); @@ -6478,9 +6398,8 @@ return $.add(nodes.form, flag); } }, - preSubmitHooks: [], submit: function(e) { - var challenge, err, extra, filetag, formData, hook, options, post, response, textOnly, thread, threadID, _i, _len, _ref, _ref1; + var challenge, err, extra, filetag, formData, options, post, response, textOnly, thread, threadID, _ref; if (e != null) { e.preventDefault(); } @@ -6513,17 +6432,9 @@ err = 'No file selected.'; } else if (post.file && thread.fileLimit) { err = 'Max limit of image replies has been reached.'; - } else { - _ref = QR.preSubmitHooks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - hook = _ref[_i]; - if (err = hook(post, thread)) { - break; - } - } } if (QR.captcha.isEnabled && !err) { - _ref1 = QR.captcha.getOne(), challenge = _ref1.challenge, response = _ref1.response; + _ref = QR.captcha.getOne(), challenge = _ref.challenge, response = _ref.response; if (!response) { err = 'No valid captcha.'; } @@ -6656,11 +6567,12 @@ }); ThreadUpdater.postID = postID; $.event('QRPostSuccessful', { - board: g.BOARD, + boardID: g.BOARD.ID, threadID: threadID, postID: postID }); $.event('QRPostSuccessful_', { + boardID: g.BOARD.ID, threadID: threadID, postID: postID }); @@ -7277,8 +7189,7 @@ rectEl = this.nodes.el.getBoundingClientRect(); rectList = this.nodes.el.parentNode.getBoundingClientRect(); this.nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width / 2 - rectList.left - rectList.width / 2; - this.load(); - return $.event('QRPostSelection', this); + return this.load(); }; _Class.prototype.load = function() { @@ -7550,8 +7461,7 @@ el.title = "" + type + " Tyme"; FappeTyme[lc] = input = el.firstElementChild; $.on(input, 'change', FappeTyme.cb.toggle.bind(input)); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: el, order: 97 }); @@ -7650,8 +7560,7 @@ createSubEntry = Gallery.menu.createSubEntry; for (name in Config.gallery) { el = createSubEntry(name).el; - $.event('AddMenuEntry', { - type: 'gallery', + nodes.menu.addEntry({ el: el, order: 0 }); @@ -7885,8 +7794,7 @@ for (name in Config.gallery) { subEntries.push(createSubEntry(name)); } - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: el, order: 105, subEntries: subEntries @@ -8219,8 +8127,7 @@ conf = _ref[name]; subEntries.push(createSubEntry(name, conf[1])); } - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: el, order: 105, subEntries: subEntries @@ -8381,8 +8288,7 @@ }); this.el = prefetch.firstElementChild; $.on(this.el, 'change', this.toggle); - return $.event('AddMenuEntry', { - type: 'header', + return Header.menu.addEntry({ el: prefetch, order: 104 }); @@ -9139,7 +9045,6 @@ textContent: 'Archive' }); entry = { - type: 'post', el: div, order: 90, open: function(_arg) { @@ -9158,7 +9063,7 @@ type = _ref[_i]; entry.subEntries.push(this.createSubEntry(type[0], type[1])); } - return $.event('AddMenuEntry', entry); + return Menu.menu.addEntry(entry); }, createSubEntry: function(text, type) { var el, open; @@ -9235,8 +9140,7 @@ return true; } }; - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: div, order: 40, open: function(post) { @@ -9360,8 +9264,7 @@ }; })(this)); }); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: a, order: 100, open: function(_arg) { @@ -9429,8 +9332,7 @@ textContent: 'Report this post' }); $.on(a, 'click', ReportLink.report); - return $.event('AddMenuEntry', { - type: 'post', + return Menu.menu.addEntry({ el: a, order: 10, open: function(post) { @@ -9507,12 +9409,6 @@ }, node: function() { return d.title = Get.threadExcerpt(this); - }, - disconnect: function() { - if (g.VIEW !== 'thread' || !Conf['Thread Excerpt']) { - return; - } - return Thread.callbacks.disconnect('Thread Excerpt'); } }; @@ -9564,25 +9460,6 @@ ThreadStats.update(postCount, fileCount); return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate); }, - disconnect: function() { - if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { - return; - } - if (Conf['Updater and Stats in Header']) { - Header.rmShortcut(this.dialog); - } else { - $.rm(this.dialog); - } - clearTimeout(this.timeout); - delete this.timeout; - delete this.thread; - delete this.postCountEl; - delete this.fileCountEl; - delete this.pageCountEl; - delete this.dialog; - Thread.callbacks.disconnect('Thread Stats'); - return $.off(d, 'ThreadUpdate', ThreadStats.onUpdate); - }, onUpdate: function(e) { var fileCount, postCount, _ref; if (e.detail[404]) { @@ -9702,8 +9579,7 @@ subEntries.push({ el: this.settings }); - $.event('AddMenuEntry', this.entry = { - type: 'header', + Header.menu.addEntry(this.entry = { el: $.el('span', { textContent: 'Updater' }), @@ -9715,45 +9591,6 @@ cb: this.node }); }, - disconnect: function() { - var el, entry, input, name, _i, _j, _len, _len1, _ref, _ref1; - if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { - return; - } - $.off(this.timer, 'click', this.update); - $.off(this.status, 'click', this.update); - if (this.timeoutID) { - clearTimeout(this.timeoutID); - } - _ref = this.entry.subEntries; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - entry = _ref[_i]; - el = entry.el; - input = el.firstElementChild; - $.off(input, 'change', $.cb.checked); - $.off(input, 'change', this.cb.scrollBG); - $.off(input, 'change', this.cb.update); - } - $.off(this.settings, 'click', this.intervalShortcut); - $.off(window, 'online offline', this.cb.online); - $.off(d, 'QRPostSuccessful', this.cb.checkpost); - $.off(d, 'visibilitychange', this.cb.visibility); - this.set('timer', null); - this.set('status', 'Offline'); - $.event('rmMenuEntry', this.entry); - if (Conf['Updater and Stats in Header']) { - Header.rmShortcut(this.dialog); - } else { - $.rmClass(doc, 'float'); - $.rm(this.dialog); - } - _ref1 = ['checkPostCount', 'timer', 'status', 'isUpdating', 'entry', 'dialog', 'thread', 'root', 'lastPost', 'outdateCount', 'online', 'seconds', 'timeoutID']; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - name = _ref1[_j]; - delete this[name]; - } - return Thread.callbacks.disconnect('Thread Updater'); - }, node: function() { ThreadUpdater.thread = this; ThreadUpdater.root = this.OP.nodes.root.parentNode; @@ -9852,7 +9689,7 @@ ThreadUpdater.thread.kill(); $.event('ThreadUpdate', { 404: true, - thread: ThreadUpdater.thread + threadID: ThreadUpdater.thread.fullID }); break; default: @@ -9946,7 +9783,7 @@ return new Notice('info', "The thread is " + change + ".", 30); }, parse: function(postObjects) { - var OP, count, deletedFiles, deletedPosts, files, index, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1; + var OP, count, files, index, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1; OP = postObjects[0]; Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler; ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); @@ -9971,19 +9808,15 @@ node = Build.postFromObject(postObject, ThreadUpdater.thread.board.ID); posts.push(new Post(node, ThreadUpdater.thread, ThreadUpdater.thread.board)); } - deletedPosts = []; - deletedFiles = []; ThreadUpdater.thread.posts.forEach(function(post) { var ID; ID = +post.ID; if (__indexOf.call(index, ID) < 0) { post.kill(); - deletedPosts.push(post); } else if (post.isDead) { post.resurrect(); } else if (post.file && !(post.file.isDead || __indexOf.call(files, ID) >= 0)) { post.kill(true); - deletedFiles.push(post); } if (ThreadUpdater.postID && ThreadUpdater.postID === ID) { return ThreadUpdater.foundPost = true; @@ -10035,10 +9868,10 @@ } return $.event('ThreadUpdate', { 404: false, - thread: ThreadUpdater.thread, - newPosts: posts, - deletedPosts: deletedPosts, - deletedFiles: deletedFiles, + threadID: ThreadUpdater.thread.fullID, + newPosts: posts.map(function(post) { + return post.fullID; + }), postCount: OP.replies + 1, fileCount: OP.images + (!!ThreadUpdater.thread.OP.file && !ThreadUpdater.thread.OP.file.isDead) }); @@ -10065,9 +9898,6 @@ this.status = $('#watcher-status', this.dialog); this.list = this.dialog.lastElementChild; $.on(d, 'QRPostSuccessful', this.cb.post); - if (g.VIEW === 'thread') { - $.on(d, 'ThreadUpdate', this.cb.threadUpdate); - } $.on(sc, 'click', this.toggleWatcher); $.on($('.move>.close', ThreadWatcher.dialog), 'click', this.toggleWatcher); $.on(d, '4chanXInitFinished', this.ready); @@ -10176,14 +10006,14 @@ return ThreadWatcher.rm(boardID, +threadID); }, post: function(e) { - var board, postID, threadID, _ref; - _ref = e.detail, board = _ref.board, postID = _ref.postID, threadID = _ref.threadID; + var boardID, postID, threadID, _ref; + _ref = e.detail, boardID = _ref.boardID, threadID = _ref.threadID, postID = _ref.postID; if (postID === threadID) { if (Conf['Auto Watch']) { return $.set('AutoWatch', threadID); } } else if (Conf['Auto Watch Reply']) { - return ThreadWatcher.add(board.threads[threadID]); + return ThreadWatcher.add(g.threads[boardID + '.' + threadID]); } }, onIndexRefresh: function() { @@ -10213,7 +10043,7 @@ }, onThreadRefresh: function(e) { var thread; - thread = e.detail.thread; + thread = g.threads[e.detail.threadID]; if (!(e.detail[404] && ThreadWatcher.db.get({ boardID: thread.board.ID, threadID: thread.ID @@ -10425,7 +10255,7 @@ if (!Conf['Thread Watcher']) { return; } - menu = new UI.Menu('thread watcher'); + menu = this.menu = new UI.Menu('thread watcher'); $.on($('.menu-button', ThreadWatcher.dialog), 'click', function(e) { return menu.toggle(e, this, ThreadWatcher); }); @@ -10440,8 +10270,7 @@ entryEl = $.el('a', { href: 'javascript:;' }); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: entryEl, order: 60 }); @@ -10462,7 +10291,6 @@ entries.push({ cb: ThreadWatcher.cb.openAll, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Open all threads' }) @@ -10474,7 +10302,6 @@ entries.push({ cb: ThreadWatcher.cb.checkThreads, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Check 404\'d threads' }) @@ -10486,7 +10313,6 @@ entries.push({ cb: ThreadWatcher.cb.pruneDeads, entry: { - type: 'thread watcher', el: $.el('a', { textContent: 'Prune 404\'d threads' }) @@ -10503,7 +10329,6 @@ } entries.push({ entry: { - type: 'thread watcher', el: $.el('span', { textContent: 'Settings' }), @@ -10521,7 +10346,7 @@ if (refresh) { this.refreshers.push(refresh.bind(entry)); } - $.event('AddMenuEntry', entry); + this.menu.addEntry(entry); } }, createSubEntry: function(name, desc) { @@ -10557,28 +10382,6 @@ cb: this.node }); }, - disconnect: function() { - var hr, name, _i, _len, _ref; - if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon'] && !Conf['Desktop Notifications']) { - return; - } - Unread.db.disconnect(); - if (hr = Unread.hr, Unread) { - $.rm(hr); - } - _ref = ['db', 'hr', 'posts', 'postsQuotingYou', 'thread', 'title', 'lastReadPost']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - delete this[name]; - } - $.off(d, '4chanXInitFinished', this.ready); - $.off(d, 'ThreadUpdate', this.onUpdate); - $.off(d, 'scroll visibilitychange', this.read); - if (Conf['Unread Line'] && !Conf['Quote Threading']) { - $.off(d, 'visibilitychange', this.setLine); - } - return Thread.callbacks.disconnect('Unread'); - }, node: function() { Unread.thread = this; Unread.title = d.title; @@ -10723,7 +10526,9 @@ if (e.detail[404]) { return Unread.update(); } else if (!QuoteThreading.enabled) { - return Unread.addPosts(e.detail.newPosts); + return Unread.addPosts(e.detail.newPosts.map(function(fullID) { + return g.posts[fullID]; + })); } else { Unread.read(); return Unread.update(); @@ -10931,7 +10736,6 @@ return; } entry = { - type: 'header', el: $.el('a', { textContent: 'Show announcement', className: 'show-announcement', @@ -10942,7 +10746,7 @@ return psa.hidden; } }; - $.event('AddMenuEntry', entry); + Header.menu.addEntry(entry); $.on(entry.el, 'click', PSAHiding.toggle); PSAHiding.btn = btn = $.el('span', { innerHTML: '[Dismiss]', @@ -11095,8 +10899,7 @@ input = $('input', el); $.on(input, 'change', this.toggle); $.sync('Header catalog links', CatalogLinks.set); - $.event('AddMenuEntry', { - type: 'header', + Header.menu.addEntry({ el: el, order: 95 }); @@ -11593,7 +11396,7 @@ }); } if (board === 'sci') { - $.globalEval('window.addEventListener(\'jsmath\', function(e) {\n if (!jsMath) return;\n if (jsMath.loaded) {\n // process one post\n jsMath.ProcessBeforeShowing(e.detail);\n } else if (jsMath.Autoload && jsMath.Autoload.checked) {\n // load jsMath and process whole document\n jsMath.Autoload.Script.Push(\'ProcessBeforeShowing\', [null]);\n jsMath.Autoload.LoadJsMath();\n }\n}, false);'); + $.globalEval('window.addEventListener(\'jsmath\', function(e) {\n if (!jsMath) return;\n if (jsMath.loaded) {\n // process one post\n jsMath.ProcessBeforeShowing(document.getElementById(e.detail));\n } else if (jsMath.Autoload && jsMath.Autoload.checked) {\n // load jsMath and process whole document\n jsMath.Autoload.Script.Push(\'ProcessBeforeShowing\', [null]);\n jsMath.Autoload.LoadJsMath();\n }\n}, false);'); return Post.callbacks.push({ name: 'Parse /sci/ math', cb: this.math @@ -11626,7 +11429,7 @@ }; })(this)), (function(_this) { return function() { - return $.event('jsmath', _this.nodes.post, window); + return $.event('jsmath', _this.nodes.post.id, window); }; })(this)); }, @@ -12474,7 +12277,7 @@ Settings.dialog = dialog = $.el('div', { id: 'fourchanx-settings', className: 'dialog', - innerHTML: '
' + innerHTML: '
' }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); @@ -13176,7 +12979,6 @@ }); } } - $.on(d, 'AddCallback', Main.addCallback); return $.ready(Main.initReady); }, initStyle: function() { @@ -13306,7 +13108,7 @@ } if (previousversion) { el = $.el('span', { - innerHTML: '4chan X has been updated to version 1.7.63.' + innerHTML: '4chan X has been updated to version 1.8.1.' }); new Notice('info', el, 15); } else { @@ -13349,25 +13151,6 @@ }; return softTask(); }, - addCallback: function(e) { - var Klass, obj; - obj = e.detail; - if (typeof obj.callback.name !== 'string') { - throw new Error("Invalid callback name: " + obj.callback.name); - } - switch (obj.type) { - case 'Post': - Klass = Post; - break; - case 'Thread': - Klass = Thread; - break; - default: - return; - } - obj.callback.isAddon = true; - return Klass.callbacks.push(obj.callback); - }, handleErrors: function(errors) { var div, error, logs, _i, _len; if (!(errors instanceof Array)) { diff --git a/package.json b/package.json index 3a0a34816..c2c29d4ac 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "4chan-X", - "version": "1.7.63", + "version": "1.8.1", "description": "Cross-browser userscript for maximum lurking on 4chan.", "meta": { "name": "4chan X", diff --git a/src/Filtering/Filter.coffee b/src/Filtering/Filter.coffee index a30767647..c759a8bd7 100755 --- a/src/Filtering/Filter.coffee +++ b/src/Filtering/Filter.coffee @@ -173,7 +173,6 @@ Filter = textContent: 'Filter' entry = - type: 'post' el: div order: 50 open: (post) -> @@ -198,7 +197,7 @@ Filter = # Add a sub entry for each filter type. entry.subEntries.push Filter.menu.createSubEntry type[0], type[1] - $.event 'AddMenuEntry', entry + Menu.menu.addEntry entry createSubEntry: (text, type) -> el = $.el 'a', diff --git a/src/Filtering/PostHiding.coffee b/src/Filtering/PostHiding.coffee index 9c7469d5f..576df9084 100755 --- a/src/Filtering/PostHiding.coffee +++ b/src/Filtering/PostHiding.coffee @@ -39,8 +39,7 @@ PostHiding = replies = UI.checkbox 'replies', ' Hide replies', Conf['Recursive Hiding'] makeStub = UI.checkbox 'makeStub', ' Make stub', Conf['Stubs'] - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: div order: 20 open: (post) -> @@ -75,8 +74,7 @@ PostHiding = href: 'javascript:;' $.on hideStubLink, 'click', PostHiding.menu.hideStub - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: div order: 20 open: (post) -> @@ -96,8 +94,7 @@ PostHiding = el: replies ] - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: hideStubLink order: 15 open: (post) -> diff --git a/src/Filtering/ThreadHiding.coffee b/src/Filtering/ThreadHiding.coffee index c4d1cec6d..e0555b226 100755 --- a/src/Filtering/ThreadHiding.coffee +++ b/src/Filtering/ThreadHiding.coffee @@ -4,7 +4,6 @@ ThreadHiding = @db = new DataBoard 'hiddenThreads' @syncCatalog() - $.on d, 'IndexBuild', @onIndexBuild Thread.callbacks.push name: 'Thread Hiding' cb: @node @@ -15,12 +14,10 @@ ThreadHiding = return unless Conf['Thread Hiding Buttons'] $.prepend @OP.nodes.root, ThreadHiding.makeButton @, 'hide' - onIndexBuild: ({detail: nodes}) -> - for root, i in nodes by 2 + onIndexBuild: (nodes) -> + for root in nodes thread = Get.threadFromRoot root - continue unless thread.isHidden - if thread.stub and root.contains thread.stub - # When we come back to a page, the stub is already there. + if thread.isHidden and thread.stub and !root.contains thread.stub ThreadHiding.makeStub thread, root return @@ -80,8 +77,7 @@ ThreadHiding = makeStub = UI.checkbox 'Stubs', ' Make stub' - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: div order: 20 open: ({thread, isReply}) -> @@ -97,8 +93,7 @@ ThreadHiding = href: 'javascript:;' $.on div, 'click', ThreadHiding.menu.show - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: div order: 20 open: ({thread, isReply}) -> @@ -112,8 +107,7 @@ ThreadHiding = href: 'javascript:;' $.on hideStubLink, 'click', ThreadHiding.menu.hideStub - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: hideStubLink order: 15 open: ({thread, isReply}) -> diff --git a/src/General/Header.coffee b/src/General/Header.coffee index 3980ef86f..3fab91d85 100755 --- a/src/General/Header.coffee +++ b/src/General/Header.coffee @@ -54,8 +54,7 @@ Header = @addShortcut menuButton - $.event 'AddMenuEntry', - type: 'header' + @menu.addEntry el: $.el 'span', textContent: 'Header' order: 107 @@ -427,9 +426,8 @@ Header = Header.menu.toggle e, @, g createNotification: (e) -> - {type, content, lifetime, cb} = e.detail + {type, content, lifetime} = e.detail notice = new Notice type, content, lifetime - cb notice if cb areNotificationsEnabled: false enableDesktopNotifications: -> diff --git a/src/General/Index.coffee b/src/General/Index.coffee index b5948efbb..64981b278 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -55,8 +55,7 @@ Index = when 'Anchor Hidden Threads' $.on input, 'change', @cb.sort - $.event 'AddMenuEntry', - type: 'header' + Header.menu.addEntry el: $.el 'span', textContent: 'Index Navigation' order: 98 @@ -438,11 +437,9 @@ Index = nodes buildStructure: (nodes) -> - result = $.frag() - i = 0 - $.add result, [node, $.el 'hr'] while node = nodes[i++] - $.event 'IndexBuild', result.children - $.add Index.root, result + for node in nodes + $.add Index.root, [node, $.el 'hr'] + ThreadHiding.onIndexBuild nodes isSearching: false diff --git a/src/General/Main.coffee b/src/General/Main.coffee index 684c5a24c..951f523f4 100755 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -78,7 +78,6 @@ Main = # c.timeEnd "#{name} initialization" # c.timeEnd 'All initializations' - $.on d, 'AddCallback', Main.addCallback $.ready Main.initReady initStyle: -> @@ -218,20 +217,6 @@ Main = softTask() - addCallback: (e) -> - obj = e.detail - unless typeof obj.callback.name is 'string' - throw new Error "Invalid callback name: #{obj.callback.name}" - switch obj.type - when 'Post' - Klass = Post - when 'Thread' - Klass = Thread - else - return - obj.callback.isAddon = true - Klass.callbacks.push obj.callback - handleErrors: (errors) -> unless errors instanceof Array error = errors diff --git a/src/General/UI.coffee b/src/General/UI.coffee index 6d3aad8fa..f6cf25223 100755 --- a/src/General/UI.coffee +++ b/src/General/UI.coffee @@ -23,8 +23,10 @@ UI = do -> constructor: (@type) -> # Doc here: https://github.com/MayhemYDG/4chan-x/wiki/Menu-API - $.on d, 'AddMenuEntry', @addEntry - $.on d, 'rmMenuEntry', @rmEntry + $.on d, 'AddMenuEntry', ({detail}) => + return if detail.type isnt @type + delete detail.open + @addEntry detail @entries = [] makeMenu: -> @@ -187,18 +189,10 @@ UI = do -> style.left = left style.right = right - addEntry: (e) => - entry = e.detail - return if entry.type isnt @type + addEntry: (entry) => @parseEntry entry @entries.push entry - rmEntry: (e) => - entry = e.detail - return if entry.type isnt @type - index = @entries.indexOf entry - @entries.splice index, 1 - parseEntry: (entry) -> {el, subEntries} = entry $.addClass el, 'entry' diff --git a/src/General/lib/$.coffee b/src/General/lib/$.coffee index 95aaa593d..083ce408b 100755 --- a/src/General/lib/$.coffee +++ b/src/General/lib/$.coffee @@ -4,10 +4,6 @@ $ = (selector, root=d.body) -> root.querySelector selector -$.extend = (obj, prop) -> - obj[key] = val for key, val of prop when prop.hasOwnProperty key - return - $.DAY = 24 * $.HOUR = 60 * $.MINUTE = 60 * @@ -181,6 +177,10 @@ $.off = (el, events, handler) -> return $.event = (event, detail, root=d) -> + <% if (type === 'userscript') { %> + if detail? and typeof cloneInto is 'function' + detail = cloneInto detail, document.defaultView + <% } %> root.dispatchEvent new CustomEvent event, {bubbles: true, detail} $.open = diff --git a/src/General/lib/callbacks.class b/src/General/lib/callbacks.class index eee6206a3..c8cdeec34 100644 --- a/src/General/lib/callbacks.class +++ b/src/General/lib/callbacks.class @@ -3,17 +3,13 @@ class Callbacks @keys = [] push: ({name, cb}) -> - @connect name if @[name] @keys.push name unless @[name] @[name] = cb - connect: (name) -> delete @[name].disconnected if @[name].disconnected - disconnect: (name) -> @[name].disconnected = true if @[name] - execute: (node) -> for name in @keys try - @[name].call node unless @[name].disconnected + @[name].call node catch err errors = [] unless errors errors.push diff --git a/src/General/lib/databoard.class b/src/General/lib/databoard.class index fec423990..5489e6867 100755 --- a/src/General/lib/databoard.class +++ b/src/General/lib/databoard.class @@ -89,8 +89,3 @@ class DataBoard onSync: (data) => @data = data or boards: {} @sync?() - - disconnect: -> - $.desync @key - delete @sync - delete @data diff --git a/src/Images/FappeTyme.coffee b/src/Images/FappeTyme.coffee index a48b934e8..a46b704aa 100755 --- a/src/Images/FappeTyme.coffee +++ b/src/Images/FappeTyme.coffee @@ -10,8 +10,7 @@ FappeTyme = FappeTyme[lc] = input = el.firstElementChild $.on input, 'change', FappeTyme.cb.toggle.bind input - $.event 'AddMenuEntry', - type: 'header' + Header.menu.addEntry el: el order: 97 diff --git a/src/Images/Gallery.coffee b/src/Images/Gallery.coffee index 83a20a51c..b551ec371 100644 --- a/src/Images/Gallery.coffee +++ b/src/Images/Gallery.coffee @@ -61,8 +61,7 @@ Gallery = for name of Config.gallery {el} = createSubEntry name - $.event 'AddMenuEntry', - type: 'gallery' + nodes.menu.addEntry el: el order: 0 @@ -235,8 +234,7 @@ Gallery = for name of Config.gallery subEntries.push createSubEntry name - $.event 'AddMenuEntry', - type: 'header' + Header.menu.addEntry el: el order: 105 subEntries: subEntries diff --git a/src/Images/ImageExpand.coffee b/src/Images/ImageExpand.coffee index ed523beeb..8a6a6530a 100755 --- a/src/Images/ImageExpand.coffee +++ b/src/Images/ImageExpand.coffee @@ -249,8 +249,7 @@ ImageExpand = for name, conf of Config.imageExpansion subEntries.push createSubEntry name, conf[1] - $.event 'AddMenuEntry', - type: 'header' + Header.menu.addEntry el: el order: 105 subEntries: subEntries diff --git a/src/Images/ImageLoader.coffee b/src/Images/ImageLoader.coffee index d06b747cb..e7190e160 100755 --- a/src/Images/ImageLoader.coffee +++ b/src/Images/ImageLoader.coffee @@ -19,8 +19,7 @@ ImageLoader = @el = prefetch.firstElementChild $.on @el, 'change', @toggle - $.event 'AddMenuEntry', - type: 'header' + Header.menu.addEntry el: prefetch order: 104 diff --git a/src/Menu/ArchiveLink.coffee b/src/Menu/ArchiveLink.coffee index 12b6e507d..05c8192b5 100755 --- a/src/Menu/ArchiveLink.coffee +++ b/src/Menu/ArchiveLink.coffee @@ -6,7 +6,6 @@ ArchiveLink = textContent: 'Archive' entry = - type: 'post' el: div order: 90 open: ({ID, thread, board}) -> @@ -25,7 +24,7 @@ ArchiveLink = # Add a sub entry for each type. entry.subEntries.push @createSubEntry type[0], type[1] - $.event 'AddMenuEntry', entry + Menu.menu.addEntry entry createSubEntry: (text, type) -> el = $.el 'a', @@ -51,4 +50,4 @@ ArchiveLink = return { el: el open: open - } \ No newline at end of file + } diff --git a/src/Menu/DeleteLink.coffee b/src/Menu/DeleteLink.coffee index 1805047f8..32ef589cf 100755 --- a/src/Menu/DeleteLink.coffee +++ b/src/Menu/DeleteLink.coffee @@ -26,8 +26,7 @@ DeleteLink = $.on fileEl, 'click', DeleteLink.delete true - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: div order: 40 open: (post) -> diff --git a/src/Menu/DownloadLink.coffee b/src/Menu/DownloadLink.coffee index 21cc8e9dc..be0abc0e8 100755 --- a/src/Menu/DownloadLink.coffee +++ b/src/Menu/DownloadLink.coffee @@ -17,8 +17,7 @@ DownloadLink = else new Notice 'error', "Could not download #{file.URL}", 30 - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: a order: 100 open: ({file}) -> diff --git a/src/Menu/ReportLink.coffee b/src/Menu/ReportLink.coffee index cebfcd7b5..f1b359ada 100755 --- a/src/Menu/ReportLink.coffee +++ b/src/Menu/ReportLink.coffee @@ -7,8 +7,7 @@ ReportLink = href: 'javascript:;' textContent: 'Report this post' $.on a, 'click', ReportLink.report - $.event 'AddMenuEntry', - type: 'post' + Menu.menu.addEntry el: a order: 10 open: (post) -> @@ -19,4 +18,4 @@ ReportLink = url = "//sys.4chan.org/#{post.board}/imgboard.php?mode=report&no=#{post}" id = Date.now() set = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,resizable=1,width=685,height=200" - window.open url, id, set \ No newline at end of file + window.open url, id, set diff --git a/src/Miscellaneous/AnnouncementHiding.coffee b/src/Miscellaneous/AnnouncementHiding.coffee index b1ac9454c..24ab1eee2 100755 --- a/src/Miscellaneous/AnnouncementHiding.coffee +++ b/src/Miscellaneous/AnnouncementHiding.coffee @@ -12,14 +12,13 @@ PSAHiding = return entry = - type: 'header' el: $.el 'a', textContent: 'Show announcement' className: 'show-announcement' href: 'javascript:;' order: 50 open: -> psa.hidden - $.event 'AddMenuEntry', entry + Header.menu.addEntry entry $.on entry.el, 'click', PSAHiding.toggle PSAHiding.btn = btn = $.el 'span', diff --git a/src/Miscellaneous/CatalogLinks.coffee b/src/Miscellaneous/CatalogLinks.coffee index 9d2afc6e3..635b09043 100755 --- a/src/Miscellaneous/CatalogLinks.coffee +++ b/src/Miscellaneous/CatalogLinks.coffee @@ -8,8 +8,7 @@ CatalogLinks = $.on input, 'change', @toggle $.sync 'Header catalog links', CatalogLinks.set - $.event 'AddMenuEntry', - type: 'header' + Header.menu.addEntry el: el order: 95 diff --git a/src/Miscellaneous/Fourchan.coffee b/src/Miscellaneous/Fourchan.coffee index aaf1317ff..5d5159f51 100755 --- a/src/Miscellaneous/Fourchan.coffee +++ b/src/Miscellaneous/Fourchan.coffee @@ -21,7 +21,7 @@ Fourchan = if (!jsMath) return; if (jsMath.loaded) { // process one post - jsMath.ProcessBeforeShowing(e.detail); + jsMath.ProcessBeforeShowing(document.getElementById(e.detail)); } else if (jsMath.Autoload && jsMath.Autoload.checked) { // load jsMath and process whole document jsMath.Autoload.Script.Push('ProcessBeforeShowing', [null]); @@ -43,7 +43,7 @@ Fourchan = math: -> return if (@isClone and doc.contains @origin.nodes.root) or !$ '.math', @nodes.comment $.asap (=> doc.contains @nodes.post), => - $.event 'jsmath', @nodes.post, window + $.event 'jsmath', @nodes.post.id, window parseThread: (threadID, offset, limit) -> # Fix /sci/ # Fix /g/ diff --git a/src/Monitoring/ThreadExcerpt.coffee b/src/Monitoring/ThreadExcerpt.coffee index 265ea202c..0c3e7e12f 100755 --- a/src/Monitoring/ThreadExcerpt.coffee +++ b/src/Monitoring/ThreadExcerpt.coffee @@ -6,6 +6,3 @@ ThreadExcerpt = name: 'Thread Excerpt' cb: @node node: -> d.title = Get.threadExcerpt @ - disconnect: -> - return if g.VIEW isnt 'thread' or !Conf['Thread Excerpt'] - Thread.callbacks.disconnect 'Thread Excerpt' diff --git a/src/Monitoring/ThreadStats.coffee b/src/Monitoring/ThreadStats.coffee index a4a0866ed..af24dcb5d 100755 --- a/src/Monitoring/ThreadStats.coffee +++ b/src/Monitoring/ThreadStats.coffee @@ -34,26 +34,6 @@ ThreadStats = ThreadStats.update postCount, fileCount $.on d, 'ThreadUpdate', ThreadStats.onUpdate - disconnect: -> - return if g.VIEW isnt 'thread' or !Conf['Thread Stats'] - - if Conf['Updater and Stats in Header'] - Header.rmShortcut @dialog - else - $.rm @dialog - - clearTimeout @timeout # a possible race condition might be that this won't clear in time, but the resulting error will prevent issues anyways. - - delete @timeout - delete @thread - delete @postCountEl - delete @fileCountEl - delete @pageCountEl - delete @dialog - - Thread.callbacks.disconnect 'Thread Stats' - $.off d, 'ThreadUpdate', ThreadStats.onUpdate - onUpdate: (e) -> return if e.detail[404] {postCount, fileCount} = e.detail diff --git a/src/Monitoring/ThreadUpdater.coffee b/src/Monitoring/ThreadUpdater.coffee index 24596e378..e75ab2864 100755 --- a/src/Monitoring/ThreadUpdater.coffee +++ b/src/Monitoring/ThreadUpdater.coffee @@ -52,8 +52,7 @@ ThreadUpdater = subEntries.push el: @settings - $.event 'AddMenuEntry', @entry = - type: 'header' + Header.menu.addEntry @entry = el: $.el 'span', textContent: 'Updater' order: 110 @@ -63,40 +62,6 @@ ThreadUpdater = name: 'Thread Updater' cb: @node - disconnect: -> - return if g.VIEW isnt 'thread' or !Conf['Thread Updater'] - $.off @timer, 'click', @update - $.off @status, 'click', @update - - clearTimeout @timeoutID if @timeoutID - - for entry in @entry.subEntries - {el} = entry - input = el.firstElementChild - $.off input, 'change', $.cb.checked - $.off input, 'change', @cb.scrollBG - $.off input, 'change', @cb.update - - $.off @settings, 'click', @intervalShortcut - $.off window, 'online offline', @cb.online - $.off d, 'QRPostSuccessful', @cb.checkpost - $.off d, 'visibilitychange', @cb.visibility - - @set 'timer', null - @set 'status', 'Offline' - - $.event 'rmMenuEntry', @entry - - if Conf['Updater and Stats in Header'] - Header.rmShortcut @dialog - else - $.rmClass doc, 'float' - $.rm @dialog - - delete @[name] for name in ['checkPostCount', 'timer', 'status', 'isUpdating', 'entry', 'dialog', 'thread', 'root', 'lastPost', 'outdateCount', 'online', 'seconds', 'timeoutID'] - - Thread.callbacks.disconnect 'Thread Updater' - node: -> ThreadUpdater.thread = @ ThreadUpdater.root = @OP.nodes.root.parentNode @@ -173,7 +138,7 @@ ThreadUpdater = ThreadUpdater.thread.kill() $.event 'ThreadUpdate', 404: true - thread: ThreadUpdater.thread + threadID: ThreadUpdater.thread.fullID else ThreadUpdater.outdateCount++ ThreadUpdater.setInterval() @@ -291,9 +256,6 @@ ThreadUpdater = node = Build.postFromObject postObject, ThreadUpdater.thread.board.ID posts.push new Post node, ThreadUpdater.thread, ThreadUpdater.thread.board - deletedPosts = [] - deletedFiles = [] - # Check for deleted posts/files. ThreadUpdater.thread.posts.forEach (post) -> # XXX tmp fix for 4chan's racing condition @@ -303,12 +265,10 @@ ThreadUpdater = unless ID in index post.kill() - deletedPosts.push post else if post.isDead post.resurrect() else if post.file and not (post.file.isDead or ID in files) post.kill true - deletedFiles.push post # Fetching your own posts after posting if ThreadUpdater.postID and ThreadUpdater.postID is ID @@ -353,9 +313,7 @@ ThreadUpdater = $.event 'ThreadUpdate', 404: false - thread: ThreadUpdater.thread - newPosts: posts - deletedPosts: deletedPosts - deletedFiles: deletedFiles + threadID: ThreadUpdater.thread.fullID + newPosts: posts.map (post) -> post.fullID postCount: OP.replies + 1 fileCount: OP.images + (!!ThreadUpdater.thread.OP.file and !ThreadUpdater.thread.OP.file.isDead) diff --git a/src/Monitoring/ThreadWatcher.coffee b/src/Monitoring/ThreadWatcher.coffee index 27706ddd1..f048b4d53 100755 --- a/src/Monitoring/ThreadWatcher.coffee +++ b/src/Monitoring/ThreadWatcher.coffee @@ -15,7 +15,6 @@ ThreadWatcher = @list = @dialog.lastElementChild $.on d, 'QRPostSuccessful', @cb.post - $.on d, 'ThreadUpdate', @cb.threadUpdate if g.VIEW is 'thread' $.on sc, 'click', @toggleWatcher $.on $('.move>.close', ThreadWatcher.dialog), 'click', @toggleWatcher @@ -88,12 +87,12 @@ ThreadWatcher = [boardID, threadID] = @parentNode.dataset.fullID.split '.' ThreadWatcher.rm boardID, +threadID post: (e) -> - {board, postID, threadID} = e.detail + {boardID, threadID, postID} = e.detail if postID is threadID if Conf['Auto Watch'] $.set 'AutoWatch', threadID else if Conf['Auto Watch Reply'] - ThreadWatcher.add board.threads[threadID] + ThreadWatcher.add g.threads[boardID + '.' + threadID] onIndexRefresh: -> {db} = ThreadWatcher boardID = g.BOARD.ID @@ -105,7 +104,7 @@ ThreadWatcher = ThreadWatcher.db.set {boardID, threadID, val: data} ThreadWatcher.refresh() onThreadRefresh: (e) -> - {thread} = e.detail + thread = g.threads[e.detail.threadID] return unless e.detail[404] and ThreadWatcher.db.get {boardID: thread.board.ID, threadID: thread.ID} # Update 404 status. ThreadWatcher.add thread @@ -228,7 +227,7 @@ ThreadWatcher = refreshers: [] init: -> return if !Conf['Thread Watcher'] - menu = new UI.Menu 'thread watcher' + menu = @menu = new UI.Menu 'thread watcher' $.on $('.menu-button', ThreadWatcher.dialog), 'click', (e) -> menu.toggle e, @, ThreadWatcher @addHeaderMenuEntry() @@ -238,8 +237,7 @@ ThreadWatcher = return if g.VIEW isnt 'thread' entryEl = $.el 'a', href: 'javascript:;' - $.event 'AddMenuEntry', - type: 'header' + Header.menu.addEntry el: entryEl order: 60 $.on entryEl, 'click', -> ThreadWatcher.toggle g.threads["#{g.BOARD}.#{g.THREADID}"] @@ -259,7 +257,6 @@ ThreadWatcher = entries.push cb: ThreadWatcher.cb.openAll entry: - type: 'thread watcher' el: $.el 'a', textContent: 'Open all threads' refresh: -> (if ThreadWatcher.list.firstElementChild then $.rmClass else $.addClass) @el, 'disabled' @@ -268,7 +265,6 @@ ThreadWatcher = entries.push cb: ThreadWatcher.cb.checkThreads entry: - type: 'thread watcher' el: $.el 'a', textContent: 'Check 404\'d threads' refresh: -> (if $('div:not(.dead-thread)', ThreadWatcher.list) then $.rmClass else $.addClass) @el, 'disabled' @@ -277,7 +273,6 @@ ThreadWatcher = entries.push cb: ThreadWatcher.cb.pruneDeads entry: - type: 'thread watcher' el: $.el 'a', textContent: 'Prune 404\'d threads' refresh: -> (if $('.dead-thread', ThreadWatcher.list) then $.rmClass else $.addClass) @el, 'disabled' @@ -288,7 +283,6 @@ ThreadWatcher = subEntries.push @createSubEntry name, conf[1] entries.push entry: - type: 'thread watcher' el: $.el 'span', textContent: 'Settings' subEntries: subEntries @@ -297,7 +291,7 @@ ThreadWatcher = entry.el.href = 'javascript:;' if entry.el.nodeName is 'A' $.on entry.el, 'click', cb if cb @refreshers.push refresh.bind entry if refresh - $.event 'AddMenuEntry', entry + @menu.addEntry entry return createSubEntry: (name, desc) -> entry = diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index a201fa930..88c691470 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -12,21 +12,6 @@ Unread = name: 'Unread' cb: @node - disconnect: -> - return if g.VIEW isnt 'thread' or !Conf['Unread Count'] and !Conf['Unread Favicon'] and !Conf['Desktop Notifications'] - - Unread.db.disconnect() - $.rm hr if {hr} = Unread - - delete @[name] for name in ['db', 'hr', 'posts', 'postsQuotingYou', 'thread', 'title', 'lastReadPost'] - - $.off d, '4chanXInitFinished', @ready - $.off d, 'ThreadUpdate', @onUpdate - $.off d, 'scroll visibilitychange', @read - $.off d, 'visibilitychange', @setLine if Conf['Unread Line'] and not Conf['Quote Threading'] - - Thread.callbacks.disconnect 'Unread' - node: -> Unread.thread = @ Unread.title = d.title @@ -129,7 +114,7 @@ Unread = if e.detail[404] Unread.update() else if !QuoteThreading.enabled - Unread.addPosts e.detail.newPosts + Unread.addPosts e.detail.newPosts.map (fullID) -> g.posts[fullID] else Unread.read() Unread.update() diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 28853553c..c9d1dd925 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -72,12 +72,6 @@ QR = $.before $.id('togglePostFormLink'), link - - $.on d, 'QRGetSelectedPost', ({detail: cb}) -> - cb QR.selected - $.on d, 'QRAddPreSubmitHook', ({detail: cb}) -> - QR.preSubmitHooks.push cb - $.on d, 'paste', QR.paste $.on d, 'dragover', QR.dragOver $.on d, 'drop', QR.dropFile @@ -606,8 +600,6 @@ QR = nodes.flag = flag $.add nodes.form, flag - preSubmitHooks: [] - submit: (e) -> e?.preventDefault() @@ -640,9 +632,6 @@ QR = err = 'No file selected.' else if post.file and thread.fileLimit err = 'Max limit of image replies has been reached.' - else for hook in QR.preSubmitHooks - if err = hook post, thread - break if QR.captcha.isEnabled and !err {challenge, response} = QR.captcha.getOne() @@ -793,11 +782,11 @@ QR = # Post/upload confirmed as successful. $.event 'QRPostSuccessful', { - board: g.BOARD + boardID: g.BOARD.ID threadID postID } - $.event 'QRPostSuccessful_', {threadID, postID} + $.event 'QRPostSuccessful_', {boardID: g.BOARD.ID, threadID, postID} # Enable auto-posting if we have stuff left to post, disable it otherwise. postsCount = QR.posts.length - 1 diff --git a/src/Posting/QR.post.coffee b/src/Posting/QR.post.coffee index d52b0021c..d3330299b 100644 --- a/src/Posting/QR.post.coffee +++ b/src/Posting/QR.post.coffee @@ -111,7 +111,6 @@ QR.post = class rectList = @nodes.el.parentNode.getBoundingClientRect() @nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width/2 - rectList.left - rectList.width/2 @load() - $.event 'QRPostSelection', @ load: -> # Load this post's values. diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index baed88332..a54d2cf5d 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -13,8 +13,7 @@ QuoteThreading = input = $ 'input', @controls $.on input, 'change', @toggle - $.event 'AddMenuEntry', @entry = - type: 'header' + Header.menu.addEntry @entry = el: @controls order: 98 @@ -24,19 +23,6 @@ QuoteThreading = name: 'Quote Threading' cb: @node - disconnect: -> - return unless Conf['Quote Threading'] and g.VIEW is 'thread' - input = $ 'input', @controls - $.off input, 'change', @toggle - - $.event 'rmMenuEntry', @entry - - delete @enabled - delete @controls - delete @entry - - Post.callbacks.disconnect 'Quote Threading' - ready: -> $.off d, '4chanXInitFinished', QuoteThreading.ready QuoteThreading.force()