diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js
index 766065368..a7b6dea30 100644
--- a/builds/4chan-X.user.js
+++ b/builds/4chan-X.user.js
@@ -821,7 +821,7 @@
var cb, name;
name = _arg.name, cb = _arg.cb;
if (this[name]) {
- this[name].connect();
+ this.connect(name);
}
if (!this[name]) {
this.keys.push(name);
@@ -829,15 +829,6 @@
return this[name] = cb;
};
- Callbacks.prototype.clean = function() {
- var name, _i, _len, _ref;
- _ref = this.keys;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- name = _ref[_i];
- this.rm(name);
- }
- };
-
Callbacks.prototype.connect = function(name) {
if (this[name]) {
return delete this[name].disconnected;
@@ -1571,7 +1562,9 @@
root.next = item;
item.prev = root;
item.next = next;
- return next.prev = item;
+ if (next) {
+ return next.prev = item;
+ }
};
RandomAccessList.prototype.prepend = function(item) {
@@ -8769,14 +8762,11 @@
ThreadUpdater = {
init: function() {
+ var checked, conf, el, input, name, sc, subEntries, _ref,
+ _this = this;
if (g.VIEW !== 'thread' || !Conf['Thread Updater']) {
return;
}
- return ThreadUpdater.connect.call(this);
- },
- connect: function() {
- var checked, conf, el, input, name, sc, subEntries, _ref,
- _this = this;
if (Conf['Updater and Stats in Header']) {
this.dialog = sc = $.el('span', {
innerHTML: "",
@@ -9672,9 +9662,6 @@
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon'] && !Conf['Desktop Notifications']) {
return;
}
- return Unread.connect.call(this);
- },
- connect: function() {
this.db = new DataBoard('lastReadPosts', this.sync);
this.hr = $.el('hr', {
id: 'unread-line'
@@ -11863,13 +11850,14 @@
g.BOARD.threads = {};
return $.rmAll($('.board'));
},
+ threadFeatures: [['Unread Count', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater]],
disconnect: function() {
var err, errors, feature, features, name, _i, _len, _ref;
- features = g.VIEW === 'thread' ? [['Thread Updater', ThreadUpdater], ['Unread Count', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats]] : [];
+ features = g.VIEW === 'thread' ? Navigate.threadFeatures : [];
for (_i = 0, _len = features.length; _i < _len; _i++) {
_ref = features[_i], name = _ref[0], feature = _ref[1];
try {
- feature.disconnect.call(feature);
+ feature.disconnect();
} catch (_error) {
err = _error;
if (!errors) {
@@ -11885,6 +11873,28 @@
}
}
},
+ reconnect: function() {
+ var err, errors, feature, features, name, _i, _len, _ref;
+ features = g.VIEW === 'thread' ? Navigate.threadFeatures : [];
+ for (_i = 0, _len = features.length; _i < _len; _i++) {
+ _ref = features[_i], name = _ref[0], feature = _ref[1];
+ try {
+ feature.init();
+ } catch (_error) {
+ err = _error;
+ if (!errors) {
+ errors = [];
+ }
+ errors.push({
+ message: "Failed to reconnect feature " + name + ".",
+ error: err
+ });
+ }
+ if (errors) {
+ Main.handleErrors(errors);
+ }
+ }
+ },
updateContext: function(view) {
$.rmClass(doc, g.VIEW);
$.addClass(doc, view);
@@ -11915,6 +11925,7 @@
Navigate.disconnect();
Navigate.clean();
Navigate.updateContext(view);
+ Navigate.reconnect();
}
if (view === 'index') {
if (boardID !== g.BOARD.ID) {
@@ -11944,6 +11955,8 @@
try {
if (req.status === 200) {
Navigate.parse(JSON.parse(req.response).posts);
+ $.on(d, '4chanXInitFinished', Navigate.finish);
+ return $.event('4chanXInitFinished');
}
} catch (_error) {
err = _error;
@@ -11956,8 +11969,10 @@
} else {
new Notice('error', 'Navigation Failed.', 2);
}
- return;
}
+ },
+ finish: function() {
+ $.off(d, '4chanXInitFinished', Navigate.finish);
Navigate.buildThread();
return Header.scrollToIfNeeded($('.board'));
},
diff --git a/builds/crx/script.js b/builds/crx/script.js
index 1b81caf07..af8d46c1b 100644
--- a/builds/crx/script.js
+++ b/builds/crx/script.js
@@ -826,7 +826,7 @@
var cb, name;
name = _arg.name, cb = _arg.cb;
if (this[name]) {
- this[name].connect();
+ this.connect(name);
}
if (!this[name]) {
this.keys.push(name);
@@ -834,15 +834,6 @@
return this[name] = cb;
};
- Callbacks.prototype.clean = function() {
- var name, _i, _len, _ref;
- _ref = this.keys;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- name = _ref[_i];
- this.rm(name);
- }
- };
-
Callbacks.prototype.connect = function(name) {
if (this[name]) {
return delete this[name].disconnected;
@@ -1577,7 +1568,9 @@
root.next = item;
item.prev = root;
item.next = next;
- return next.prev = item;
+ if (next) {
+ return next.prev = item;
+ }
};
RandomAccessList.prototype.prepend = function(item) {
@@ -8752,14 +8745,11 @@
ThreadUpdater = {
init: function() {
+ var checked, conf, el, input, name, sc, subEntries, _ref,
+ _this = this;
if (g.VIEW !== 'thread' || !Conf['Thread Updater']) {
return;
}
- return ThreadUpdater.connect.call(this);
- },
- connect: function() {
- var checked, conf, el, input, name, sc, subEntries, _ref,
- _this = this;
if (Conf['Updater and Stats in Header']) {
this.dialog = sc = $.el('span', {
innerHTML: "",
@@ -9655,9 +9645,6 @@
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon'] && !Conf['Desktop Notifications']) {
return;
}
- return Unread.connect.call(this);
- },
- connect: function() {
this.db = new DataBoard('lastReadPosts', this.sync);
this.hr = $.el('hr', {
id: 'unread-line'
@@ -11852,13 +11839,14 @@
g.BOARD.threads = {};
return $.rmAll($('.board'));
},
+ threadFeatures: [['Unread Count', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater]],
disconnect: function() {
var err, errors, feature, features, name, _i, _len, _ref;
- features = g.VIEW === 'thread' ? [['Thread Updater', ThreadUpdater], ['Unread Count', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats]] : [];
+ features = g.VIEW === 'thread' ? Navigate.threadFeatures : [];
for (_i = 0, _len = features.length; _i < _len; _i++) {
_ref = features[_i], name = _ref[0], feature = _ref[1];
try {
- feature.disconnect.call(feature);
+ feature.disconnect();
} catch (_error) {
err = _error;
if (!errors) {
@@ -11874,6 +11862,28 @@
}
}
},
+ reconnect: function() {
+ var err, errors, feature, features, name, _i, _len, _ref;
+ features = g.VIEW === 'thread' ? Navigate.threadFeatures : [];
+ for (_i = 0, _len = features.length; _i < _len; _i++) {
+ _ref = features[_i], name = _ref[0], feature = _ref[1];
+ try {
+ feature.init();
+ } catch (_error) {
+ err = _error;
+ if (!errors) {
+ errors = [];
+ }
+ errors.push({
+ message: "Failed to reconnect feature " + name + ".",
+ error: err
+ });
+ }
+ if (errors) {
+ Main.handleErrors(errors);
+ }
+ }
+ },
updateContext: function(view) {
$.rmClass(doc, g.VIEW);
$.addClass(doc, view);
@@ -11904,6 +11914,7 @@
Navigate.disconnect();
Navigate.clean();
Navigate.updateContext(view);
+ Navigate.reconnect();
}
if (view === 'index') {
if (boardID !== g.BOARD.ID) {
@@ -11933,6 +11944,8 @@
try {
if (req.status === 200) {
Navigate.parse(JSON.parse(req.response).posts);
+ $.on(d, '4chanXInitFinished', Navigate.finish);
+ return $.event('4chanXInitFinished');
}
} catch (_error) {
err = _error;
@@ -11945,8 +11958,10 @@
} else {
new Notice('error', 'Navigation Failed.', 2);
}
- return;
}
+ },
+ finish: function() {
+ $.off(d, '4chanXInitFinished', Navigate.finish);
Navigate.buildThread();
return Header.scrollToIfNeeded($('.board'));
},
diff --git a/src/General/Navigate.coffee b/src/General/Navigate.coffee
index 548fa2f90..894f6ea9e 100644
--- a/src/General/Navigate.coffee
+++ b/src/General/Navigate.coffee
@@ -34,20 +34,22 @@ Navigate =
# Delete nodes
$.rmAll $ '.board'
+ threadFeatures: [
+ ['Unread Count', Unread]
+ ['Quote Threading', QuoteThreading]
+ ['Thread Stats', ThreadStats]
+ ['Thread Updater', ThreadUpdater]
+ ]
+
disconnect: ->
features = if g.VIEW is 'thread'
- [
- ['Thread Updater', ThreadUpdater]
- ['Unread Count', Unread]
- ['Quote Threading', QuoteThreading]
- ['Thread Stats', ThreadStats]
- ]
+ Navigate.threadFeatures
else
[]
for [name, feature] in features
try
- feature.disconnect.call feature
+ feature.disconnect()
catch err
errors = [] unless errors
errors.push
@@ -58,6 +60,25 @@ Navigate =
return
+ reconnect: ->
+ features = if g.VIEW is 'thread'
+ Navigate.threadFeatures
+ else
+ []
+
+ for [name, feature] in features
+ try
+ feature.init()
+ catch err
+ errors = [] unless errors
+ errors.push
+ message: "Failed to reconnect feature #{name}."
+ error: err
+
+ Main.handleErrors errors if errors
+
+ return
+
updateContext: (view) ->
$.rmClass doc, g.VIEW
$.addClass doc, view
@@ -85,6 +106,7 @@ Navigate =
Navigate.disconnect()
Navigate.clean()
Navigate.updateContext view
+ Navigate.reconnect()
if view is 'index'
Navigate.updateBoard boardID unless boardID is g.BOARD.ID
@@ -112,6 +134,8 @@ Navigate =
try
if req.status is 200
Navigate.parse JSON.parse(req.response).posts
+ $.on d, '4chanXInitFinished', Navigate.finish
+ $.event '4chanXInitFinished'
catch err
console.error 'Navigate failure:'
console.log err
@@ -123,9 +147,10 @@ Navigate =
else
new Notice 'error', 'Navigation Failed.', 2
return
-
+
+ finish: ->
+ $.off d, '4chanXInitFinished', Navigate.finish
Navigate.buildThread()
-
Header.scrollToIfNeeded $ '.board'
parse: (data) ->
diff --git a/src/General/lib/callbacks.class b/src/General/lib/callbacks.class
index 4ac1e43ed..32a677896 100644
--- a/src/General/lib/callbacks.class
+++ b/src/General/lib/callbacks.class
@@ -3,14 +3,10 @@ class Callbacks
@keys = []
push: ({name, cb}) ->
- @[name].connect() if @[name]
+ @connect name if @[name]
@keys.push name unless @[name]
@[name] = cb
- clean: ->
- @rm name for name in @keys
- return
-
connect: (name) -> delete @[name].disconnected if @[name]
disconnect: (name) -> @[name].disconnected = true if @[name]
diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class
index 0cc754d60..e16e57204 100644
--- a/src/General/lib/randomaccesslist.class
+++ b/src/General/lib/randomaccesslist.class
@@ -23,7 +23,7 @@ class RandomAccessList
root.next = item
item.prev = root
item.next = next
- next.prev = item
+ next.prev = item if next
prepend: (item) ->
{first} = @
diff --git a/src/Monitoring/ThreadUpdater.coffee b/src/Monitoring/ThreadUpdater.coffee
index 6b34c8e32..5e38a7b2e 100755
--- a/src/Monitoring/ThreadUpdater.coffee
+++ b/src/Monitoring/ThreadUpdater.coffee
@@ -1,10 +1,7 @@
ThreadUpdater =
init: ->
return if g.VIEW isnt 'thread' or !Conf['Thread Updater']
-
- ThreadUpdater.connect.call @
- connect: ->
if Conf['Updater and Stats in Header']
@dialog = sc = $.el 'span',
innerHTML: ""
diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee
index 9b4c45663..b5d78772b 100755
--- a/src/Monitoring/Unread.coffee
+++ b/src/Monitoring/Unread.coffee
@@ -2,9 +2,6 @@ Unread =
init: ->
return if g.VIEW isnt 'thread' or !Conf['Unread Count'] and !Conf['Unread Favicon'] and !Conf['Desktop Notifications']
- Unread.connect.call this
-
- connect: ->
@db = new DataBoard 'lastReadPosts', @sync
@hr = $.el 'hr',
id: 'unread-line'
diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee
index 6dab23d26..def25578f 100755
--- a/src/Quotelinks/QuoteThreading.coffee
+++ b/src/Quotelinks/QuoteThreading.coffee
@@ -23,17 +23,17 @@ QuoteThreading =
Post.callbacks.push
name: 'Quote Threading'
cb: @node
-
+
disconnect: ->
input = $ 'input', @controls
$.off input, 'change', @toggle
-
+
$.event 'rmMenuEntry', @entry
-
+
delete @enabled
delete @controls
delete @entry
-
+
Post.callbacks.disconnect 'Quote Threading'
setup: ->
@@ -115,7 +115,7 @@ QuoteThreading =
containers = $$ '.threadContainer', thread
$.rm container for container in containers
$.rmClass post, 'threadOP' for post in $$ '.threadOP'
-
+
return
kb: ->