More fixes
Still no header or posts, but no errors either. :D
This commit is contained in:
parent
872612ad9f
commit
54c5b59946
@ -3872,15 +3872,22 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
DataBoard.prototype["delete"] = function(_arg) {
|
DataBoard.prototype["delete"] = function(_arg) {
|
||||||
var boardID, postID, threadID;
|
var boardID, postID, threadID, _ref;
|
||||||
boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID;
|
boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID;
|
||||||
|
$.forceSync(this.key);
|
||||||
if (postID) {
|
if (postID) {
|
||||||
|
if (!((_ref = this.data.boards[boardID]) != null ? _ref[threadID] : void 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
delete this.data.boards[boardID][threadID][postID];
|
delete this.data.boards[boardID][threadID][postID];
|
||||||
this.deleteIfEmpty({
|
this.deleteIfEmpty({
|
||||||
boardID: boardID,
|
boardID: boardID,
|
||||||
threadID: threadID
|
threadID: threadID
|
||||||
});
|
});
|
||||||
} else if (threadID) {
|
} else if (threadID) {
|
||||||
|
if (!this.data.boards[boardID]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
delete this.data.boards[boardID][threadID];
|
delete this.data.boards[boardID][threadID];
|
||||||
this.deleteIfEmpty({
|
this.deleteIfEmpty({
|
||||||
boardID: boardID
|
boardID: boardID
|
||||||
@ -3894,6 +3901,7 @@
|
|||||||
DataBoard.prototype.deleteIfEmpty = function(_arg) {
|
DataBoard.prototype.deleteIfEmpty = function(_arg) {
|
||||||
var boardID, threadID;
|
var boardID, threadID;
|
||||||
boardID = _arg.boardID, threadID = _arg.threadID;
|
boardID = _arg.boardID, threadID = _arg.threadID;
|
||||||
|
$.forceSync(this.key);
|
||||||
if (threadID) {
|
if (threadID) {
|
||||||
if (!Object.keys(this.data.boards[boardID][threadID]).length) {
|
if (!Object.keys(this.data.boards[boardID][threadID]).length) {
|
||||||
delete this.data.boards[boardID][threadID];
|
delete this.data.boards[boardID][threadID];
|
||||||
@ -3909,6 +3917,7 @@
|
|||||||
DataBoard.prototype.set = function(_arg) {
|
DataBoard.prototype.set = function(_arg) {
|
||||||
var boardID, postID, threadID, val, _base, _base1, _base2;
|
var boardID, postID, threadID, val, _base, _base1, _base2;
|
||||||
boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, val = _arg.val;
|
boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, val = _arg.val;
|
||||||
|
$.forceSync(this.key);
|
||||||
if (postID !== void 0) {
|
if (postID !== void 0) {
|
||||||
((_base = ((_base1 = this.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[postID] = val;
|
((_base = ((_base1 = this.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[postID] = val;
|
||||||
} else if (threadID !== void 0) {
|
} else if (threadID !== void 0) {
|
||||||
@ -3942,70 +3951,47 @@
|
|||||||
return val || defaultValue;
|
return val || defaultValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DataBoard.prototype.forceSync = function() {
|
||||||
|
return $.forceSync(this.key);
|
||||||
|
};
|
||||||
|
|
||||||
DataBoard.prototype.clean = function() {
|
DataBoard.prototype.clean = function() {
|
||||||
var boardID, keys, now, _i, _len;
|
var boardID, now, threadID, val, _ref;
|
||||||
now = Date.now();
|
$.forceSync(this.key);
|
||||||
if ((this.data.lastChecked || 0) > now - 2 * $.HOUR) {
|
_ref = this.data.boards;
|
||||||
return;
|
for (boardID in _ref) {
|
||||||
}
|
val = _ref[boardID];
|
||||||
keys = Object.keys(this.data.boards);
|
|
||||||
if (!keys.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
|
||||||
boardID = keys[_i];
|
|
||||||
this.deleteIfEmpty({
|
this.deleteIfEmpty({
|
||||||
boardID: boardID
|
boardID: boardID
|
||||||
});
|
});
|
||||||
if (boardID in this.data.boards) {
|
}
|
||||||
this.ajaxClean(boardID);
|
now = Date.now();
|
||||||
|
if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
|
||||||
|
this.data.lastChecked = now;
|
||||||
|
for (boardID in this.data.boards) {
|
||||||
|
for (threadID in this.data.boards[boardID]) {
|
||||||
|
this.ajaxClean(boardID, threadID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.data.lastChecked = now;
|
|
||||||
return this.save();
|
return this.save();
|
||||||
};
|
};
|
||||||
|
|
||||||
DataBoard.prototype.ajaxClean = function(boardID) {
|
DataBoard.prototype.ajaxClean = function(boardID, threadID) {
|
||||||
return $.cache("//a.4cdn.org/" + boardID + "/threads.json", (function(_this) {
|
return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
|
||||||
return function(e) {
|
onloadend: (function(_this) {
|
||||||
var board, count, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1;
|
return function(e) {
|
||||||
if (e.target.status !== 200) {
|
|
||||||
if (e.target.status === 404) {
|
if (e.target.status === 404) {
|
||||||
_this["delete"]({
|
return _this["delete"]({
|
||||||
boardID: boardID
|
boardID: boardID,
|
||||||
|
threadID: threadID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
};
|
||||||
}
|
})(this)
|
||||||
board = _this.data.boards[boardID];
|
}, {
|
||||||
threads = {};
|
type: 'head'
|
||||||
_ref = e.target.response;
|
});
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
page = _ref[_i];
|
|
||||||
_ref1 = page.threads;
|
|
||||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
|
||||||
thread = _ref1[_j];
|
|
||||||
if (thread.no in board) {
|
|
||||||
threads[thread.no] = board[thread.no];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
count = Object.keys(threads).length;
|
|
||||||
if (count === Object.keys(board).length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (count) {
|
|
||||||
return _this.set({
|
|
||||||
boardID: boardID,
|
|
||||||
val: threads
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return _this["delete"]({
|
|
||||||
boardID: boardID
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})(this));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DataBoard.prototype.onSync = function(data) {
|
DataBoard.prototype.onSync = function(data) {
|
||||||
@ -4053,7 +4039,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.off(d, 'visibilitychange', this.add);
|
$.off(d, 'visibilitychange', this.add);
|
||||||
$.add(Header.noticesRoot, this.el);
|
$.add(doc, this.el);
|
||||||
this.el.clientHeight;
|
this.el.clientHeight;
|
||||||
this.el.style.opacity = 1;
|
this.el.style.opacity = 1;
|
||||||
if (this.timeout) {
|
if (this.timeout) {
|
||||||
@ -4319,7 +4305,7 @@
|
|||||||
className: 'menu-button a-icon',
|
className: 'menu-button a-icon',
|
||||||
id: 'main-menu'
|
id: 'main-menu'
|
||||||
});
|
});
|
||||||
box = UI.checkbox.bind(UI);
|
box = UI.checkbox;
|
||||||
barFixedToggler = box('Fixed Header', 'Fixed Header');
|
barFixedToggler = box('Fixed Header', 'Fixed Header');
|
||||||
headerToggler = box('Header auto-hide', ' Auto-hide header');
|
headerToggler = box('Header auto-hide', ' Auto-hide header');
|
||||||
scrollHeaderToggler = box('Header auto-hide on scroll', ' Auto-hide header on scroll');
|
scrollHeaderToggler = box('Header auto-hide on scroll', ' Auto-hide header on scroll');
|
||||||
@ -6211,43 +6197,21 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* File Info */
|
/* File Info */
|
||||||
if (file != null ? file.isDeleted : void 0) {
|
fileCont = (file != null ? file.isDeleted : void 0) ? {
|
||||||
fileCont = {
|
innerHTML: "<span class=\"fileThumb\"><img src=\"" + E(staticPath) + "filedeleted-res" + E(gifIcon) + "\" alt=\"File deleted.\" class=\"fileDeletedRes retina\"></span>"
|
||||||
innerHTML: "<span class=\"fileThumb\"><img src=\"" + E(staticPath) + "filedeleted-res" + E(gifIcon) + "\" alt=\"File deleted.\" class=\"fileDeletedRes retina\"></span>"
|
} : file && boardID === 'f' ? {
|
||||||
};
|
innerHTML: "<div class=\"fileInfo\"><span class=\"fileText\" id=\"fT" + E(postID) + "\">File: <a data-width=\"" + E(file.width) + "\" data-height=\"" + E(file.height) + "\" href=\"" + E(file.url) + "\" target=\"_blank\">" + E(file.name) + "</a>-(" + E($.bytesToString(file.size)) + ", " + E(file.width) + "x" + E(file.height) + ", " + E(file.tag) + ")</span></div>"
|
||||||
} else if (file && boardID === 'f') {
|
} : file ? (file.isSpoiler ? (shortFilename = 'Spoiler Image', (spoilerRange = Build.spoilerRange[boardID]) ? fileThumb = "//s.4cdn.org/image/spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png" : fileThumb = '//s.4cdn.org/image/spoiler.png', file.twidth = file.theight = 100) : (shortFilename = Build.shortFilename(file.name, !isOP), fileThumb = file.turl), fileSize = $.bytesToString(file.size), fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : "" + file.width + "x" + file.height, fileLink = file.isSpoiler || file.name === shortFilename ? {
|
||||||
fileCont = {
|
innerHTML: "<a href=\"" + E(file.url) + "\" target=\"_blank\">" + E(shortFilename) + "</a>"
|
||||||
innerHTML: "<div class=\"fileInfo\"><span class=\"fileText\" id=\"fT" + E(postID) + "\">File: <a data-width=\"" + E(file.width) + "\" data-height=\"" + E(file.height) + "\" href=\"" + E(file.url) + "\" target=\"_blank\">" + E(file.name) + "</a>-(" + E($.bytesToString(file.size)) + ", " + E(file.width) + "x" + E(file.height) + ", " + E(file.tag) + ")</span></div>"
|
} : {
|
||||||
};
|
innerHTML: "<a title=\"" + E(file.name) + "\" href=\"" + E(file.url) + "\" target=\"_blank\">" + E(shortFilename) + "</a>"
|
||||||
} else if (file) {
|
}, fileText = file.isSpoiler ? {
|
||||||
if (file.isSpoiler) {
|
innerHTML: "<div class=\"fileText\" id=\"fT" + E(postID) + "\" title=\"" + E(file.name) + "\">File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")</div>"
|
||||||
shortFilename = 'Spoiler Image';
|
} : {
|
||||||
if (spoilerRange = Build.spoilerRange[boardID]) {
|
innerHTML: "<div class=\"fileText\" id=\"fT" + E(postID) + "\">File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")</div>"
|
||||||
fileThumb = "//s.4cdn.org/image/spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png";
|
}, {
|
||||||
} else {
|
innerHTML: fileText.innerHTML + "<a class=\"fileThumb" + E(file.isSpoiler ? " imgspoiler" : "") + "\" href=\"" + E(file.url) + "\" target=\"_blank\"><img src=\"" + E(fileThumb) + "\" alt=\"" + E(fileSize) + "\" data-md5=\"" + E(file.MD5) + "\" style=\"height: " + E(file.theight) + "px; width: " + E(file.twidth) + "px;\"></a>"
|
||||||
fileThumb = '//s.4cdn.org/image/spoiler.png';
|
}) : void 0;
|
||||||
}
|
|
||||||
file.twidth = file.theight = 100;
|
|
||||||
} else {
|
|
||||||
shortFilename = Build.shortFilename(file.name, !isOP);
|
|
||||||
fileThumb = file.turl;
|
|
||||||
}
|
|
||||||
fileSize = $.bytesToString(file.size);
|
|
||||||
fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : "" + file.width + "x" + file.height;
|
|
||||||
fileLink = file.isSpoiler || file.name === shortFilename ? {
|
|
||||||
innerHTML: "<a href=\"" + E(file.url) + "\" target=\"_blank\">" + E(shortFilename) + "</a>"
|
|
||||||
} : {
|
|
||||||
innerHTML: "<a title=\"" + E(file.name) + "\" href=\"" + E(file.url) + "\" target=\"_blank\">" + E(shortFilename) + "</a>"
|
|
||||||
};
|
|
||||||
fileText = file.isSpoiler ? {
|
|
||||||
innerHTML: "<div class=\"fileText\" id=\"fT" + E(postID) + "\" title=\"" + E(file.name) + "\">File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")</div>"
|
|
||||||
} : {
|
|
||||||
innerHTML: "<div class=\"fileText\" id=\"fT" + E(postID) + "\">File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")</div>"
|
|
||||||
};
|
|
||||||
({
|
|
||||||
innerHTML: fileText.innerHTML + "<a class=\"fileThumb" + E(file.isSpoiler ? " imgspoiler" : "") + "\" href=\"" + E(file.url) + "\" target=\"_blank\"><img src=\"" + E(fileThumb) + "\" alt=\"" + E(fileSize) + "\" data-md5=\"" + E(file.MD5) + "\" style=\"height: " + E(file.theight) + "px; width: " + E(file.twidth) + "px;\"></a>"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
fileBlock = file ? {
|
fileBlock = file ? {
|
||||||
innerHTML: "<div class=\"file\" id=\"f" + E(postID) + "\">" + fileCont.innerHTML + "</div>"
|
innerHTML: "<div class=\"file\" id=\"f" + E(postID) + "\">" + fileCont.innerHTML + "</div>"
|
||||||
} : {
|
} : {
|
||||||
@ -6765,20 +6729,30 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
UI = (function() {
|
UI = (function() {
|
||||||
var Menu, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove;
|
var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove;
|
||||||
dialog = function(id, position, html) {
|
dialog = function(id, position, properties) {
|
||||||
var el, move;
|
var child, el, move, _i, _len, _ref;
|
||||||
el = $.el('div', {
|
el = $.el('div', {
|
||||||
className: 'dialog',
|
className: 'dialog',
|
||||||
innerHTML: html,
|
|
||||||
id: id
|
id: id
|
||||||
});
|
});
|
||||||
|
$.extend(el, properties);
|
||||||
el.style.cssText = position;
|
el.style.cssText = position;
|
||||||
$.get("" + id + ".position", position, function(item) {
|
$.get("" + id + ".position", position, function(item) {
|
||||||
return el.style.cssText = item["" + id + ".position"];
|
return el.style.cssText = item["" + id + ".position"];
|
||||||
});
|
});
|
||||||
move = $('.move', el);
|
move = $('.move', el);
|
||||||
$.on(move, 'touchstart mousedown', dragstart);
|
$.on(move, 'touchstart mousedown', dragstart);
|
||||||
|
_ref = move.children;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
child = _ref[_i];
|
||||||
|
if (!child.tagName) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$.on(child, 'touchstart mousedown', function(e) {
|
||||||
|
return e.stopPropagation();
|
||||||
|
});
|
||||||
|
}
|
||||||
return el;
|
return el;
|
||||||
};
|
};
|
||||||
Menu = (function() {
|
Menu = (function() {
|
||||||
@ -6788,11 +6762,24 @@
|
|||||||
|
|
||||||
lastToggledButton = null;
|
lastToggledButton = null;
|
||||||
|
|
||||||
function Menu() {
|
function Menu(type) {
|
||||||
|
this.type = type;
|
||||||
this.rmEntry = __bind(this.rmEntry, this);
|
this.rmEntry = __bind(this.rmEntry, this);
|
||||||
|
this.addEntry = __bind(this.addEntry, this);
|
||||||
this.onFocus = __bind(this.onFocus, this);
|
this.onFocus = __bind(this.onFocus, this);
|
||||||
this.keybinds = __bind(this.keybinds, this);
|
this.keybinds = __bind(this.keybinds, this);
|
||||||
this.close = __bind(this.close, this);
|
this.close = __bind(this.close, this);
|
||||||
|
$.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 = [];
|
this.entries = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6832,7 +6819,6 @@
|
|||||||
menu = this.makeMenu();
|
menu = this.makeMenu();
|
||||||
currentMenu = menu;
|
currentMenu = menu;
|
||||||
lastToggledButton = button;
|
lastToggledButton = button;
|
||||||
$.addClass(button, 'open');
|
|
||||||
this.entries.sort(function(first, second) {
|
this.entries.sort(function(first, second) {
|
||||||
return first.order - second.order;
|
return first.order - second.order;
|
||||||
});
|
});
|
||||||
@ -6870,12 +6856,7 @@
|
|||||||
Menu.prototype.insertEntry = function(entry, parent, data) {
|
Menu.prototype.insertEntry = function(entry, parent, data) {
|
||||||
var subEntry, submenu, _i, _len, _ref;
|
var subEntry, submenu, _i, _len, _ref;
|
||||||
if (typeof entry.open === 'function') {
|
if (typeof entry.open === 'function') {
|
||||||
if (!entry.open(data, (function(_this) {
|
if (!entry.open(data)) {
|
||||||
return function(subEntry) {
|
|
||||||
_this.parseEntry(subEntry);
|
|
||||||
return entry.subEntries.push(subEntry);
|
|
||||||
};
|
|
||||||
})(this))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6899,7 +6880,7 @@
|
|||||||
|
|
||||||
Menu.prototype.close = function() {
|
Menu.prototype.close = function() {
|
||||||
$.rm(currentMenu);
|
$.rm(currentMenu);
|
||||||
$.rmClass(lastToggledButton, 'open');
|
$.rmClass(lastToggledButton, 'active');
|
||||||
currentMenu = null;
|
currentMenu = null;
|
||||||
lastToggledButton = null;
|
lastToggledButton = null;
|
||||||
return $.off(d, 'click CloseMenu', this.close);
|
return $.off(d, 'click CloseMenu', this.close);
|
||||||
@ -7014,7 +6995,6 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.addClass(el, 'has-submenu');
|
$.addClass(el, 'has-submenu');
|
||||||
$.addClass(el, 'pfa');
|
|
||||||
for (_i = 0, _len = subEntries.length; _i < _len; _i++) {
|
for (_i = 0, _len = subEntries.length; _i < _len; _i++) {
|
||||||
subEntry = subEntries[_i];
|
subEntry = subEntries[_i];
|
||||||
this.parseEntry(subEntry);
|
this.parseEntry(subEntry);
|
||||||
@ -7025,13 +7005,13 @@
|
|||||||
|
|
||||||
})();
|
})();
|
||||||
dragstart = function(e) {
|
dragstart = function(e) {
|
||||||
var el, isTouching, o, rect, screenHeight, screenWidth, _ref, _ref1;
|
var el, isTouching, o, rect, screenHeight, screenWidth, _ref;
|
||||||
if (e.type === 'mousedown' && e.button !== 0) {
|
if (e.type === 'mousedown' && e.button !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (isTouching = e.type === 'touchstart') {
|
if (isTouching = e.type === 'touchstart') {
|
||||||
_ref = e.changedTouches, e = _ref[_ref.length - 1];
|
e = e.changedTouches[e.changedTouches.length - 1];
|
||||||
}
|
}
|
||||||
el = $.x('ancestor::div[contains(@class,"dialog")][1]', this);
|
el = $.x('ancestor::div[contains(@class,"dialog")][1]', this);
|
||||||
rect = el.getBoundingClientRect();
|
rect = el.getBoundingClientRect();
|
||||||
@ -7048,7 +7028,7 @@
|
|||||||
screenWidth: screenWidth,
|
screenWidth: screenWidth,
|
||||||
isTouching: isTouching
|
isTouching: isTouching
|
||||||
};
|
};
|
||||||
_ref1 = Conf['Header auto-hide'] || !Conf['Fixed Header'] ? [0, 0] : Conf['Bottom Header'] ? [0, Header.bar.getBoundingClientRect().height] : [Header.bar.getBoundingClientRect().height, 0], o.topBorder = _ref1[0], o.bottomBorder = _ref1[1];
|
_ref = Conf['Header auto-hide'] || !Conf['Fixed Header'] ? [0, 0] : Conf['Bottom Header'] ? [0, Header.bar.getBoundingClientRect().height] : [Header.bar.getBoundingClientRect().height, 0], o.topBorder = _ref[0], o.bottomBorder = _ref[1];
|
||||||
if (isTouching) {
|
if (isTouching) {
|
||||||
o.identifier = e.identifier;
|
o.identifier = e.identifier;
|
||||||
o.move = touchmove.bind(o);
|
o.move = touchmove.bind(o);
|
||||||
@ -7110,33 +7090,29 @@
|
|||||||
return $.set("" + this.id + ".position", this.style.cssText);
|
return $.set("" + this.id + ".position", this.style.cssText);
|
||||||
};
|
};
|
||||||
hoverstart = function(_arg) {
|
hoverstart = function(_arg) {
|
||||||
var asapTest, cb, el, endEvents, latestEvent, noRemove, o, offsetX, offsetY, root;
|
var asapTest, cb, el, endEvents, height, latestEvent, noRemove, o, root, _ref;
|
||||||
root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, cb = _arg.cb, offsetX = _arg.offsetX, offsetY = _arg.offsetY, noRemove = _arg.noRemove;
|
root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, height = _arg.height, cb = _arg.cb, noRemove = _arg.noRemove;
|
||||||
o = {
|
o = {
|
||||||
root: root,
|
root: root,
|
||||||
el: el,
|
el: el,
|
||||||
style: el.style,
|
style: el.style,
|
||||||
|
isImage: (_ref = el.nodeName) === 'IMG' || _ref === 'VIDEO',
|
||||||
cb: cb,
|
cb: cb,
|
||||||
close: close,
|
|
||||||
endEvents: endEvents,
|
endEvents: endEvents,
|
||||||
latestEvent: latestEvent,
|
latestEvent: latestEvent,
|
||||||
clientHeight: doc.clientHeight,
|
clientHeight: doc.clientHeight,
|
||||||
clientWidth: doc.clientWidth,
|
clientWidth: doc.clientWidth,
|
||||||
offsetX: offsetX || 45,
|
|
||||||
offsetY: offsetY || -120,
|
|
||||||
noRemove: noRemove
|
noRemove: noRemove
|
||||||
};
|
};
|
||||||
o.hover = hover.bind(o);
|
o.hover = hover.bind(o);
|
||||||
o.hoverend = hoverend.bind(o);
|
o.hoverend = hoverend.bind(o);
|
||||||
if (asapTest) {
|
$.asap(function() {
|
||||||
$.asap(function() {
|
return !el.parentNode || asapTest();
|
||||||
return !el.parentNode || asapTest();
|
}, function() {
|
||||||
}, function() {
|
if (el.parentNode) {
|
||||||
if (el.parentNode) {
|
return o.hover(o.latestEvent);
|
||||||
return o.hover(o.latestEvent);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
$.on(root, endEvents, o.hoverend);
|
$.on(root, endEvents, o.hoverend);
|
||||||
if ($.x('ancestor::div[contains(@class,"inline")][1]', root)) {
|
if ($.x('ancestor::div[contains(@class,"inline")][1]', root)) {
|
||||||
$.on(d, 'keydown', o.hoverend);
|
$.on(d, 'keydown', o.hoverend);
|
||||||
@ -7150,22 +7126,28 @@
|
|||||||
return $.on(doc, 'mousemove', o.workaround);
|
return $.on(doc, 'mousemove', o.workaround);
|
||||||
};
|
};
|
||||||
hover = function(e) {
|
hover = function(e) {
|
||||||
var clientX, clientY, height, left, right, top, _ref;
|
var clientX, clientY, height, left, right, style, threshold, top, _ref;
|
||||||
this.latestEvent = e;
|
this.latestEvent = e;
|
||||||
height = this.el.offsetHeight + 25;
|
height = this.height || this.el.offsetHeight;
|
||||||
clientX = e.clientX, clientY = e.clientY;
|
clientX = e.clientX, clientY = e.clientY;
|
||||||
top = clientY + this.offsetY;
|
top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120));
|
||||||
top = this.clientHeight <= height || top <= 0 ? 0 : top + height >= this.clientHeight ? this.clientHeight - height : top;
|
threshold = this.clientWidth / 2;
|
||||||
_ref = clientX <= this.clientWidth / 2 ? [clientX + this.offsetX + 'px', null] : [null, this.clientWidth - clientX + this.offsetX + 'px'], left = _ref[0], right = _ref[1];
|
if (!this.isImage) {
|
||||||
this.style.top = top + 'px';
|
threshold = Math.max(threshold, this.clientWidth - 400);
|
||||||
this.style.left = left;
|
}
|
||||||
return this.style.right = right;
|
_ref = clientX <= threshold ? [clientX + 45 + 'px', null] : [null, this.clientWidth - clientX + 45 + 'px'], left = _ref[0], right = _ref[1];
|
||||||
|
style = this.style;
|
||||||
|
style.top = top + 'px';
|
||||||
|
style.left = left;
|
||||||
|
return style.right = right;
|
||||||
};
|
};
|
||||||
hoverend = function(e) {
|
hoverend = function(e) {
|
||||||
if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") {
|
if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.rm(this.el);
|
if (!this.noRemove) {
|
||||||
|
$.rm(this.el);
|
||||||
|
}
|
||||||
$.off(this.root, this.endEvents, this.hoverend);
|
$.off(this.root, this.endEvents, this.hoverend);
|
||||||
$.off(d, 'keydown', this.hoverend);
|
$.off(d, 'keydown', this.hoverend);
|
||||||
$.off(this.root, 'mousemove', this.hover);
|
$.off(this.root, 'mousemove', this.hover);
|
||||||
@ -7174,10 +7156,25 @@
|
|||||||
return this.cb.call(this);
|
return this.cb.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
checkbox = function(name, text, checked) {
|
||||||
|
var input, label;
|
||||||
|
if (checked == null) {
|
||||||
|
checked = Conf[name];
|
||||||
|
}
|
||||||
|
label = $.el('label');
|
||||||
|
input = $.el('input', {
|
||||||
|
type: 'checkbox',
|
||||||
|
name: name,
|
||||||
|
checked: checked
|
||||||
|
});
|
||||||
|
$.add(label, [input, $.tn(text)]);
|
||||||
|
return label;
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
dialog: dialog,
|
dialog: dialog,
|
||||||
Menu: Menu,
|
Menu: Menu,
|
||||||
hover: hoverstart
|
hover: hoverstart,
|
||||||
|
checkbox: checkbox
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -9730,11 +9727,10 @@
|
|||||||
dialog: function() {
|
dialog: function() {
|
||||||
var dialog, event, i, items, match_max, match_min, name, node, nodes, rules, save, setNode;
|
var dialog, event, i, items, match_max, match_min, name, node, nodes, rules, save, setNode;
|
||||||
QR.nodes = nodes = {
|
QR.nodes = nodes = {
|
||||||
el: dialog = UI.dialog('qr', 'top:0;right:0;')
|
el: dialog = UI.dialog('qr', 'top:0;right:0;', {
|
||||||
|
innerHTML: "<div id=qrtab class=move>\r<input type=checkbox id=autohide title=Auto-hide>\r<div id=qr-thread-select>\r<select data-name=thread title='Create a new thread / Reply'>\r<option value=new>New thread</option>\r</select>\r</div>\r<a href=javascript:; class='close fa' title=Close>\\uf00d</a>\r</div>\r<form>\r<div class=persona>\r<input name=name data-name=name list=\"list-name\" placeholder=Name class=field size=1>\r<input name=email data-name=email list=\"list-email\" placeholder=Options class=field size=1>\r<input name=sub data-name=sub list=\"list-sub\" placeholder=Subject class=field size=1> \r</div>\r<div class=textarea>\r<textarea data-name=com placeholder=Comment class=field></textarea>\r<span id=char-count></span>\r</div>\r<div id=dump-list-container>\r<div id=dump-list></div>\r<a id=add-post href=javascript:; title=\"Add a post\">+</a>\r</div>\r<div id=file-n-submit>\r<span id=qr-filename-container class=field tabindex=0>\r<span id=qr-no-file>No selected file</span>\r<input id=\"qr-filename\" data-name=\"filename\" spellcheck=\"false\">\r<span id=qr-extras-container>\r<label id=qr-spoiler-label>\r<input type=checkbox id=qr-file-spoiler title='Spoiler image'>\r</label>\r<span class=description>Spoiler</span>\r<a id=url-button><i class=\"fa\">\\uf0c1</i></a>\r<span class=description>Post from URL</span>\r<a id=dump-button title='Dump list'>+</a>\r<span class=description>Dump</span>\r<a id=qr-filerm href=javascript:; title='Remove file' class=fa>\\uf00d</a>\r<span class=description>Remove File</span>\r</span>\r</span>\r<input type=submit>\r</div>\r<input type=file multiple>\r</form>\r<datalist id=\"list-name\"></datalist>\r<datalist id=\"list-email\"></datalist>\r<datalist id=\"list-sub\"></datalist>\r"
|
||||||
|
})
|
||||||
};
|
};
|
||||||
$.extend(dialog, {
|
|
||||||
innerHTML: "<div id=qrtab class=move>\r<input type=checkbox id=autohide title=Auto-hide>\r<div id=qr-thread-select>\r<select data-name=thread title='Create a new thread / Reply'>\r<option value=new>New thread</option>\r</select>\r</div>\r<a href=javascript:; class='close fa' title=Close>\\uf00d</a>\r</div>\r<form>\r<div class=persona>\r<input name=name data-name=name list=\"list-name\" placeholder=Name class=field size=1>\r<input name=email data-name=email list=\"list-email\" placeholder=Options class=field size=1>\r<input name=sub data-name=sub list=\"list-sub\" placeholder=Subject class=field size=1> \r</div>\r<div class=textarea>\r<textarea data-name=com placeholder=Comment class=field></textarea>\r<span id=char-count></span>\r</div>\r<div id=dump-list-container>\r<div id=dump-list></div>\r<a id=add-post href=javascript:; title=\"Add a post\">+</a>\r</div>\r<div id=file-n-submit>\r<span id=qr-filename-container class=field tabindex=0>\r<span id=qr-no-file>No selected file</span>\r<input id=\"qr-filename\" data-name=\"filename\" spellcheck=\"false\">\r<span id=qr-extras-container>\r<label id=qr-spoiler-label>\r<input type=checkbox id=qr-file-spoiler title='Spoiler image'>\r</label>\r<span class=description>Spoiler</span>\r<a id=url-button><i class=\"fa\">\\uf0c1</i></a>\r<span class=description>Post from URL</span>\r<a id=dump-button title='Dump list'>+</a>\r<span class=description>Dump</span>\r<a id=qr-filerm href=javascript:; title='Remove file' class=fa>\\uf00d</a>\r<span class=description>Remove File</span>\r</span>\r</span>\r<input type=submit>\r</div>\r<input type=file multiple>\r</form>\r<datalist id=\"list-name\"></datalist>\r<datalist id=\"list-email\"></datalist>\r<datalist id=\"list-sub\"></datalist>\r"
|
|
||||||
});
|
|
||||||
setNode = function(name, query) {
|
setNode = function(name, query) {
|
||||||
return nodes[name] = $(query, dialog);
|
return nodes[name] = $(query, dialog);
|
||||||
};
|
};
|
||||||
@ -14099,6 +14095,7 @@
|
|||||||
this.status = $('#watcher-status', this.dialog);
|
this.status = $('#watcher-status', this.dialog);
|
||||||
this.list = this.dialog.lastElementChild;
|
this.list = this.dialog.lastElementChild;
|
||||||
this.refreshButton = $('.refresh', this.dialog);
|
this.refreshButton = $('.refresh', this.dialog);
|
||||||
|
this.unreaddb = Unread.db || new DataBoard('lastReadPosts');
|
||||||
$.on(d, 'QRPostSuccessful', this.cb.post);
|
$.on(d, 'QRPostSuccessful', this.cb.post);
|
||||||
if (g.VIEW === 'thread') {
|
if (g.VIEW === 'thread') {
|
||||||
$.on(d, 'ThreadUpdate', this.cb.threadUpdate);
|
$.on(d, 'ThreadUpdate', this.cb.threadUpdate);
|
||||||
|
|||||||
@ -3899,15 +3899,22 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
DataBoard.prototype["delete"] = function(_arg) {
|
DataBoard.prototype["delete"] = function(_arg) {
|
||||||
var boardID, postID, threadID;
|
var boardID, postID, threadID, _ref;
|
||||||
boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID;
|
boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID;
|
||||||
|
$.forceSync(this.key);
|
||||||
if (postID) {
|
if (postID) {
|
||||||
|
if (!((_ref = this.data.boards[boardID]) != null ? _ref[threadID] : void 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
delete this.data.boards[boardID][threadID][postID];
|
delete this.data.boards[boardID][threadID][postID];
|
||||||
this.deleteIfEmpty({
|
this.deleteIfEmpty({
|
||||||
boardID: boardID,
|
boardID: boardID,
|
||||||
threadID: threadID
|
threadID: threadID
|
||||||
});
|
});
|
||||||
} else if (threadID) {
|
} else if (threadID) {
|
||||||
|
if (!this.data.boards[boardID]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
delete this.data.boards[boardID][threadID];
|
delete this.data.boards[boardID][threadID];
|
||||||
this.deleteIfEmpty({
|
this.deleteIfEmpty({
|
||||||
boardID: boardID
|
boardID: boardID
|
||||||
@ -3921,6 +3928,7 @@
|
|||||||
DataBoard.prototype.deleteIfEmpty = function(_arg) {
|
DataBoard.prototype.deleteIfEmpty = function(_arg) {
|
||||||
var boardID, threadID;
|
var boardID, threadID;
|
||||||
boardID = _arg.boardID, threadID = _arg.threadID;
|
boardID = _arg.boardID, threadID = _arg.threadID;
|
||||||
|
$.forceSync(this.key);
|
||||||
if (threadID) {
|
if (threadID) {
|
||||||
if (!Object.keys(this.data.boards[boardID][threadID]).length) {
|
if (!Object.keys(this.data.boards[boardID][threadID]).length) {
|
||||||
delete this.data.boards[boardID][threadID];
|
delete this.data.boards[boardID][threadID];
|
||||||
@ -3936,6 +3944,7 @@
|
|||||||
DataBoard.prototype.set = function(_arg) {
|
DataBoard.prototype.set = function(_arg) {
|
||||||
var boardID, postID, threadID, val, _base, _base1, _base2;
|
var boardID, postID, threadID, val, _base, _base1, _base2;
|
||||||
boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, val = _arg.val;
|
boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, val = _arg.val;
|
||||||
|
$.forceSync(this.key);
|
||||||
if (postID !== void 0) {
|
if (postID !== void 0) {
|
||||||
((_base = ((_base1 = this.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[postID] = val;
|
((_base = ((_base1 = this.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[postID] = val;
|
||||||
} else if (threadID !== void 0) {
|
} else if (threadID !== void 0) {
|
||||||
@ -3969,70 +3978,47 @@
|
|||||||
return val || defaultValue;
|
return val || defaultValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DataBoard.prototype.forceSync = function() {
|
||||||
|
return $.forceSync(this.key);
|
||||||
|
};
|
||||||
|
|
||||||
DataBoard.prototype.clean = function() {
|
DataBoard.prototype.clean = function() {
|
||||||
var boardID, keys, now, _i, _len;
|
var boardID, now, threadID, val, _ref;
|
||||||
now = Date.now();
|
$.forceSync(this.key);
|
||||||
if ((this.data.lastChecked || 0) > now - 2 * $.HOUR) {
|
_ref = this.data.boards;
|
||||||
return;
|
for (boardID in _ref) {
|
||||||
}
|
val = _ref[boardID];
|
||||||
keys = Object.keys(this.data.boards);
|
|
||||||
if (!keys.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
|
||||||
boardID = keys[_i];
|
|
||||||
this.deleteIfEmpty({
|
this.deleteIfEmpty({
|
||||||
boardID: boardID
|
boardID: boardID
|
||||||
});
|
});
|
||||||
if (boardID in this.data.boards) {
|
}
|
||||||
this.ajaxClean(boardID);
|
now = Date.now();
|
||||||
|
if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
|
||||||
|
this.data.lastChecked = now;
|
||||||
|
for (boardID in this.data.boards) {
|
||||||
|
for (threadID in this.data.boards[boardID]) {
|
||||||
|
this.ajaxClean(boardID, threadID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.data.lastChecked = now;
|
|
||||||
return this.save();
|
return this.save();
|
||||||
};
|
};
|
||||||
|
|
||||||
DataBoard.prototype.ajaxClean = function(boardID) {
|
DataBoard.prototype.ajaxClean = function(boardID, threadID) {
|
||||||
return $.cache("//a.4cdn.org/" + boardID + "/threads.json", (function(_this) {
|
return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
|
||||||
return function(e) {
|
onloadend: (function(_this) {
|
||||||
var board, count, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1;
|
return function(e) {
|
||||||
if (e.target.status !== 200) {
|
|
||||||
if (e.target.status === 404) {
|
if (e.target.status === 404) {
|
||||||
_this["delete"]({
|
return _this["delete"]({
|
||||||
boardID: boardID
|
boardID: boardID,
|
||||||
|
threadID: threadID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
};
|
||||||
}
|
})(this)
|
||||||
board = _this.data.boards[boardID];
|
}, {
|
||||||
threads = {};
|
type: 'head'
|
||||||
_ref = e.target.response;
|
});
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
page = _ref[_i];
|
|
||||||
_ref1 = page.threads;
|
|
||||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
|
||||||
thread = _ref1[_j];
|
|
||||||
if (thread.no in board) {
|
|
||||||
threads[thread.no] = board[thread.no];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
count = Object.keys(threads).length;
|
|
||||||
if (count === Object.keys(board).length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (count) {
|
|
||||||
return _this.set({
|
|
||||||
boardID: boardID,
|
|
||||||
val: threads
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return _this["delete"]({
|
|
||||||
boardID: boardID
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})(this));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DataBoard.prototype.onSync = function(data) {
|
DataBoard.prototype.onSync = function(data) {
|
||||||
@ -4080,7 +4066,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.off(d, 'visibilitychange', this.add);
|
$.off(d, 'visibilitychange', this.add);
|
||||||
$.add(Header.noticesRoot, this.el);
|
$.add(doc, this.el);
|
||||||
this.el.clientHeight;
|
this.el.clientHeight;
|
||||||
this.el.style.opacity = 1;
|
this.el.style.opacity = 1;
|
||||||
if (this.timeout) {
|
if (this.timeout) {
|
||||||
@ -4348,7 +4334,7 @@
|
|||||||
className: 'menu-button a-icon',
|
className: 'menu-button a-icon',
|
||||||
id: 'main-menu'
|
id: 'main-menu'
|
||||||
});
|
});
|
||||||
box = UI.checkbox.bind(UI);
|
box = UI.checkbox;
|
||||||
barFixedToggler = box('Fixed Header', 'Fixed Header');
|
barFixedToggler = box('Fixed Header', 'Fixed Header');
|
||||||
headerToggler = box('Header auto-hide', ' Auto-hide header');
|
headerToggler = box('Header auto-hide', ' Auto-hide header');
|
||||||
scrollHeaderToggler = box('Header auto-hide on scroll', ' Auto-hide header on scroll');
|
scrollHeaderToggler = box('Header auto-hide on scroll', ' Auto-hide header on scroll');
|
||||||
@ -6240,43 +6226,21 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* File Info */
|
/* File Info */
|
||||||
if (file != null ? file.isDeleted : void 0) {
|
fileCont = (file != null ? file.isDeleted : void 0) ? {
|
||||||
fileCont = {
|
innerHTML: "<span class=\"fileThumb\"><img src=\"" + E(staticPath) + "filedeleted-res" + E(gifIcon) + "\" alt=\"File deleted.\" class=\"fileDeletedRes retina\"></span>"
|
||||||
innerHTML: "<span class=\"fileThumb\"><img src=\"" + E(staticPath) + "filedeleted-res" + E(gifIcon) + "\" alt=\"File deleted.\" class=\"fileDeletedRes retina\"></span>"
|
} : file && boardID === 'f' ? {
|
||||||
};
|
innerHTML: "<div class=\"fileInfo\"><span class=\"fileText\" id=\"fT" + E(postID) + "\">File: <a data-width=\"" + E(file.width) + "\" data-height=\"" + E(file.height) + "\" href=\"" + E(file.url) + "\" target=\"_blank\">" + E(file.name) + "</a>-(" + E($.bytesToString(file.size)) + ", " + E(file.width) + "x" + E(file.height) + ", " + E(file.tag) + ")</span></div>"
|
||||||
} else if (file && boardID === 'f') {
|
} : file ? (file.isSpoiler ? (shortFilename = 'Spoiler Image', (spoilerRange = Build.spoilerRange[boardID]) ? fileThumb = "//s.4cdn.org/image/spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png" : fileThumb = '//s.4cdn.org/image/spoiler.png', file.twidth = file.theight = 100) : (shortFilename = Build.shortFilename(file.name, !isOP), fileThumb = file.turl), fileSize = $.bytesToString(file.size), fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : "" + file.width + "x" + file.height, fileLink = file.isSpoiler || file.name === shortFilename ? {
|
||||||
fileCont = {
|
innerHTML: "<a href=\"" + E(file.url) + "\" target=\"_blank\">" + E(shortFilename) + "</a>"
|
||||||
innerHTML: "<div class=\"fileInfo\"><span class=\"fileText\" id=\"fT" + E(postID) + "\">File: <a data-width=\"" + E(file.width) + "\" data-height=\"" + E(file.height) + "\" href=\"" + E(file.url) + "\" target=\"_blank\">" + E(file.name) + "</a>-(" + E($.bytesToString(file.size)) + ", " + E(file.width) + "x" + E(file.height) + ", " + E(file.tag) + ")</span></div>"
|
} : {
|
||||||
};
|
innerHTML: "<a title=\"" + E(file.name) + "\" href=\"" + E(file.url) + "\" target=\"_blank\">" + E(shortFilename) + "</a>"
|
||||||
} else if (file) {
|
}, fileText = file.isSpoiler ? {
|
||||||
if (file.isSpoiler) {
|
innerHTML: "<div class=\"fileText\" id=\"fT" + E(postID) + "\" title=\"" + E(file.name) + "\">File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")</div>"
|
||||||
shortFilename = 'Spoiler Image';
|
} : {
|
||||||
if (spoilerRange = Build.spoilerRange[boardID]) {
|
innerHTML: "<div class=\"fileText\" id=\"fT" + E(postID) + "\">File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")</div>"
|
||||||
fileThumb = "//s.4cdn.org/image/spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png";
|
}, {
|
||||||
} else {
|
innerHTML: fileText.innerHTML + "<a class=\"fileThumb" + E(file.isSpoiler ? " imgspoiler" : "") + "\" href=\"" + E(file.url) + "\" target=\"_blank\"><img src=\"" + E(fileThumb) + "\" alt=\"" + E(fileSize) + "\" data-md5=\"" + E(file.MD5) + "\" style=\"height: " + E(file.theight) + "px; width: " + E(file.twidth) + "px;\"></a>"
|
||||||
fileThumb = '//s.4cdn.org/image/spoiler.png';
|
}) : void 0;
|
||||||
}
|
|
||||||
file.twidth = file.theight = 100;
|
|
||||||
} else {
|
|
||||||
shortFilename = Build.shortFilename(file.name, !isOP);
|
|
||||||
fileThumb = file.turl;
|
|
||||||
}
|
|
||||||
fileSize = $.bytesToString(file.size);
|
|
||||||
fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : "" + file.width + "x" + file.height;
|
|
||||||
fileLink = file.isSpoiler || file.name === shortFilename ? {
|
|
||||||
innerHTML: "<a href=\"" + E(file.url) + "\" target=\"_blank\">" + E(shortFilename) + "</a>"
|
|
||||||
} : {
|
|
||||||
innerHTML: "<a title=\"" + E(file.name) + "\" href=\"" + E(file.url) + "\" target=\"_blank\">" + E(shortFilename) + "</a>"
|
|
||||||
};
|
|
||||||
fileText = file.isSpoiler ? {
|
|
||||||
innerHTML: "<div class=\"fileText\" id=\"fT" + E(postID) + "\" title=\"" + E(file.name) + "\">File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")</div>"
|
|
||||||
} : {
|
|
||||||
innerHTML: "<div class=\"fileText\" id=\"fT" + E(postID) + "\">File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")</div>"
|
|
||||||
};
|
|
||||||
({
|
|
||||||
innerHTML: fileText.innerHTML + "<a class=\"fileThumb" + E(file.isSpoiler ? " imgspoiler" : "") + "\" href=\"" + E(file.url) + "\" target=\"_blank\"><img src=\"" + E(fileThumb) + "\" alt=\"" + E(fileSize) + "\" data-md5=\"" + E(file.MD5) + "\" style=\"height: " + E(file.theight) + "px; width: " + E(file.twidth) + "px;\"></a>"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
fileBlock = file ? {
|
fileBlock = file ? {
|
||||||
innerHTML: "<div class=\"file\" id=\"f" + E(postID) + "\">" + fileCont.innerHTML + "</div>"
|
innerHTML: "<div class=\"file\" id=\"f" + E(postID) + "\">" + fileCont.innerHTML + "</div>"
|
||||||
} : {
|
} : {
|
||||||
@ -6794,20 +6758,30 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
UI = (function() {
|
UI = (function() {
|
||||||
var Menu, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove;
|
var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove;
|
||||||
dialog = function(id, position, html) {
|
dialog = function(id, position, properties) {
|
||||||
var el, move;
|
var child, el, move, _i, _len, _ref;
|
||||||
el = $.el('div', {
|
el = $.el('div', {
|
||||||
className: 'dialog',
|
className: 'dialog',
|
||||||
innerHTML: html,
|
|
||||||
id: id
|
id: id
|
||||||
});
|
});
|
||||||
|
$.extend(el, properties);
|
||||||
el.style.cssText = position;
|
el.style.cssText = position;
|
||||||
$.get("" + id + ".position", position, function(item) {
|
$.get("" + id + ".position", position, function(item) {
|
||||||
return el.style.cssText = item["" + id + ".position"];
|
return el.style.cssText = item["" + id + ".position"];
|
||||||
});
|
});
|
||||||
move = $('.move', el);
|
move = $('.move', el);
|
||||||
$.on(move, 'touchstart mousedown', dragstart);
|
$.on(move, 'touchstart mousedown', dragstart);
|
||||||
|
_ref = move.children;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
child = _ref[_i];
|
||||||
|
if (!child.tagName) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$.on(child, 'touchstart mousedown', function(e) {
|
||||||
|
return e.stopPropagation();
|
||||||
|
});
|
||||||
|
}
|
||||||
return el;
|
return el;
|
||||||
};
|
};
|
||||||
Menu = (function() {
|
Menu = (function() {
|
||||||
@ -6817,11 +6791,24 @@
|
|||||||
|
|
||||||
lastToggledButton = null;
|
lastToggledButton = null;
|
||||||
|
|
||||||
function Menu() {
|
function Menu(type) {
|
||||||
|
this.type = type;
|
||||||
this.rmEntry = __bind(this.rmEntry, this);
|
this.rmEntry = __bind(this.rmEntry, this);
|
||||||
|
this.addEntry = __bind(this.addEntry, this);
|
||||||
this.onFocus = __bind(this.onFocus, this);
|
this.onFocus = __bind(this.onFocus, this);
|
||||||
this.keybinds = __bind(this.keybinds, this);
|
this.keybinds = __bind(this.keybinds, this);
|
||||||
this.close = __bind(this.close, this);
|
this.close = __bind(this.close, this);
|
||||||
|
$.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 = [];
|
this.entries = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6861,7 +6848,6 @@
|
|||||||
menu = this.makeMenu();
|
menu = this.makeMenu();
|
||||||
currentMenu = menu;
|
currentMenu = menu;
|
||||||
lastToggledButton = button;
|
lastToggledButton = button;
|
||||||
$.addClass(button, 'open');
|
|
||||||
this.entries.sort(function(first, second) {
|
this.entries.sort(function(first, second) {
|
||||||
return first.order - second.order;
|
return first.order - second.order;
|
||||||
});
|
});
|
||||||
@ -6899,12 +6885,7 @@
|
|||||||
Menu.prototype.insertEntry = function(entry, parent, data) {
|
Menu.prototype.insertEntry = function(entry, parent, data) {
|
||||||
var subEntry, submenu, _i, _len, _ref;
|
var subEntry, submenu, _i, _len, _ref;
|
||||||
if (typeof entry.open === 'function') {
|
if (typeof entry.open === 'function') {
|
||||||
if (!entry.open(data, (function(_this) {
|
if (!entry.open(data)) {
|
||||||
return function(subEntry) {
|
|
||||||
_this.parseEntry(subEntry);
|
|
||||||
return entry.subEntries.push(subEntry);
|
|
||||||
};
|
|
||||||
})(this))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6928,7 +6909,7 @@
|
|||||||
|
|
||||||
Menu.prototype.close = function() {
|
Menu.prototype.close = function() {
|
||||||
$.rm(currentMenu);
|
$.rm(currentMenu);
|
||||||
$.rmClass(lastToggledButton, 'open');
|
$.rmClass(lastToggledButton, 'active');
|
||||||
currentMenu = null;
|
currentMenu = null;
|
||||||
lastToggledButton = null;
|
lastToggledButton = null;
|
||||||
return $.off(d, 'click CloseMenu', this.close);
|
return $.off(d, 'click CloseMenu', this.close);
|
||||||
@ -7043,7 +7024,6 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.addClass(el, 'has-submenu');
|
$.addClass(el, 'has-submenu');
|
||||||
$.addClass(el, 'pfa');
|
|
||||||
for (_i = 0, _len = subEntries.length; _i < _len; _i++) {
|
for (_i = 0, _len = subEntries.length; _i < _len; _i++) {
|
||||||
subEntry = subEntries[_i];
|
subEntry = subEntries[_i];
|
||||||
this.parseEntry(subEntry);
|
this.parseEntry(subEntry);
|
||||||
@ -7054,13 +7034,13 @@
|
|||||||
|
|
||||||
})();
|
})();
|
||||||
dragstart = function(e) {
|
dragstart = function(e) {
|
||||||
var el, isTouching, o, rect, screenHeight, screenWidth, _ref, _ref1;
|
var el, isTouching, o, rect, screenHeight, screenWidth, _ref;
|
||||||
if (e.type === 'mousedown' && e.button !== 0) {
|
if (e.type === 'mousedown' && e.button !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (isTouching = e.type === 'touchstart') {
|
if (isTouching = e.type === 'touchstart') {
|
||||||
_ref = e.changedTouches, e = _ref[_ref.length - 1];
|
e = e.changedTouches[e.changedTouches.length - 1];
|
||||||
}
|
}
|
||||||
el = $.x('ancestor::div[contains(@class,"dialog")][1]', this);
|
el = $.x('ancestor::div[contains(@class,"dialog")][1]', this);
|
||||||
rect = el.getBoundingClientRect();
|
rect = el.getBoundingClientRect();
|
||||||
@ -7077,7 +7057,7 @@
|
|||||||
screenWidth: screenWidth,
|
screenWidth: screenWidth,
|
||||||
isTouching: isTouching
|
isTouching: isTouching
|
||||||
};
|
};
|
||||||
_ref1 = Conf['Header auto-hide'] || !Conf['Fixed Header'] ? [0, 0] : Conf['Bottom Header'] ? [0, Header.bar.getBoundingClientRect().height] : [Header.bar.getBoundingClientRect().height, 0], o.topBorder = _ref1[0], o.bottomBorder = _ref1[1];
|
_ref = Conf['Header auto-hide'] || !Conf['Fixed Header'] ? [0, 0] : Conf['Bottom Header'] ? [0, Header.bar.getBoundingClientRect().height] : [Header.bar.getBoundingClientRect().height, 0], o.topBorder = _ref[0], o.bottomBorder = _ref[1];
|
||||||
if (isTouching) {
|
if (isTouching) {
|
||||||
o.identifier = e.identifier;
|
o.identifier = e.identifier;
|
||||||
o.move = touchmove.bind(o);
|
o.move = touchmove.bind(o);
|
||||||
@ -7139,33 +7119,29 @@
|
|||||||
return $.set("" + this.id + ".position", this.style.cssText);
|
return $.set("" + this.id + ".position", this.style.cssText);
|
||||||
};
|
};
|
||||||
hoverstart = function(_arg) {
|
hoverstart = function(_arg) {
|
||||||
var asapTest, cb, el, endEvents, latestEvent, noRemove, o, offsetX, offsetY, root;
|
var asapTest, cb, el, endEvents, height, latestEvent, noRemove, o, root, _ref;
|
||||||
root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, cb = _arg.cb, offsetX = _arg.offsetX, offsetY = _arg.offsetY, noRemove = _arg.noRemove;
|
root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, height = _arg.height, cb = _arg.cb, noRemove = _arg.noRemove;
|
||||||
o = {
|
o = {
|
||||||
root: root,
|
root: root,
|
||||||
el: el,
|
el: el,
|
||||||
style: el.style,
|
style: el.style,
|
||||||
|
isImage: (_ref = el.nodeName) === 'IMG' || _ref === 'VIDEO',
|
||||||
cb: cb,
|
cb: cb,
|
||||||
close: close,
|
|
||||||
endEvents: endEvents,
|
endEvents: endEvents,
|
||||||
latestEvent: latestEvent,
|
latestEvent: latestEvent,
|
||||||
clientHeight: doc.clientHeight,
|
clientHeight: doc.clientHeight,
|
||||||
clientWidth: doc.clientWidth,
|
clientWidth: doc.clientWidth,
|
||||||
offsetX: offsetX || 45,
|
|
||||||
offsetY: offsetY || -120,
|
|
||||||
noRemove: noRemove
|
noRemove: noRemove
|
||||||
};
|
};
|
||||||
o.hover = hover.bind(o);
|
o.hover = hover.bind(o);
|
||||||
o.hoverend = hoverend.bind(o);
|
o.hoverend = hoverend.bind(o);
|
||||||
if (asapTest) {
|
$.asap(function() {
|
||||||
$.asap(function() {
|
return !el.parentNode || asapTest();
|
||||||
return !el.parentNode || asapTest();
|
}, function() {
|
||||||
}, function() {
|
if (el.parentNode) {
|
||||||
if (el.parentNode) {
|
return o.hover(o.latestEvent);
|
||||||
return o.hover(o.latestEvent);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
$.on(root, endEvents, o.hoverend);
|
$.on(root, endEvents, o.hoverend);
|
||||||
if ($.x('ancestor::div[contains(@class,"inline")][1]', root)) {
|
if ($.x('ancestor::div[contains(@class,"inline")][1]', root)) {
|
||||||
$.on(d, 'keydown', o.hoverend);
|
$.on(d, 'keydown', o.hoverend);
|
||||||
@ -7173,22 +7149,28 @@
|
|||||||
return $.on(root, 'mousemove', o.hover);
|
return $.on(root, 'mousemove', o.hover);
|
||||||
};
|
};
|
||||||
hover = function(e) {
|
hover = function(e) {
|
||||||
var clientX, clientY, height, left, right, top, _ref;
|
var clientX, clientY, height, left, right, style, threshold, top, _ref;
|
||||||
this.latestEvent = e;
|
this.latestEvent = e;
|
||||||
height = this.el.offsetHeight + 25;
|
height = this.height || this.el.offsetHeight;
|
||||||
clientX = e.clientX, clientY = e.clientY;
|
clientX = e.clientX, clientY = e.clientY;
|
||||||
top = clientY + this.offsetY;
|
top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120));
|
||||||
top = this.clientHeight <= height || top <= 0 ? 0 : top + height >= this.clientHeight ? this.clientHeight - height : top;
|
threshold = this.clientWidth / 2;
|
||||||
_ref = clientX <= this.clientWidth / 2 ? [clientX + this.offsetX + 'px', null] : [null, this.clientWidth - clientX + this.offsetX + 'px'], left = _ref[0], right = _ref[1];
|
if (!this.isImage) {
|
||||||
this.style.top = top + 'px';
|
threshold = Math.max(threshold, this.clientWidth - 400);
|
||||||
this.style.left = left;
|
}
|
||||||
return this.style.right = right;
|
_ref = clientX <= threshold ? [clientX + 45 + 'px', null] : [null, this.clientWidth - clientX + 45 + 'px'], left = _ref[0], right = _ref[1];
|
||||||
|
style = this.style;
|
||||||
|
style.top = top + 'px';
|
||||||
|
style.left = left;
|
||||||
|
return style.right = right;
|
||||||
};
|
};
|
||||||
hoverend = function(e) {
|
hoverend = function(e) {
|
||||||
if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") {
|
if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.rm(this.el);
|
if (!this.noRemove) {
|
||||||
|
$.rm(this.el);
|
||||||
|
}
|
||||||
$.off(this.root, this.endEvents, this.hoverend);
|
$.off(this.root, this.endEvents, this.hoverend);
|
||||||
$.off(d, 'keydown', this.hoverend);
|
$.off(d, 'keydown', this.hoverend);
|
||||||
$.off(this.root, 'mousemove', this.hover);
|
$.off(this.root, 'mousemove', this.hover);
|
||||||
@ -7196,10 +7178,25 @@
|
|||||||
return this.cb.call(this);
|
return this.cb.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
checkbox = function(name, text, checked) {
|
||||||
|
var input, label;
|
||||||
|
if (checked == null) {
|
||||||
|
checked = Conf[name];
|
||||||
|
}
|
||||||
|
label = $.el('label');
|
||||||
|
input = $.el('input', {
|
||||||
|
type: 'checkbox',
|
||||||
|
name: name,
|
||||||
|
checked: checked
|
||||||
|
});
|
||||||
|
$.add(label, [input, $.tn(text)]);
|
||||||
|
return label;
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
dialog: dialog,
|
dialog: dialog,
|
||||||
Menu: Menu,
|
Menu: Menu,
|
||||||
hover: hoverstart
|
hover: hoverstart,
|
||||||
|
checkbox: checkbox
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -9784,11 +9781,10 @@
|
|||||||
dialog: function() {
|
dialog: function() {
|
||||||
var dialog, event, i, items, match_max, match_min, name, node, nodes, rules, save, setNode;
|
var dialog, event, i, items, match_max, match_min, name, node, nodes, rules, save, setNode;
|
||||||
QR.nodes = nodes = {
|
QR.nodes = nodes = {
|
||||||
el: dialog = UI.dialog('qr', 'top:0;right:0;')
|
el: dialog = UI.dialog('qr', 'top:0;right:0;', {
|
||||||
|
innerHTML: "<div id=qrtab class=move>\r<input type=checkbox id=autohide title=Auto-hide>\r<div id=qr-thread-select>\r<select data-name=thread title='Create a new thread / Reply'>\r<option value=new>New thread</option>\r</select>\r</div>\r<a href=javascript:; class='close fa' title=Close>\\uf00d</a>\r</div>\r<form>\r<div class=persona>\r<input name=name data-name=name list=\"list-name\" placeholder=Name class=field size=1>\r<input name=email data-name=email list=\"list-email\" placeholder=Options class=field size=1>\r<input name=sub data-name=sub list=\"list-sub\" placeholder=Subject class=field size=1> \r</div>\r<div class=textarea>\r<textarea data-name=com placeholder=Comment class=field></textarea>\r<span id=char-count></span>\r</div>\r<div id=dump-list-container>\r<div id=dump-list></div>\r<a id=add-post href=javascript:; title=\"Add a post\">+</a>\r</div>\r<div id=file-n-submit>\r<span id=qr-filename-container class=field tabindex=0>\r<span id=qr-no-file>No selected file</span>\r<input id=\"qr-filename\" data-name=\"filename\" spellcheck=\"false\">\r<span id=qr-extras-container>\r<label id=qr-spoiler-label>\r<input type=checkbox id=qr-file-spoiler title='Spoiler image'>\r</label>\r<span class=description>Spoiler</span>\r<a id=url-button><i class=\"fa\">\\uf0c1</i></a>\r<span class=description>Post from URL</span>\r<a id=dump-button title='Dump list'>+</a>\r<span class=description>Dump</span>\r<a id=qr-filerm href=javascript:; title='Remove file' class=fa>\\uf00d</a>\r<span class=description>Remove File</span>\r</span>\r</span>\r<input type=submit>\r</div>\r<input type=file multiple>\r</form>\r<datalist id=\"list-name\"></datalist>\r<datalist id=\"list-email\"></datalist>\r<datalist id=\"list-sub\"></datalist>\r"
|
||||||
|
})
|
||||||
};
|
};
|
||||||
$.extend(dialog, {
|
|
||||||
innerHTML: "<div id=qrtab class=move>\r<input type=checkbox id=autohide title=Auto-hide>\r<div id=qr-thread-select>\r<select data-name=thread title='Create a new thread / Reply'>\r<option value=new>New thread</option>\r</select>\r</div>\r<a href=javascript:; class='close fa' title=Close>\\uf00d</a>\r</div>\r<form>\r<div class=persona>\r<input name=name data-name=name list=\"list-name\" placeholder=Name class=field size=1>\r<input name=email data-name=email list=\"list-email\" placeholder=Options class=field size=1>\r<input name=sub data-name=sub list=\"list-sub\" placeholder=Subject class=field size=1> \r</div>\r<div class=textarea>\r<textarea data-name=com placeholder=Comment class=field></textarea>\r<span id=char-count></span>\r</div>\r<div id=dump-list-container>\r<div id=dump-list></div>\r<a id=add-post href=javascript:; title=\"Add a post\">+</a>\r</div>\r<div id=file-n-submit>\r<span id=qr-filename-container class=field tabindex=0>\r<span id=qr-no-file>No selected file</span>\r<input id=\"qr-filename\" data-name=\"filename\" spellcheck=\"false\">\r<span id=qr-extras-container>\r<label id=qr-spoiler-label>\r<input type=checkbox id=qr-file-spoiler title='Spoiler image'>\r</label>\r<span class=description>Spoiler</span>\r<a id=url-button><i class=\"fa\">\\uf0c1</i></a>\r<span class=description>Post from URL</span>\r<a id=dump-button title='Dump list'>+</a>\r<span class=description>Dump</span>\r<a id=qr-filerm href=javascript:; title='Remove file' class=fa>\\uf00d</a>\r<span class=description>Remove File</span>\r</span>\r</span>\r<input type=submit>\r</div>\r<input type=file multiple>\r</form>\r<datalist id=\"list-name\"></datalist>\r<datalist id=\"list-email\"></datalist>\r<datalist id=\"list-sub\"></datalist>\r"
|
|
||||||
});
|
|
||||||
setNode = function(name, query) {
|
setNode = function(name, query) {
|
||||||
return nodes[name] = $(query, dialog);
|
return nodes[name] = $(query, dialog);
|
||||||
};
|
};
|
||||||
@ -14126,6 +14122,7 @@
|
|||||||
this.status = $('#watcher-status', this.dialog);
|
this.status = $('#watcher-status', this.dialog);
|
||||||
this.list = this.dialog.lastElementChild;
|
this.list = this.dialog.lastElementChild;
|
||||||
this.refreshButton = $('.refresh', this.dialog);
|
this.refreshButton = $('.refresh', this.dialog);
|
||||||
|
this.unreaddb = Unread.db || new DataBoard('lastReadPosts');
|
||||||
$.on(d, 'QRPostSuccessful', this.cb.post);
|
$.on(d, 'QRPostSuccessful', this.cb.post);
|
||||||
if (g.VIEW === 'thread') {
|
if (g.VIEW === 'thread') {
|
||||||
$.on(d, 'ThreadUpdate', this.cb.threadUpdate);
|
$.on(d, 'ThreadUpdate', this.cb.threadUpdate);
|
||||||
|
|||||||
@ -181,14 +181,14 @@ Build =
|
|||||||
|
|
||||||
### File Info ###
|
### File Info ###
|
||||||
|
|
||||||
if file?.isDeleted
|
fileCont = if file?.isDeleted
|
||||||
fileCont = <%= html(
|
<%= html(
|
||||||
'<span class="fileThumb">' +
|
'<span class="fileThumb">' +
|
||||||
'<img src="${staticPath}filedeleted-res${gifIcon}" alt="File deleted." class="fileDeletedRes retina">' +
|
'<img src="${staticPath}filedeleted-res${gifIcon}" alt="File deleted." class="fileDeletedRes retina">' +
|
||||||
'</span>'
|
'</span>'
|
||||||
) %>
|
) %>
|
||||||
else if file and boardID is 'f'
|
else if file and boardID is 'f'
|
||||||
fileCont = <%= html(
|
<%= html(
|
||||||
'<div class="fileInfo"><span class="fileText" id="fT${postID}">' +
|
'<div class="fileInfo"><span class="fileText" id="fT${postID}">' +
|
||||||
'File: <a data-width="${file.width}" data-height="${file.height}" href="${file.url}" target="_blank">${file.name}</a>' +
|
'File: <a data-width="${file.width}" data-height="${file.height}" href="${file.url}" target="_blank">${file.name}</a>' +
|
||||||
'-(${$.bytesToString(file.size)}, ${file.width}x${file.height}, ${file.tag})' +
|
'-(${$.bytesToString(file.size)}, ${file.width}x${file.height}, ${file.tag})' +
|
||||||
|
|||||||
@ -6,7 +6,7 @@ Header =
|
|||||||
className: 'menu-button a-icon'
|
className: 'menu-button a-icon'
|
||||||
id: 'main-menu'
|
id: 'main-menu'
|
||||||
|
|
||||||
box = UI.checkbox.bind UI
|
box = UI.checkbox
|
||||||
|
|
||||||
barFixedToggler = box 'Fixed Header', 'Fixed Header'
|
barFixedToggler = box 'Fixed Header', 'Fixed Header'
|
||||||
headerToggler = box 'Header auto-hide', ' Auto-hide header'
|
headerToggler = box 'Header auto-hide', ' Auto-hide header'
|
||||||
|
|||||||
@ -1,15 +1,19 @@
|
|||||||
UI = do ->
|
UI = do ->
|
||||||
dialog = (id, position, html) ->
|
dialog = (id, position, properties) ->
|
||||||
el = $.el 'div',
|
el = $.el 'div',
|
||||||
className: 'dialog'
|
className: 'dialog'
|
||||||
innerHTML: html
|
|
||||||
id: id
|
id: id
|
||||||
|
$.extend el, properties
|
||||||
el.style.cssText = position
|
el.style.cssText = position
|
||||||
$.get "#{id}.position", position, (item) ->
|
$.get "#{id}.position", position, (item) ->
|
||||||
el.style.cssText = item["#{id}.position"]
|
el.style.cssText = item["#{id}.position"]
|
||||||
|
|
||||||
move = $ '.move', el
|
move = $ '.move', el
|
||||||
$.on move, 'touchstart mousedown', dragstart
|
$.on move, 'touchstart mousedown', dragstart
|
||||||
|
for child in move.children
|
||||||
|
continue unless child.tagName
|
||||||
|
$.on child, 'touchstart mousedown', (e) ->
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
el
|
el
|
||||||
|
|
||||||
@ -17,7 +21,12 @@ UI = do ->
|
|||||||
currentMenu = null
|
currentMenu = null
|
||||||
lastToggledButton = null
|
lastToggledButton = null
|
||||||
|
|
||||||
constructor: ->
|
constructor: (@type) ->
|
||||||
|
# XXX AddMenuEntry event is deprecated
|
||||||
|
$.on d, 'AddMenuEntry', ({detail}) =>
|
||||||
|
return if detail.type isnt @type
|
||||||
|
delete detail.open
|
||||||
|
@addEntry detail
|
||||||
@entries = []
|
@entries = []
|
||||||
|
|
||||||
makeMenu: ->
|
makeMenu: ->
|
||||||
@ -47,7 +56,6 @@ UI = do ->
|
|||||||
menu = @makeMenu()
|
menu = @makeMenu()
|
||||||
currentMenu = menu
|
currentMenu = menu
|
||||||
lastToggledButton = button
|
lastToggledButton = button
|
||||||
$.addClass button, 'open'
|
|
||||||
|
|
||||||
@entries.sort (first, second) ->
|
@entries.sort (first, second) ->
|
||||||
first.order - second.order
|
first.order - second.order
|
||||||
@ -95,9 +103,7 @@ UI = do ->
|
|||||||
|
|
||||||
insertEntry: (entry, parent, data) ->
|
insertEntry: (entry, parent, data) ->
|
||||||
if typeof entry.open is 'function'
|
if typeof entry.open is 'function'
|
||||||
return unless entry.open data, (subEntry) =>
|
return unless entry.open data
|
||||||
@parseEntry subEntry
|
|
||||||
entry.subEntries.push subEntry
|
|
||||||
$.add parent, entry.el
|
$.add parent, entry.el
|
||||||
|
|
||||||
return unless entry.subEntries
|
return unless entry.subEntries
|
||||||
@ -113,7 +119,7 @@ UI = do ->
|
|||||||
|
|
||||||
close: =>
|
close: =>
|
||||||
$.rm currentMenu
|
$.rm currentMenu
|
||||||
$.rmClass lastToggledButton, 'open'
|
$.rmClass lastToggledButton, 'active'
|
||||||
currentMenu = null
|
currentMenu = null
|
||||||
lastToggledButton = null
|
lastToggledButton = null
|
||||||
$.off d, 'click CloseMenu', @close
|
$.off d, 'click CloseMenu', @close
|
||||||
@ -184,7 +190,7 @@ UI = do ->
|
|||||||
style.left = left
|
style.left = left
|
||||||
style.right = right
|
style.right = right
|
||||||
|
|
||||||
addEntry: (entry) ->
|
addEntry: (entry) =>
|
||||||
@parseEntry entry
|
@parseEntry entry
|
||||||
@entries.push entry
|
@entries.push entry
|
||||||
|
|
||||||
@ -199,7 +205,6 @@ UI = do ->
|
|||||||
el.style.order = entry.order or 100
|
el.style.order = entry.order or 100
|
||||||
return unless subEntries
|
return unless subEntries
|
||||||
$.addClass el, 'has-submenu'
|
$.addClass el, 'has-submenu'
|
||||||
$.addClass el, 'pfa'
|
|
||||||
for subEntry in subEntries
|
for subEntry in subEntries
|
||||||
@parseEntry subEntry
|
@parseEntry subEntry
|
||||||
return
|
return
|
||||||
@ -209,7 +214,7 @@ UI = do ->
|
|||||||
# prevent text selection
|
# prevent text selection
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if isTouching = e.type is 'touchstart'
|
if isTouching = e.type is 'touchstart'
|
||||||
[..., e] = e.changedTouches
|
e = e.changedTouches[e.changedTouches.length - 1]
|
||||||
# distance from pointer to el edge is constant; calculate it here.
|
# distance from pointer to el edge is constant; calculate it here.
|
||||||
el = $.x 'ancestor::div[contains(@class,"dialog")][1]', @
|
el = $.x 'ancestor::div[contains(@class,"dialog")][1]', @
|
||||||
rect = el.getBoundingClientRect()
|
rect = el.getBoundingClientRect()
|
||||||
@ -302,76 +307,80 @@ UI = do ->
|
|||||||
$.off d, 'mouseup', @up
|
$.off d, 'mouseup', @up
|
||||||
$.set "#{@id}.position", @style.cssText
|
$.set "#{@id}.position", @style.cssText
|
||||||
|
|
||||||
hoverstart = ({root, el, latestEvent, endEvents, asapTest, cb, offsetX, offsetY, noRemove}) ->
|
hoverstart = ({root, el, latestEvent, endEvents, asapTest, height, cb, noRemove}) ->
|
||||||
o = {
|
o = {
|
||||||
root
|
root
|
||||||
el
|
el
|
||||||
style: el.style
|
style: el.style
|
||||||
|
isImage: el.nodeName in ['IMG', 'VIDEO']
|
||||||
cb
|
cb
|
||||||
close: close
|
|
||||||
endEvents
|
endEvents
|
||||||
latestEvent
|
latestEvent
|
||||||
clientHeight: doc.clientHeight
|
clientHeight: doc.clientHeight
|
||||||
clientWidth: doc.clientWidth
|
clientWidth: doc.clientWidth
|
||||||
offsetX: offsetX or 45
|
|
||||||
offsetY: offsetY or -120
|
|
||||||
noRemove
|
noRemove
|
||||||
}
|
}
|
||||||
o.hover = hover.bind o
|
o.hover = hover.bind o
|
||||||
o.hoverend = hoverend.bind o
|
o.hoverend = hoverend.bind o
|
||||||
|
|
||||||
if asapTest
|
$.asap ->
|
||||||
$.asap ->
|
!el.parentNode or asapTest()
|
||||||
!el.parentNode or asapTest()
|
, ->
|
||||||
, ->
|
o.hover o.latestEvent if el.parentNode
|
||||||
o.hover o.latestEvent if el.parentNode
|
|
||||||
|
|
||||||
$.on root, endEvents, o.hoverend
|
$.on root, endEvents, o.hoverend
|
||||||
if $.x 'ancestor::div[contains(@class,"inline")][1]', root
|
if $.x 'ancestor::div[contains(@class,"inline")][1]', root
|
||||||
$.on d, 'keydown', o.hoverend
|
$.on d, 'keydown', o.hoverend
|
||||||
$.on root, 'mousemove', o.hover
|
$.on root, 'mousemove', o.hover
|
||||||
<% if (type === 'userscript') { %>
|
<% if (type === 'userscript') { %>
|
||||||
# Workaround for https://github.com/MayhemYDG/4chan-x/issues/377
|
# Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=674955
|
||||||
o.workaround = (e) -> o.hoverend(e) unless root.contains e.target
|
o.workaround = (e) -> o.hoverend(e) unless root.contains e.target
|
||||||
$.on doc, 'mousemove', o.workaround
|
$.on doc, 'mousemove', o.workaround
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
hover = (e) ->
|
hover = (e) ->
|
||||||
@latestEvent = e
|
@latestEvent = e
|
||||||
height = @el.offsetHeight + 25
|
height = @height or @el.offsetHeight
|
||||||
{clientX, clientY} = e
|
{clientX, clientY} = e
|
||||||
|
top = if @isImage
|
||||||
top = clientY + @offsetY
|
Math.max 0, clientY * (@clientHeight - height) / @clientHeight
|
||||||
top = if @clientHeight <= height or top <= 0
|
|
||||||
0
|
|
||||||
else if top + height >= @clientHeight
|
|
||||||
@clientHeight - height
|
|
||||||
else
|
else
|
||||||
top
|
Math.max 0, Math.min(@clientHeight - height, clientY - 120)
|
||||||
|
|
||||||
[left, right] = if clientX <= @clientWidth / 2
|
threshold = @clientWidth / 2
|
||||||
[clientX + @offsetX + 'px', null]
|
threshold = Math.max threshold, @clientWidth - 400 unless @isImage
|
||||||
|
[left, right] = if clientX <= threshold
|
||||||
|
[clientX + 45 + 'px', null]
|
||||||
else
|
else
|
||||||
[null, @clientWidth - clientX + @offsetX + 'px']
|
[null, @clientWidth - clientX + 45 + 'px']
|
||||||
|
|
||||||
@style.top = top + 'px'
|
{style} = @
|
||||||
@style.left = left
|
style.top = top + 'px'
|
||||||
@style.right = right
|
style.left = left
|
||||||
|
style.right = right
|
||||||
|
|
||||||
hoverend = (e) ->
|
hoverend = (e) ->
|
||||||
return if e.type is 'keydown' and e.keyCode isnt 13 or e.target.nodeName is "TEXTAREA"
|
return if e.type is 'keydown' and e.keyCode isnt 13 or e.target.nodeName is "TEXTAREA"
|
||||||
$.rm @el
|
$.rm @el unless @noRemove
|
||||||
$.off @root, @endEvents, @hoverend
|
$.off @root, @endEvents, @hoverend
|
||||||
$.off d, 'keydown', @hoverend
|
$.off d, 'keydown', @hoverend
|
||||||
$.off @root, 'mousemove', @hover
|
$.off @root, 'mousemove', @hover
|
||||||
<% if (type === 'userscript') { %>
|
<% if (type === 'userscript') { %>
|
||||||
# Workaround for https://github.com/MayhemYDG/4chan-x/issues/377
|
# Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=674955
|
||||||
$.off doc, 'mousemove', @workaround
|
$.off doc, 'mousemove', @workaround
|
||||||
<% } %>
|
<% } %>
|
||||||
@cb.call @ if @cb
|
@cb.call @ if @cb
|
||||||
|
|
||||||
|
checkbox = (name, text, checked) ->
|
||||||
|
checked = Conf[name] unless checked?
|
||||||
|
label = $.el 'label'
|
||||||
|
input = $.el 'input', {type: 'checkbox', name, checked}
|
||||||
|
$.add label, [input, $.tn text]
|
||||||
|
label
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dialog: dialog
|
dialog: dialog
|
||||||
Menu: Menu
|
Menu: Menu
|
||||||
hover: hoverstart
|
hover: hoverstart
|
||||||
|
checkbox: checkbox
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/General/eventPage/eventPage.coffee
Normal file
28
src/General/eventPage/eventPage.coffee
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
requestID = 0
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener (request, sender, sendResponse) ->
|
||||||
|
id = requestID
|
||||||
|
requestID++
|
||||||
|
sendResponse id
|
||||||
|
|
||||||
|
xhr = new XMLHttpRequest()
|
||||||
|
xhr.open 'GET', request.url, true
|
||||||
|
xhr.responseType = request.responseType
|
||||||
|
xhr.addEventListener 'load', ->
|
||||||
|
if @readyState is @DONE && xhr.status is 200
|
||||||
|
contentType = @getResponseHeader 'Content-Type'
|
||||||
|
contentDisposition = @getResponseHeader 'Content-Disposition'
|
||||||
|
{response} = @
|
||||||
|
if request.responseType is 'arraybuffer'
|
||||||
|
response = [new Uint8Array(response)...]
|
||||||
|
chrome.tabs.sendMessage sender.tab.id, {id, response, contentType, contentDisposition}
|
||||||
|
else
|
||||||
|
chrome.tabs.sendMessage sender.tab.id, {id, error: true}
|
||||||
|
, false
|
||||||
|
xhr.addEventListener 'error', ->
|
||||||
|
chrome.tabs.sendMessage sender.tab.id, {id, error: true}
|
||||||
|
, false
|
||||||
|
xhr.addEventListener 'abort', ->
|
||||||
|
chrome.tabs.sendMessage sender.tab.id, {id, error: true}
|
||||||
|
, false
|
||||||
|
xhr.send()
|
||||||
@ -16,10 +16,13 @@ class DataBoard
|
|||||||
save: -> $.set @key, @data
|
save: -> $.set @key, @data
|
||||||
|
|
||||||
delete: ({boardID, threadID, postID}) ->
|
delete: ({boardID, threadID, postID}) ->
|
||||||
|
$.forceSync @key
|
||||||
if postID
|
if postID
|
||||||
|
return unless @data.boards[boardID]?[threadID]
|
||||||
delete @data.boards[boardID][threadID][postID]
|
delete @data.boards[boardID][threadID][postID]
|
||||||
@deleteIfEmpty {boardID, threadID}
|
@deleteIfEmpty {boardID, threadID}
|
||||||
else if threadID
|
else if threadID
|
||||||
|
return unless @data.boards[boardID]
|
||||||
delete @data.boards[boardID][threadID]
|
delete @data.boards[boardID][threadID]
|
||||||
@deleteIfEmpty {boardID}
|
@deleteIfEmpty {boardID}
|
||||||
else
|
else
|
||||||
@ -27,6 +30,7 @@ class DataBoard
|
|||||||
@save()
|
@save()
|
||||||
|
|
||||||
deleteIfEmpty: ({boardID, threadID}) ->
|
deleteIfEmpty: ({boardID, threadID}) ->
|
||||||
|
$.forceSync @key
|
||||||
if threadID
|
if threadID
|
||||||
unless Object.keys(@data.boards[boardID][threadID]).length
|
unless Object.keys(@data.boards[boardID][threadID]).length
|
||||||
delete @data.boards[boardID][threadID]
|
delete @data.boards[boardID][threadID]
|
||||||
@ -35,6 +39,7 @@ class DataBoard
|
|||||||
delete @data.boards[boardID]
|
delete @data.boards[boardID]
|
||||||
|
|
||||||
set: ({boardID, threadID, postID, val}) ->
|
set: ({boardID, threadID, postID, val}) ->
|
||||||
|
$.forceSync @key
|
||||||
if postID isnt undefined
|
if postID isnt undefined
|
||||||
((@data.boards[boardID] or= {})[threadID] or= {})[postID] = val
|
((@data.boards[boardID] or= {})[threadID] or= {})[postID] = val
|
||||||
else if threadID isnt undefined
|
else if threadID isnt undefined
|
||||||
@ -60,39 +65,28 @@ class DataBoard
|
|||||||
thread
|
thread
|
||||||
val or defaultValue
|
val or defaultValue
|
||||||
|
|
||||||
|
forceSync: ->
|
||||||
|
$.forceSync @key
|
||||||
clean: ->
|
clean: ->
|
||||||
now = Date.now()
|
$.forceSync @key
|
||||||
return if (@data.lastChecked or 0) > now - 2 * $.HOUR
|
for boardID, val of @data.boards
|
||||||
|
|
||||||
# Don't even bother writing unless we have data to write
|
|
||||||
keys = Object.keys @data.boards
|
|
||||||
return unless keys.length
|
|
||||||
|
|
||||||
# Since we generated the keys anyways, use them to avoid the slow ``Object::hasOwnProperty`` method
|
|
||||||
# Not that ``Object.keys`` is fast
|
|
||||||
for boardID in keys
|
|
||||||
@deleteIfEmpty {boardID}
|
@deleteIfEmpty {boardID}
|
||||||
@ajaxClean boardID if boardID of @data.boards
|
|
||||||
|
|
||||||
@data.lastChecked = now
|
now = Date.now()
|
||||||
|
if (@data.lastChecked or 0) < now - 2 * $.HOUR
|
||||||
|
@data.lastChecked = now
|
||||||
|
for boardID of @data.boards
|
||||||
|
for threadID of @data.boards[boardID]
|
||||||
|
@ajaxClean boardID, threadID
|
||||||
@save()
|
@save()
|
||||||
|
|
||||||
ajaxClean: (boardID) ->
|
ajaxClean: (boardID, threadID) ->
|
||||||
$.cache "//a.4cdn.org/#{boardID}/threads.json", (e) =>
|
$.ajax "//a.4cdn.org/#{boardID}/thread/#{threadID}.json",
|
||||||
if e.target.status isnt 200
|
onloadend: (e) =>
|
||||||
@delete {boardID} if e.target.status is 404
|
if e.target.status is 404
|
||||||
return
|
@delete {boardID, threadID}
|
||||||
board = @data.boards[boardID]
|
,
|
||||||
threads = {}
|
type: 'head'
|
||||||
for page in e.target.response
|
|
||||||
for thread in page.threads when thread.no of board
|
|
||||||
threads[thread.no] = board[thread.no]
|
|
||||||
count = Object.keys(threads).length
|
|
||||||
return if count is Object.keys(board).length # Nothing changed.
|
|
||||||
if count
|
|
||||||
@set {boardID, val: threads}
|
|
||||||
else
|
|
||||||
@delete {boardID}
|
|
||||||
|
|
||||||
onSync: (data) =>
|
onSync: (data) =>
|
||||||
@data = data or boards: {}
|
@data = data or boards: {}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ class Notice
|
|||||||
$.on d, 'visibilitychange', @add
|
$.on d, 'visibilitychange', @add
|
||||||
return
|
return
|
||||||
$.off d, 'visibilitychange', @add
|
$.off d, 'visibilitychange', @add
|
||||||
$.add Header.noticesRoot, @el
|
$.add doc, @el
|
||||||
@el.clientHeight # force reflow
|
@el.clientHeight # force reflow
|
||||||
@el.style.opacity = 1
|
@el.style.opacity = 1
|
||||||
setTimeout @close, @timeout * $.SECOND if @timeout
|
setTimeout @close, @timeout * $.SECOND if @timeout
|
||||||
|
|||||||
@ -8,6 +8,7 @@ ThreadWatcher =
|
|||||||
@status = $ '#watcher-status', @dialog
|
@status = $ '#watcher-status', @dialog
|
||||||
@list = @dialog.lastElementChild
|
@list = @dialog.lastElementChild
|
||||||
@refreshButton = $ '.refresh', @dialog
|
@refreshButton = $ '.refresh', @dialog
|
||||||
|
@unreaddb = Unread.db or new DataBoard 'lastReadPosts'
|
||||||
|
|
||||||
$.on d, 'QRPostSuccessful', @cb.post
|
$.on d, 'QRPostSuccessful', @cb.post
|
||||||
$.on d, 'ThreadUpdate', @cb.threadUpdate if g.VIEW is 'thread'
|
$.on d, 'ThreadUpdate', @cb.threadUpdate if g.VIEW is 'thread'
|
||||||
|
|||||||
@ -387,7 +387,7 @@ QR =
|
|||||||
dialog: ->
|
dialog: ->
|
||||||
QR.nodes = nodes =
|
QR.nodes = nodes =
|
||||||
el: dialog = UI.dialog 'qr', 'top:0;right:0;',
|
el: dialog = UI.dialog 'qr', 'top:0;right:0;',
|
||||||
$.extend dialog, <%= importHTML('Features/QuickReply') %>
|
<%= importHTML('Features/QuickReply') %>
|
||||||
|
|
||||||
setNode = (name, query) ->
|
setNode = (name, query) ->
|
||||||
nodes[name] = $ query, dialog
|
nodes[name] = $ query, dialog
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user