Merge branch 'v3'
Conflicts: CHANGELOG.md LICENSE builds/appchan-x.user.js builds/crx/manifest.json builds/crx/script.js package.json src/General/Navigate.coffee src/Miscellaneous/Keybinds.coffee src/Posting/QR.coffee
This commit is contained in:
commit
41ec3933cd
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
**ccd0**
|
**ccd0**
|
||||||
|
- Some keybind bugfixes.
|
||||||
|
- Begin work toward compatibility with new URLs.
|
||||||
- `Loop in New Tab` (enabled by default) causes videos opened in a separate tab to loop, and applies your settings for inline expanded videos to them.
|
- `Loop in New Tab` (enabled by default) causes videos opened in a separate tab to loop, and applies your settings for inline expanded videos to them.
|
||||||
- Add WebM support to gallery (currently no controls).
|
- Add WebM support to gallery (currently no controls).
|
||||||
- Add PDF support to gallery, disabled by default. Enable with `PDF in Gallery`.
|
- Add PDF support to gallery, disabled by default. Enable with `PDF in Gallery`.
|
||||||
@ -13,6 +14,11 @@
|
|||||||
**fgts**
|
**fgts**
|
||||||
- Update archive list.
|
- Update archive list.
|
||||||
|
|
||||||
|
**MayhemYDG**
|
||||||
|
- Update 4chan namespaces support.
|
||||||
|
- Better handling of webm playback errors.
|
||||||
|
|
||||||
|
|
||||||
**Nebukazar**
|
**Nebukazar**
|
||||||
- `Quote Threading` disabled by default
|
- `Quote Threading` disabled by default
|
||||||
- Added missing titles to Header icons
|
- Added missing titles to Header icons
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* appchan x - Version 2.9.15 - 2014-04-11
|
* appchan x - Version 2.9.15 - 2014-04-19
|
||||||
*
|
*
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 4chan X
|
// @name 4chan X
|
||||||
// @version 1.7.7
|
// @version 1.7.8
|
||||||
// @minGMVer 1.14
|
// @minGMVer 1.14
|
||||||
// @minFFVer 26
|
// @minFFVer 26
|
||||||
// @namespace 4chan-X
|
// @namespace 4chan-X
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* appchan x - Version 2.9.15 - 2014-04-11
|
* appchan x - Version 2.9.15 - 2014-04-19
|
||||||
*
|
*
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||||
@ -428,8 +428,8 @@
|
|||||||
'Open Gallery': ['g', 'Opens the gallery.'],
|
'Open Gallery': ['g', 'Opens the gallery.'],
|
||||||
'fappeTyme': ['f', 'Fappe Tyme.'],
|
'fappeTyme': ['f', 'Fappe Tyme.'],
|
||||||
'werkTyme': ['Shift+w', 'Werk Tyme'],
|
'werkTyme': ['Shift+w', 'Werk Tyme'],
|
||||||
'Front page': ['0', 'Jump to page 0.'],
|
'Front page': ['0', 'Jump to front page.'],
|
||||||
'Open front page': ['Shift+0', 'Open page 0 in a new tab.'],
|
'Open front page': ['Shift+0', 'Open front page in a new tab.'],
|
||||||
'Next page': ['Shift+Right', 'Jump to the next page.'],
|
'Next page': ['Shift+Right', 'Jump to the next page.'],
|
||||||
'Previous page': ['Shift+Left', 'Jump to the previous page.'],
|
'Previous page': ['Shift+Left', 'Jump to the previous page.'],
|
||||||
'Search form': ['Ctrl+Alt+s', 'Focus the search field on the board index.'],
|
'Search form': ['Ctrl+Alt+s', 'Focus the search field on the board index.'],
|
||||||
@ -3364,7 +3364,7 @@
|
|||||||
|
|
||||||
Post.prototype.parseQuote = function(quotelink) {
|
Post.prototype.parseQuote = function(quotelink) {
|
||||||
var fullID, match;
|
var fullID, match;
|
||||||
if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/res\/\d+#p(\d+)$/))) {
|
if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/thread\/\d+#p(\d+)$/))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.nodes.quotelinks.push(quotelink);
|
this.nodes.quotelinks.push(quotelink);
|
||||||
@ -3398,7 +3398,7 @@
|
|||||||
size *= 1024;
|
size *= 1024;
|
||||||
}
|
}
|
||||||
this.file.sizeInBytes = size;
|
this.file.sizeInBytes = size;
|
||||||
this.file.thumbURL = that.isArchived ? thumb.src : "" + location.protocol + "//t.4cdn.org/" + this.board + "/thumb/" + (this.file.URL.match(/(\d+)\./)[1]) + "s.jpg";
|
this.file.thumbURL = that.isArchived ? thumb.src : "" + location.protocol + "//t.4cdn.org/" + this.board + "/" + (this.file.URL.match(/(\d+)\./)[1]) + "s.jpg";
|
||||||
this.file.name = (nameNode = $('span', fileText)) ? nameNode.title || nameNode.textContent : fileText.title;
|
this.file.name = (nameNode = $('span', fileText)) ? nameNode.title || nameNode.textContent : fileText.title;
|
||||||
this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name);
|
this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name);
|
||||||
this.file.isVideo = /webm$/i.test(this.file.name);
|
this.file.isVideo = /webm$/i.test(this.file.name);
|
||||||
@ -4130,23 +4130,6 @@
|
|||||||
|
|
||||||
Polyfill = {
|
Polyfill = {
|
||||||
init: function() {},
|
init: function() {},
|
||||||
notificationPermission: function() {
|
|
||||||
if (!window.Notification || 'permission' in Notification || !window.webkitNotifications) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return Object.defineProperty(Notification, 'permission', {
|
|
||||||
get: function() {
|
|
||||||
switch (webkitNotifications.checkPermission()) {
|
|
||||||
case 0:
|
|
||||||
return 'granted';
|
|
||||||
case 1:
|
|
||||||
return 'default';
|
|
||||||
case 2:
|
|
||||||
return 'denied';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
toBlob: function() {
|
toBlob: function() {
|
||||||
var _base;
|
var _base;
|
||||||
return (_base = HTMLCanvasElement.prototype).toBlob || (_base.toBlob = function(cb) {
|
return (_base = HTMLCanvasElement.prototype).toBlob || (_base.toBlob = function(cb) {
|
||||||
@ -4161,26 +4144,6 @@
|
|||||||
type: 'image/png'
|
type: 'image/png'
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
},
|
|
||||||
visibility: function() {
|
|
||||||
if ('visibilityState' in d) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Object.defineProperties(HTMLDocument.prototype, {
|
|
||||||
visibilityState: {
|
|
||||||
get: function() {
|
|
||||||
return this.webkitVisibilityState;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hidden: {
|
|
||||||
get: function() {
|
|
||||||
return this.webkitHidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return $.on(d, 'webkitvisibilitychange', function() {
|
|
||||||
return $.event('visibilitychange');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5234,6 +5197,7 @@
|
|||||||
return +window.location.pathname.split('/')[2];
|
return +window.location.pathname.split('/')[2];
|
||||||
},
|
},
|
||||||
userPageNav: function(pageNum) {
|
userPageNav: function(pageNum) {
|
||||||
|
Navigate.pushState(pageNum === 0 ? './' : pageNum);
|
||||||
if (Conf['Refreshed Navigation'] && Conf['Index Mode'] !== 'all pages') {
|
if (Conf['Refreshed Navigation'] && Conf['Index Mode'] !== 'all pages') {
|
||||||
return Index.update(pageNum);
|
return Index.update(pageNum);
|
||||||
} else {
|
} else {
|
||||||
@ -5244,7 +5208,7 @@
|
|||||||
if (Index.currentPage === pageNum && !Index.root.parentElement) {
|
if (Index.currentPage === pageNum && !Index.root.parentElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
history.pushState(null, '', pageNum === 0 ? './' : pageNum);
|
Navigate.pushState(pageNum === 0 ? './' : pageNum);
|
||||||
return Index.pageLoad(pageNum);
|
return Index.pageLoad(pageNum);
|
||||||
},
|
},
|
||||||
pageLoad: function(pageNum) {
|
pageLoad: function(pageNum) {
|
||||||
@ -5829,12 +5793,12 @@
|
|||||||
o.file = {
|
o.file = {
|
||||||
name: data.filename + data.ext,
|
name: data.filename + data.ext,
|
||||||
timestamp: "" + data.tim + data.ext,
|
timestamp: "" + data.tim + data.ext,
|
||||||
url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/src/" + data.filename + data.ext : "//i.4cdn.org/" + boardID + "/src/" + data.tim + data.ext,
|
url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + data.filename + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext,
|
||||||
height: data.h,
|
height: data.h,
|
||||||
width: data.w,
|
width: data.w,
|
||||||
MD5: data.md5,
|
MD5: data.md5,
|
||||||
size: data.fsize,
|
size: data.fsize,
|
||||||
turl: "//" + (Build.thumbRotate()) + ".t.4cdn.org/" + boardID + "/thumb/" + data.tim + "s.jpg",
|
turl: "//" + (Build.thumbRotate()) + ".t.4cdn.org/" + boardID + "/" + data.tim + "s.jpg",
|
||||||
theight: data.tn_h,
|
theight: data.tn_h,
|
||||||
twidth: data.tn_w,
|
twidth: data.tn_w,
|
||||||
isSpoiler: !!data.spoiler,
|
isSpoiler: !!data.spoiler,
|
||||||
@ -5921,14 +5885,14 @@
|
|||||||
if (isOP && g.VIEW === 'index') {
|
if (isOP && g.VIEW === 'index') {
|
||||||
pageNum = Math.floor(Index.liveThreadData.keys.indexOf("" + postID) / Index.threadsNumPerPage);
|
pageNum = Math.floor(Index.liveThreadData.keys.indexOf("" + postID) / Index.threadsNumPerPage);
|
||||||
pageIcon = " <span class=page-num title='This thread is on page " + pageNum + " in the original index.'>Page " + pageNum + "</span>";
|
pageIcon = " <span class=page-num title='This thread is on page " + pageNum + " in the original index.'>Page " + pageNum + "</span>";
|
||||||
replyLink = " <span>[<a href='/" + boardID + "/res/" + threadID + "' class=replylink>Reply</a>]</span>";
|
replyLink = " <span>[<a href='/" + boardID + "/thread/" + threadID + "' class=replylink>Reply</a>]</span>";
|
||||||
} else {
|
} else {
|
||||||
pageIcon = replyLink = '';
|
pageIcon = replyLink = '';
|
||||||
}
|
}
|
||||||
container = $.el('div', {
|
container = $.el('div', {
|
||||||
id: "pc" + postID,
|
id: "pc" + postID,
|
||||||
className: "postContainer " + (isOP ? 'op' : 'reply') + "Container",
|
className: "postContainer " + (isOP ? 'op' : 'reply') + "Container",
|
||||||
innerHTML: "" + (isOP ? '' : "<div class=sideArrows>>></div>") + "<div id=p" + postID + " class='post " + (isOP ? 'op' : 'reply') + (capcodeIcon === 'admin_highlight' ? ' highlightPost' : '') + "'>" + (isOP ? fileHTML : '') + "<div class='postInfo'><input type=checkbox name=" + postID + " value=delete>" + ' ' + "<span class=subject>" + (subject || '') + "</span>" + ' ' + "<span class='nameBlock" + capcodeClass + "'>" + emailStart + "<span class=name>" + (name || '') + "</span>" + (tripcode + capcodeStart + emailEnd + capcodeIcon + userID + flag) + "</span>" + " " + "<span class=dateTime data-utc=" + dateUTC + ">" + date + "</span>" + ' ' + "<span class='postNum'><a href=" + ("/" + boardID + "/res/" + threadID + "#p" + postID) + " title='Highlight this post'>No.</a><a href='" + (g.VIEW === 'thread' && g.THREADID === +threadID ? "javascript:quote(" + postID + ")" : "/" + boardID + "/res/" + threadID + "#q" + postID) + "' title='Quote this post'>" + postID + "</a>" + (pageIcon + sticky + closed + replyLink) + "</span></div>" + (isOP ? '' : fileHTML) + "<blockquote class=postMessage>" + (comment || '') + "</blockquote>" + ' ' + "</div>"
|
innerHTML: (isOP ? '' : "<div class=sideArrows>>></div>") + ("<div id=p" + postID + " class='post " + (isOP ? 'op' : 'reply') + (capcode === 'admin_highlight' ? ' highlightPost' : '') + "'>") + (isOP ? fileHTML : '') + "<div class=postInfo>" + ("<input type=checkbox name=" + postID + " value=delete> ") + ("<span class=subject>" + (subject || '') + "</span> ") + ("<span class='nameBlock" + capcodeClass + "'>") + emailStart + ("<span class=name>" + (name || '') + "</span>") + tripcode + capcodeStart + emailEnd + capcodeIcon + userID + flag + ' </span> ' + ("<span class=dateTime data-utc=" + dateUTC + ">" + date + "</span> ") + "<span class='postNum'>" + ("<a href=" + ("/" + boardID + "/thread/" + threadID + "#p" + postID) + " title='Highlight this post'>No.</a>") + ("<a href='" + (g.VIEW === 'thread' && g.THREADID === threadID ? "javascript:quote(" + postID + ")" : "/" + boardID + "/thread/" + threadID + "#q" + postID) + "' title='Quote this post'>" + postID + "</a>") + pageIcon + sticky + closed + replyLink + '</span>' + '</div>' + (isOP ? '' : fileHTML) + ("<blockquote class=postMessage>" + (comment || '') + "</blockquote> ") + '</div>'
|
||||||
});
|
});
|
||||||
_ref = $$('.quotelink', container);
|
_ref = $$('.quotelink', container);
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
@ -5937,7 +5901,7 @@
|
|||||||
if (href[0] === '/') {
|
if (href[0] === '/') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
quote.href = "/" + boardID + "/res/" + href;
|
quote.href = "/" + boardID + "/thread/" + href;
|
||||||
}
|
}
|
||||||
return container;
|
return container;
|
||||||
},
|
},
|
||||||
@ -5952,7 +5916,7 @@
|
|||||||
return $.el('a', {
|
return $.el('a', {
|
||||||
className: 'summary',
|
className: 'summary',
|
||||||
textContent: text.join(' '),
|
textContent: text.join(' '),
|
||||||
href: "/" + boardID + "/res/" + threadID
|
href: "/" + boardID + "/thread/" + threadID
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
thread: function(board, data, full) {
|
thread: function(board, data, full) {
|
||||||
@ -5993,7 +5957,7 @@
|
|||||||
comment = thread.OP.nodes.comment.innerHTML.replace(/(<br>\s*){2,}/g, '<br>');
|
comment = thread.OP.nodes.comment.innerHTML.replace(/(<br>\s*){2,}/g, '<br>');
|
||||||
root = $.el('div', {
|
root = $.el('div', {
|
||||||
className: 'catalog-thread',
|
className: 'catalog-thread',
|
||||||
innerHTML: "<a href=\"/" + thread.board + "/res/" + thread.ID + "\" class=\"thumb\"></a><div class=\"thread-stats\" title=\"Post count / File count / Page count\"><span class=\"post-count\">" + postCount + "</span> / <span class=\"file-count\">" + fileCount + "</span> / <span class=\"page-count\">" + pageCount + "</span><span class=\"thread-icons\"></span></div>" + subject + "<div class=\"comment\">" + comment + "</div>"
|
innerHTML: "<a href=\"/" + thread.board + "/thread/" + thread.ID + "\" class=\"thumb\"></a><div class=\"thread-stats\" title=\"Post count / File count / Page count\"><span class=\"post-count\">" + postCount + "</span> / <span class=\"file-count\">" + fileCount + "</span> / <span class=\"page-count\">" + pageCount + "</span><span class=\"thread-icons\"></span></div>" + subject + "<div class=\"comment\">" + comment + "</div>"
|
||||||
});
|
});
|
||||||
root.dataset.fullID = thread.fullID;
|
root.dataset.fullID = thread.fullID;
|
||||||
if (thread.isPinned) {
|
if (thread.isPinned) {
|
||||||
@ -6151,7 +6115,7 @@
|
|||||||
}
|
}
|
||||||
root.textContent = "Loading post No." + postID + "...";
|
root.textContent = "Loading post No." + postID + "...";
|
||||||
if (threadID) {
|
if (threadID) {
|
||||||
return $.cache("//a.4cdn.org/" + boardID + "/res/" + threadID + ".json", function() {
|
return $.cache("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", function() {
|
||||||
return Get.fetchedPost(this, boardID, threadID, postID, root, context);
|
return Get.fetchedPost(this, boardID, threadID, postID, root, context);
|
||||||
});
|
});
|
||||||
} else if (url = Redirect.to('post', {
|
} else if (url = Redirect.to('post', {
|
||||||
@ -6285,7 +6249,7 @@
|
|||||||
width: data.media.media_w,
|
width: data.media.media_w,
|
||||||
MD5: data.media.media_hash,
|
MD5: data.media.media_hash,
|
||||||
size: data.media.media_size,
|
size: data.media.media_size,
|
||||||
turl: data.media.thumb_link || ("//t.4cdn.org/" + boardID + "/thumb/" + data.media.preview_orig),
|
turl: data.media.thumb_link || ("//t.4cdn.org/" + boardID + "/" + data.media.preview_orig),
|
||||||
theight: data.media.preview_h,
|
theight: data.media.preview_h,
|
||||||
twidth: data.media.preview_w,
|
twidth: data.media.preview_w,
|
||||||
isSpoiler: data.media.spoiler === '1'
|
isSpoiler: data.media.spoiler === '1'
|
||||||
@ -7060,27 +7024,10 @@
|
|||||||
href: 'javascript:;',
|
href: 'javascript:;',
|
||||||
textContent: '\uf196'
|
textContent: '\uf196'
|
||||||
});
|
});
|
||||||
Post.callbacks.push({
|
return Post.callbacks.push({
|
||||||
name: 'Post Hiding',
|
name: 'Post Hiding',
|
||||||
cb: this.node
|
cb: this.node
|
||||||
});
|
});
|
||||||
return $.get('hiddenThreads', null, function(_arg) {
|
|
||||||
var board, boardID, hiddenThreads, threadID, val, _base, _base1, _ref;
|
|
||||||
hiddenThreads = _arg.hiddenThreads;
|
|
||||||
if (!hiddenThreads) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ref = hiddenThreads.boards;
|
|
||||||
for (boardID in _ref) {
|
|
||||||
board = _ref[boardID];
|
|
||||||
for (threadID in board) {
|
|
||||||
val = board[threadID];
|
|
||||||
((_base = ((_base1 = PostHiding.db.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[threadID] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PostHiding.db.save();
|
|
||||||
return $["delete"]('hiddenThreads');
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var a, data, label;
|
var a, data, label;
|
||||||
@ -7481,7 +7428,7 @@
|
|||||||
var a, frag, hash, text;
|
var a, frag, hash, text;
|
||||||
frag = QuoteBacklink.frag.cloneNode(true);
|
frag = QuoteBacklink.frag.cloneNode(true);
|
||||||
a = frag.lastElementChild;
|
a = frag.lastElementChild;
|
||||||
a.href = "/" + quoter.board + "/res/" + quoter.thread + "#p" + quoter;
|
a.href = "/" + quoter.board + "/thread/" + quoter.thread + "#p" + quoter;
|
||||||
a.textContent = text = QuoteBacklink.funk(quoter.ID);
|
a.textContent = text = QuoteBacklink.funk(quoter.ID);
|
||||||
if (quoter.isDead) {
|
if (quoter.isDead) {
|
||||||
$.addClass(a, 'deadlink');
|
$.addClass(a, 'deadlink');
|
||||||
@ -8053,7 +8000,7 @@
|
|||||||
quoteID = "" + boardID + "." + postID;
|
quoteID = "" + boardID + "." + postID;
|
||||||
if (post = g.posts[quoteID]) {
|
if (post = g.posts[quoteID]) {
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
href: "/" + boardID + "/res/" + post.thread + "#p" + postID,
|
href: "/" + boardID + "/thread/" + post.thread + "#p" + postID,
|
||||||
className: post.isDead ? 'quotelink deadlink' : 'quotelink',
|
className: post.isDead ? 'quotelink deadlink' : 'quotelink',
|
||||||
textContent: quote
|
textContent: quote
|
||||||
});
|
});
|
||||||
@ -8912,7 +8859,9 @@
|
|||||||
_ref = $$('br', frag);
|
_ref = $$('br', frag);
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
node = _ref[_i];
|
node = _ref[_i];
|
||||||
$.replace(node, $.tn('\n>'));
|
if (node !== frag.lastElementChild) {
|
||||||
|
$.replace(node, $.tn('\n>'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ref1 = $$('s', frag);
|
_ref1 = $$('s', frag);
|
||||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||||
@ -10801,8 +10750,12 @@
|
|||||||
delete post.file.videoControls;
|
delete post.file.videoControls;
|
||||||
}
|
}
|
||||||
$.rmClass(post.nodes.root, 'expanded-image');
|
$.rmClass(post.nodes.root, 'expanded-image');
|
||||||
$.rmClass(thumb, 'expanding');
|
$.rmClass(post.file.thumb, 'expanding');
|
||||||
return post.file.isExpanded = false;
|
delete post.file.isExpanding;
|
||||||
|
delete post.file.isExpanded;
|
||||||
|
if (post.file.isVideo && post.file.fullImage) {
|
||||||
|
return post.file.fullImage.pause();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
expand: function(post, src, disableAutoplay) {
|
expand: function(post, src, disableAutoplay) {
|
||||||
var el, isVideo, thumb, _ref;
|
var el, isVideo, thumb, _ref;
|
||||||
@ -10918,19 +10871,40 @@
|
|||||||
return $.add(file.text, file.videoControls);
|
return $.add(file.text, file.videoControls);
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function() {
|
||||||
var URL, post, src, timeoutID;
|
var URL, error, post, src, timeoutID;
|
||||||
post = Get.postFromNode(this);
|
post = Get.postFromNode(this);
|
||||||
$.rm(this);
|
$.rm(this);
|
||||||
|
delete post.file.isReady;
|
||||||
delete post.file.fullImage;
|
delete post.file.fullImage;
|
||||||
if (!($.hasClass(post.file.thumb, 'expanding') || $.hasClass(post.nodes.root, 'expanded-image'))) {
|
if (!($.hasClass(post.file.thumb, 'expanding') || $.hasClass(post.nodes.root, 'expanded-image'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ImageExpand.contract(post);
|
ImageExpand.contract(post);
|
||||||
|
if (this.error && this.error.code !== this.error.MEDIA_ERR_NETWORK) {
|
||||||
|
error = (function() {
|
||||||
|
switch (this.error.code) {
|
||||||
|
case 1:
|
||||||
|
return 'MEDIA_ERR_ABORTED';
|
||||||
|
case 3:
|
||||||
|
return 'MEDIA_ERR_DECODE';
|
||||||
|
case 4:
|
||||||
|
return 'MEDIA_ERR_SRC_NOT_SUPPORTED';
|
||||||
|
case 5:
|
||||||
|
return 'MEDIA_ERR_ENCRYPTED';
|
||||||
|
}
|
||||||
|
}).call(this);
|
||||||
|
post.file.error = $.el('div', {
|
||||||
|
textContent: "Playback error: " + error,
|
||||||
|
className: 'warning'
|
||||||
|
});
|
||||||
|
$.after(post.file.thumb, post.file.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
src = this.src.split('/');
|
src = this.src.split('/');
|
||||||
if (src[2] === 'i.4cdn.org') {
|
if (src[2] === 'i.4cdn.org') {
|
||||||
URL = Redirect.to('file', {
|
URL = Redirect.to('file', {
|
||||||
boardID: src[3],
|
boardID: src[3],
|
||||||
filename: src[5]
|
filename: src[4].replace(/\?.+$/, '')
|
||||||
});
|
});
|
||||||
if (URL) {
|
if (URL) {
|
||||||
setTimeout(ImageExpand.expand, 10000, post, URL);
|
setTimeout(ImageExpand.expand, 10000, post, URL);
|
||||||
@ -10941,7 +10915,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
timeoutID = setTimeout(ImageExpand.expand, 10000, post);
|
timeoutID = setTimeout(ImageExpand.expand, 10000, post);
|
||||||
return $.ajax("//a.4cdn.org/" + post.board + "/res/" + post.thread + ".json", {
|
return $.ajax("//a.4cdn.org/" + post.board + "/thread/" + post.thread + ".json", {
|
||||||
onload: function() {
|
onload: function() {
|
||||||
var postObj, _i, _len, _ref;
|
var postObj, _i, _len, _ref;
|
||||||
if (this.status !== 200) {
|
if (this.status !== 200) {
|
||||||
@ -11046,7 +11020,6 @@
|
|||||||
TrashQueue.remove(el);
|
TrashQueue.remove(el);
|
||||||
} else {
|
} else {
|
||||||
el = $.el((isVideo ? 'video' : 'img'), {
|
el = $.el((isVideo ? 'video' : 'img'), {
|
||||||
className: 'full-image',
|
|
||||||
src: post.file.URL
|
src: post.file.URL
|
||||||
});
|
});
|
||||||
post.file.fullImage = el;
|
post.file.fullImage = el;
|
||||||
@ -11076,10 +11049,11 @@
|
|||||||
el: el,
|
el: el,
|
||||||
latestEvent: e,
|
latestEvent: e,
|
||||||
endEvents: 'mouseout click',
|
endEvents: 'mouseout click',
|
||||||
asapTest: function() {
|
asapTest: post.file.isImage ? function() {
|
||||||
return el.videoHeight || el.naturalHeight;
|
return el.naturalHeight;
|
||||||
|
} : function() {
|
||||||
|
return el.readyState >= el.HAVE_CURRENT_DATA;
|
||||||
},
|
},
|
||||||
noRemove: true,
|
|
||||||
cb: function() {
|
cb: function() {
|
||||||
if (isVideo) {
|
if (isVideo) {
|
||||||
el.pause();
|
el.pause();
|
||||||
@ -11100,7 +11074,7 @@
|
|||||||
if (src[2] === 'i.4cdn.org') {
|
if (src[2] === 'i.4cdn.org') {
|
||||||
URL = Redirect.to('file', {
|
URL = Redirect.to('file', {
|
||||||
boardID: src[3],
|
boardID: src[3],
|
||||||
filename: src[5].replace(/\?.+$/, '')
|
filename: src[4].replace(/\?.+$/, '')
|
||||||
});
|
});
|
||||||
if (URL) {
|
if (URL) {
|
||||||
this.src = URL;
|
this.src = URL;
|
||||||
@ -11115,7 +11089,7 @@
|
|||||||
return _this.src = post.file.URL + '?' + Date.now();
|
return _this.src = post.file.URL + '?' + Date.now();
|
||||||
};
|
};
|
||||||
})(this)), 3000);
|
})(this)), 3000);
|
||||||
return $.ajax("//a.4cdn.org/" + post.board + "/res/" + post.thread + ".json", {
|
return $.ajax("//a.4cdn.org/" + post.board + "/thread/" + post.thread + ".json", {
|
||||||
onload: function() {
|
onload: function() {
|
||||||
var postObj, _i, _len, _ref;
|
var postObj, _i, _len, _ref;
|
||||||
if (this.status !== 200) {
|
if (this.status !== 200) {
|
||||||
@ -12167,9 +12141,12 @@
|
|||||||
if ((_ref = ThreadUpdater.req) != null) {
|
if ((_ref = ThreadUpdater.req) != null) {
|
||||||
_ref.abort();
|
_ref.abort();
|
||||||
}
|
}
|
||||||
url = "//a.4cdn.org/" + ThreadUpdater.thread.board + "/res/" + ThreadUpdater.thread + ".json";
|
url = "//a.4cdn.org/" + ThreadUpdater.thread.board + "/thread/" + ThreadUpdater.thread + ".json";
|
||||||
return ThreadUpdater.req = $.ajax(url, {
|
return ThreadUpdater.req = $.ajax(url, {
|
||||||
onloadend: ThreadUpdater.cb.load
|
onabort: ThreadUpdater.cb.load,
|
||||||
|
onloadend: ThreadUpdater.cb.load,
|
||||||
|
ontimeout: ThreadUpdater.cb.load,
|
||||||
|
timeout: $.MINUTE
|
||||||
}, {
|
}, {
|
||||||
whenModified: true
|
whenModified: true
|
||||||
});
|
});
|
||||||
@ -12467,7 +12444,7 @@
|
|||||||
}
|
}
|
||||||
fetchCount = ThreadWatcher.fetchCount;
|
fetchCount = ThreadWatcher.fetchCount;
|
||||||
fetchCount.fetching++;
|
fetchCount.fetching++;
|
||||||
return $.ajax("//a.4cdn.org/" + boardID + "/res/" + threadID + ".json", {
|
return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
|
||||||
onloadend: function() {
|
onloadend: function() {
|
||||||
var status;
|
var status;
|
||||||
fetchCount.fetched++;
|
fetchCount.fetched++;
|
||||||
@ -12536,7 +12513,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
link = $.el('a', {
|
link = $.el('a', {
|
||||||
href: href || ("/" + boardID + "/res/" + threadID),
|
href: href || ("/" + boardID + "/thread/" + threadID),
|
||||||
textContent: data.excerpt,
|
textContent: data.excerpt,
|
||||||
title: data.excerpt
|
title: data.excerpt
|
||||||
});
|
});
|
||||||
@ -15233,7 +15210,7 @@
|
|||||||
var status;
|
var status;
|
||||||
ExpandThread.statuses[thread] = status = {};
|
ExpandThread.statuses[thread] = status = {};
|
||||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(__slice.call(a.textContent.match(/\d+/g))));
|
a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(__slice.call(a.textContent.match(/\d+/g))));
|
||||||
return status.req = $.cache("//a.4cdn.org/" + thread.board + "/res/" + thread + ".json", function() {
|
return status.req = $.cache("//a.4cdn.org/" + thread.board + "/thread/" + thread + ".json", function() {
|
||||||
delete status.req;
|
delete status.req;
|
||||||
return ExpandThread.parse(this, thread, a);
|
return ExpandThread.parse(this, thread, a);
|
||||||
});
|
});
|
||||||
@ -15733,7 +15710,7 @@
|
|||||||
return Conf[hotkey] = key;
|
return Conf[hotkey] = key;
|
||||||
},
|
},
|
||||||
keydown: function(e) {
|
keydown: function(e) {
|
||||||
var key, notification, notifications, op, target, thread, threadRoot, _i, _len, _ref;
|
var form, key, notification, notifications, op, target, thread, threadRoot, _i, _len, _ref;
|
||||||
if (!(key = Keybinds.keyCode(e))) {
|
if (!(key = Keybinds.keyCode(e))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -15827,7 +15804,9 @@
|
|||||||
ThreadUpdater.update();
|
ThreadUpdater.update();
|
||||||
break;
|
break;
|
||||||
case 'index':
|
case 'index':
|
||||||
Index.update();
|
if (Conf['JSON Navigation']) {
|
||||||
|
Index.update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Conf['Watch']:
|
case Conf['Watch']:
|
||||||
@ -15853,7 +15832,7 @@
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case Conf['Front page']:
|
case Conf['Front page']:
|
||||||
if (g.VIEW === 'index') {
|
if (Conf['JSON Navigation'] && g.VIEW === 'index') {
|
||||||
Index.userPageNav(0);
|
Index.userPageNav(0);
|
||||||
} else {
|
} else {
|
||||||
window.location = "/" + g.BOARD + "/";
|
window.location = "/" + g.BOARD + "/";
|
||||||
@ -15863,19 +15842,39 @@
|
|||||||
$.open("/" + g.BOARD + "/");
|
$.open("/" + g.BOARD + "/");
|
||||||
break;
|
break;
|
||||||
case Conf['Next page']:
|
case Conf['Next page']:
|
||||||
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'all pages')) {
|
if (g.VIEW !== 'index') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$('.next button, .next a', Index.pagelist).click();
|
if (Conf['JSON Navigation']) {
|
||||||
|
if (Conf['Index Mode'] !== 'all pages') {
|
||||||
|
$('.next button', Index.pagelist).click();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (form = $('.next form')) {
|
||||||
|
window.location = form.action;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Conf['Previous page']:
|
case Conf['Previous page']:
|
||||||
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'all pages')) {
|
if (g.VIEW !== 'index') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$('.prev button, .prev a', Index.pagelist).click();
|
if (Conf['JSON Navigation']) {
|
||||||
|
if (Conf['Index Mode'] !== 'all pages') {
|
||||||
|
$('.prev button', Index.pagelist).click();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (form = $('.prev form')) {
|
||||||
|
window.location = form.action;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Conf['Search form']:
|
case Conf['Search form']:
|
||||||
Index.searchInput.focus();
|
if (Conf['JSON Navigation']) {
|
||||||
|
Index.searchInput.focus();
|
||||||
|
} else {
|
||||||
|
$.id('search-btn').click();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Conf['Paged mode']:
|
case Conf['Paged mode']:
|
||||||
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'paged')) {
|
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'paged')) {
|
||||||
@ -15901,6 +15900,19 @@
|
|||||||
}
|
}
|
||||||
Index.cycleSortType();
|
Index.cycleSortType();
|
||||||
break;
|
break;
|
||||||
|
case Conf['Open catalog']:
|
||||||
|
if (Conf['External Catalog']) {
|
||||||
|
window.location = CatalogLinks.external(g.BOARD.ID);
|
||||||
|
} else {
|
||||||
|
if (!Conf['JSON Navigation']) {
|
||||||
|
return window.location = "/" + g.BOARD + "/catalog";
|
||||||
|
}
|
||||||
|
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'catalog')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Index.setIndexMode('catalog');
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Conf['Next thread']:
|
case Conf['Next thread']:
|
||||||
if (g.VIEW !== 'index') {
|
if (g.VIEW !== 'index') {
|
||||||
return;
|
return;
|
||||||
@ -16033,7 +16045,7 @@
|
|||||||
if (g.VIEW !== 'index') {
|
if (g.VIEW !== 'index') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
url = "/" + thread.board + "/res/" + thread;
|
url = "/" + thread.board + "/thread/" + thread;
|
||||||
if (tab) {
|
if (tab) {
|
||||||
return $.open(url);
|
return $.open(url);
|
||||||
} else {
|
} else {
|
||||||
@ -16651,7 +16663,7 @@
|
|||||||
if (threadID) {
|
if (threadID) {
|
||||||
view = 'thread';
|
view = 'thread';
|
||||||
} else {
|
} else {
|
||||||
pageNum = view;
|
pageNum = +view;
|
||||||
view = 'index';
|
view = 'index';
|
||||||
}
|
}
|
||||||
path = this.pathname;
|
path = this.pathname;
|
||||||
@ -16660,9 +16672,8 @@
|
|||||||
}
|
}
|
||||||
Navigate.makeBreadCrumb(this.href, view, boardID, threadID);
|
Navigate.makeBreadCrumb(this.href, view, boardID, threadID);
|
||||||
if (this.id !== 'popState') {
|
if (this.id !== 'popState') {
|
||||||
history.pushState('internal', '', path);
|
Navigate.pushState(path);
|
||||||
}
|
}
|
||||||
Navigate.path = this.pathname;
|
|
||||||
Navigate.setMode(this);
|
Navigate.setMode(this);
|
||||||
if (!(view === 'index' && 'index' === g.VIEW && boardID === g.BOARD.ID)) {
|
if (!(view === 'index' && 'index' === g.VIEW && boardID === g.BOARD.ID)) {
|
||||||
Navigate.disconnect();
|
Navigate.disconnect();
|
||||||
@ -16786,6 +16797,10 @@
|
|||||||
return Main.handleErrors(errors);
|
return Main.handleErrors(errors);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
pushState: function(path) {
|
||||||
|
history.pushState(null, '', path);
|
||||||
|
return Navigate.path = window.location.pathname;
|
||||||
|
},
|
||||||
popstate: function() {
|
popstate: function() {
|
||||||
var a;
|
var a;
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
@ -17251,7 +17266,7 @@
|
|||||||
data = {
|
data = {
|
||||||
isReply: true,
|
isReply: true,
|
||||||
file: {
|
file: {
|
||||||
URL: '//i.4cdn.org/g/src/1334437723720.jpg',
|
URL: '//i.4cdn.org/g/1334437723720.jpg',
|
||||||
name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg',
|
name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg',
|
||||||
size: '276 KB',
|
size: '276 KB',
|
||||||
sizeInBytes: 276 * 1024,
|
sizeInBytes: 276 * 1024,
|
||||||
@ -17874,6 +17889,7 @@
|
|||||||
g.VIEW = (function() {
|
g.VIEW = (function() {
|
||||||
switch (pathname[2]) {
|
switch (pathname[2]) {
|
||||||
case 'res':
|
case 'res':
|
||||||
|
case 'thread':
|
||||||
return 'thread';
|
return 'thread';
|
||||||
case 'catalog':
|
case 'catalog':
|
||||||
return 'catalog';
|
return 'catalog';
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
"run_at": "document_start"
|
"run_at": "document_start"
|
||||||
}],
|
}],
|
||||||
"homepage_url": "http://zixaphir.github.com/appchan-x/",
|
"homepage_url": "http://zixaphir.github.com/appchan-x/",
|
||||||
"minimum_chrome_version": "32",
|
"minimum_chrome_version": "33",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"storage",
|
"storage",
|
||||||
"http://*/",
|
"http://*/",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Generated by CoffeeScript
|
// Generated by CoffeeScript
|
||||||
/*
|
/*
|
||||||
* appchan x - Version 2.9.15 - 2014-04-11
|
* appchan x - Version 2.9.15 - 2014-04-19
|
||||||
*
|
*
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||||
@ -403,8 +403,8 @@
|
|||||||
'Open Gallery': ['g', 'Opens the gallery.'],
|
'Open Gallery': ['g', 'Opens the gallery.'],
|
||||||
'fappeTyme': ['f', 'Fappe Tyme.'],
|
'fappeTyme': ['f', 'Fappe Tyme.'],
|
||||||
'werkTyme': ['Shift+w', 'Werk Tyme'],
|
'werkTyme': ['Shift+w', 'Werk Tyme'],
|
||||||
'Front page': ['0', 'Jump to page 0.'],
|
'Front page': ['0', 'Jump to front page.'],
|
||||||
'Open front page': ['Shift+0', 'Open page 0 in a new tab.'],
|
'Open front page': ['Shift+0', 'Open front page in a new tab.'],
|
||||||
'Next page': ['Shift+Right', 'Jump to the next page.'],
|
'Next page': ['Shift+Right', 'Jump to the next page.'],
|
||||||
'Previous page': ['Shift+Left', 'Jump to the previous page.'],
|
'Previous page': ['Shift+Left', 'Jump to the previous page.'],
|
||||||
'Search form': ['Ctrl+Alt+s', 'Focus the search field on the board index.'],
|
'Search form': ['Ctrl+Alt+s', 'Focus the search field on the board index.'],
|
||||||
@ -3419,7 +3419,7 @@
|
|||||||
|
|
||||||
Post.prototype.parseQuote = function(quotelink) {
|
Post.prototype.parseQuote = function(quotelink) {
|
||||||
var fullID, match;
|
var fullID, match;
|
||||||
if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/res\/\d+#p(\d+)$/))) {
|
if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/thread\/\d+#p(\d+)$/))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.nodes.quotelinks.push(quotelink);
|
this.nodes.quotelinks.push(quotelink);
|
||||||
@ -3453,7 +3453,7 @@
|
|||||||
size *= 1024;
|
size *= 1024;
|
||||||
}
|
}
|
||||||
this.file.sizeInBytes = size;
|
this.file.sizeInBytes = size;
|
||||||
this.file.thumbURL = that.isArchived ? thumb.src : "" + location.protocol + "//t.4cdn.org/" + this.board + "/thumb/" + (this.file.URL.match(/(\d+)\./)[1]) + "s.jpg";
|
this.file.thumbURL = that.isArchived ? thumb.src : "" + location.protocol + "//t.4cdn.org/" + this.board + "/" + (this.file.URL.match(/(\d+)\./)[1]) + "s.jpg";
|
||||||
this.file.name = (nameNode = $('span', fileText)) ? nameNode.title || nameNode.textContent : fileText.title;
|
this.file.name = (nameNode = $('span', fileText)) ? nameNode.title || nameNode.textContent : fileText.title;
|
||||||
this.file.name = this.file.name.replace(/%22/g, '"');
|
this.file.name = this.file.name.replace(/%22/g, '"');
|
||||||
this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name);
|
this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name);
|
||||||
@ -4186,26 +4186,7 @@
|
|||||||
|
|
||||||
Polyfill = {
|
Polyfill = {
|
||||||
init: function() {
|
init: function() {
|
||||||
this.notificationPermission();
|
return this.toBlob();
|
||||||
this.toBlob();
|
|
||||||
return this.visibility();
|
|
||||||
},
|
|
||||||
notificationPermission: function() {
|
|
||||||
if (!window.Notification || 'permission' in Notification || !window.webkitNotifications) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return Object.defineProperty(Notification, 'permission', {
|
|
||||||
get: function() {
|
|
||||||
switch (webkitNotifications.checkPermission()) {
|
|
||||||
case 0:
|
|
||||||
return 'granted';
|
|
||||||
case 1:
|
|
||||||
return 'default';
|
|
||||||
case 2:
|
|
||||||
return 'denied';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
toBlob: function() {
|
toBlob: function() {
|
||||||
var _base;
|
var _base;
|
||||||
@ -4221,26 +4202,6 @@
|
|||||||
type: 'image/png'
|
type: 'image/png'
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
},
|
|
||||||
visibility: function() {
|
|
||||||
if ('visibilityState' in d) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Object.defineProperties(HTMLDocument.prototype, {
|
|
||||||
visibilityState: {
|
|
||||||
get: function() {
|
|
||||||
return this.webkitVisibilityState;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hidden: {
|
|
||||||
get: function() {
|
|
||||||
return this.webkitHidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return $.on(d, 'webkitvisibilitychange', function() {
|
|
||||||
return $.event('visibilitychange');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5294,6 +5255,7 @@
|
|||||||
return +window.location.pathname.split('/')[2];
|
return +window.location.pathname.split('/')[2];
|
||||||
},
|
},
|
||||||
userPageNav: function(pageNum) {
|
userPageNav: function(pageNum) {
|
||||||
|
Navigate.pushState(pageNum === 0 ? './' : pageNum);
|
||||||
if (Conf['Refreshed Navigation'] && Conf['Index Mode'] !== 'all pages') {
|
if (Conf['Refreshed Navigation'] && Conf['Index Mode'] !== 'all pages') {
|
||||||
return Index.update(pageNum);
|
return Index.update(pageNum);
|
||||||
} else {
|
} else {
|
||||||
@ -5304,7 +5266,7 @@
|
|||||||
if (Index.currentPage === pageNum && !Index.root.parentElement) {
|
if (Index.currentPage === pageNum && !Index.root.parentElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
history.pushState(null, '', pageNum === 0 ? './' : pageNum);
|
Navigate.pushState(pageNum === 0 ? './' : pageNum);
|
||||||
return Index.pageLoad(pageNum);
|
return Index.pageLoad(pageNum);
|
||||||
},
|
},
|
||||||
pageLoad: function(pageNum) {
|
pageLoad: function(pageNum) {
|
||||||
@ -5889,12 +5851,12 @@
|
|||||||
o.file = {
|
o.file = {
|
||||||
name: data.filename + data.ext,
|
name: data.filename + data.ext,
|
||||||
timestamp: "" + data.tim + data.ext,
|
timestamp: "" + data.tim + data.ext,
|
||||||
url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/src/" + data.filename + data.ext : "//i.4cdn.org/" + boardID + "/src/" + data.tim + data.ext,
|
url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + data.filename + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext,
|
||||||
height: data.h,
|
height: data.h,
|
||||||
width: data.w,
|
width: data.w,
|
||||||
MD5: data.md5,
|
MD5: data.md5,
|
||||||
size: data.fsize,
|
size: data.fsize,
|
||||||
turl: "//" + (Build.thumbRotate()) + ".t.4cdn.org/" + boardID + "/thumb/" + data.tim + "s.jpg",
|
turl: "//" + (Build.thumbRotate()) + ".t.4cdn.org/" + boardID + "/" + data.tim + "s.jpg",
|
||||||
theight: data.tn_h,
|
theight: data.tn_h,
|
||||||
twidth: data.tn_w,
|
twidth: data.tn_w,
|
||||||
isSpoiler: !!data.spoiler,
|
isSpoiler: !!data.spoiler,
|
||||||
@ -5981,14 +5943,14 @@
|
|||||||
if (isOP && g.VIEW === 'index') {
|
if (isOP && g.VIEW === 'index') {
|
||||||
pageNum = Math.floor(Index.liveThreadData.keys.indexOf("" + postID) / Index.threadsNumPerPage);
|
pageNum = Math.floor(Index.liveThreadData.keys.indexOf("" + postID) / Index.threadsNumPerPage);
|
||||||
pageIcon = " <span class=page-num title='This thread is on page " + pageNum + " in the original index.'>Page " + pageNum + "</span>";
|
pageIcon = " <span class=page-num title='This thread is on page " + pageNum + " in the original index.'>Page " + pageNum + "</span>";
|
||||||
replyLink = " <span>[<a href='/" + boardID + "/res/" + threadID + "' class=replylink>Reply</a>]</span>";
|
replyLink = " <span>[<a href='/" + boardID + "/thread/" + threadID + "' class=replylink>Reply</a>]</span>";
|
||||||
} else {
|
} else {
|
||||||
pageIcon = replyLink = '';
|
pageIcon = replyLink = '';
|
||||||
}
|
}
|
||||||
container = $.el('div', {
|
container = $.el('div', {
|
||||||
id: "pc" + postID,
|
id: "pc" + postID,
|
||||||
className: "postContainer " + (isOP ? 'op' : 'reply') + "Container",
|
className: "postContainer " + (isOP ? 'op' : 'reply') + "Container",
|
||||||
innerHTML: "" + (isOP ? '' : "<div class=sideArrows>>></div>") + "<div id=p" + postID + " class='post " + (isOP ? 'op' : 'reply') + (capcodeIcon === 'admin_highlight' ? ' highlightPost' : '') + "'>" + (isOP ? fileHTML : '') + "<div class='postInfo'><input type=checkbox name=" + postID + " value=delete>" + ' ' + "<span class=subject>" + (subject || '') + "</span>" + ' ' + "<span class='nameBlock" + capcodeClass + "'>" + emailStart + "<span class=name>" + (name || '') + "</span>" + (tripcode + capcodeStart + emailEnd + capcodeIcon + userID + flag) + "</span>" + " " + "<span class=dateTime data-utc=" + dateUTC + ">" + date + "</span>" + ' ' + "<span class='postNum'><a href=" + ("/" + boardID + "/res/" + threadID + "#p" + postID) + " title='Highlight this post'>No.</a><a href='" + (g.VIEW === 'thread' && g.THREADID === +threadID ? "javascript:quote(" + postID + ")" : "/" + boardID + "/res/" + threadID + "#q" + postID) + "' title='Quote this post'>" + postID + "</a>" + (pageIcon + sticky + closed + replyLink) + "</span></div>" + (isOP ? '' : fileHTML) + "<blockquote class=postMessage>" + (comment || '') + "</blockquote>" + ' ' + "</div>"
|
innerHTML: (isOP ? '' : "<div class=sideArrows>>></div>") + ("<div id=p" + postID + " class='post " + (isOP ? 'op' : 'reply') + (capcode === 'admin_highlight' ? ' highlightPost' : '') + "'>") + (isOP ? fileHTML : '') + "<div class=postInfo>" + ("<input type=checkbox name=" + postID + " value=delete> ") + ("<span class=subject>" + (subject || '') + "</span> ") + ("<span class='nameBlock" + capcodeClass + "'>") + emailStart + ("<span class=name>" + (name || '') + "</span>") + tripcode + capcodeStart + emailEnd + capcodeIcon + userID + flag + ' </span> ' + ("<span class=dateTime data-utc=" + dateUTC + ">" + date + "</span> ") + "<span class='postNum'>" + ("<a href=" + ("/" + boardID + "/thread/" + threadID + "#p" + postID) + " title='Highlight this post'>No.</a>") + ("<a href='" + (g.VIEW === 'thread' && g.THREADID === threadID ? "javascript:quote(" + postID + ")" : "/" + boardID + "/thread/" + threadID + "#q" + postID) + "' title='Quote this post'>" + postID + "</a>") + pageIcon + sticky + closed + replyLink + '</span>' + '</div>' + (isOP ? '' : fileHTML) + ("<blockquote class=postMessage>" + (comment || '') + "</blockquote> ") + '</div>'
|
||||||
});
|
});
|
||||||
_ref = $$('.quotelink', container);
|
_ref = $$('.quotelink', container);
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
@ -5997,7 +5959,7 @@
|
|||||||
if (href[0] === '/') {
|
if (href[0] === '/') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
quote.href = "/" + boardID + "/res/" + href;
|
quote.href = "/" + boardID + "/thread/" + href;
|
||||||
}
|
}
|
||||||
return container;
|
return container;
|
||||||
},
|
},
|
||||||
@ -6012,7 +5974,7 @@
|
|||||||
return $.el('a', {
|
return $.el('a', {
|
||||||
className: 'summary',
|
className: 'summary',
|
||||||
textContent: text.join(' '),
|
textContent: text.join(' '),
|
||||||
href: "/" + boardID + "/res/" + threadID
|
href: "/" + boardID + "/thread/" + threadID
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
thread: function(board, data, full) {
|
thread: function(board, data, full) {
|
||||||
@ -6053,7 +6015,7 @@
|
|||||||
comment = thread.OP.nodes.comment.innerHTML.replace(/(<br>\s*){2,}/g, '<br>');
|
comment = thread.OP.nodes.comment.innerHTML.replace(/(<br>\s*){2,}/g, '<br>');
|
||||||
root = $.el('div', {
|
root = $.el('div', {
|
||||||
className: 'catalog-thread',
|
className: 'catalog-thread',
|
||||||
innerHTML: "<a href=\"/" + thread.board + "/res/" + thread.ID + "\" class=\"thumb\"></a><div class=\"thread-stats\" title=\"Post count / File count / Page count\"><span class=\"post-count\">" + postCount + "</span> / <span class=\"file-count\">" + fileCount + "</span> / <span class=\"page-count\">" + pageCount + "</span><span class=\"thread-icons\"></span></div>" + subject + "<div class=\"comment\">" + comment + "</div>"
|
innerHTML: "<a href=\"/" + thread.board + "/thread/" + thread.ID + "\" class=\"thumb\"></a><div class=\"thread-stats\" title=\"Post count / File count / Page count\"><span class=\"post-count\">" + postCount + "</span> / <span class=\"file-count\">" + fileCount + "</span> / <span class=\"page-count\">" + pageCount + "</span><span class=\"thread-icons\"></span></div>" + subject + "<div class=\"comment\">" + comment + "</div>"
|
||||||
});
|
});
|
||||||
root.dataset.fullID = thread.fullID;
|
root.dataset.fullID = thread.fullID;
|
||||||
if (thread.isPinned) {
|
if (thread.isPinned) {
|
||||||
@ -6211,7 +6173,7 @@
|
|||||||
}
|
}
|
||||||
root.textContent = "Loading post No." + postID + "...";
|
root.textContent = "Loading post No." + postID + "...";
|
||||||
if (threadID) {
|
if (threadID) {
|
||||||
return $.cache("//a.4cdn.org/" + boardID + "/res/" + threadID + ".json", function() {
|
return $.cache("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", function() {
|
||||||
return Get.fetchedPost(this, boardID, threadID, postID, root, context);
|
return Get.fetchedPost(this, boardID, threadID, postID, root, context);
|
||||||
});
|
});
|
||||||
} else if (url = Redirect.to('post', {
|
} else if (url = Redirect.to('post', {
|
||||||
@ -6345,7 +6307,7 @@
|
|||||||
width: data.media.media_w,
|
width: data.media.media_w,
|
||||||
MD5: data.media.media_hash,
|
MD5: data.media.media_hash,
|
||||||
size: data.media.media_size,
|
size: data.media.media_size,
|
||||||
turl: data.media.thumb_link || ("//t.4cdn.org/" + boardID + "/thumb/" + data.media.preview_orig),
|
turl: data.media.thumb_link || ("//t.4cdn.org/" + boardID + "/" + data.media.preview_orig),
|
||||||
theight: data.media.preview_h,
|
theight: data.media.preview_h,
|
||||||
twidth: data.media.preview_w,
|
twidth: data.media.preview_w,
|
||||||
isSpoiler: data.media.spoiler === '1'
|
isSpoiler: data.media.spoiler === '1'
|
||||||
@ -7113,27 +7075,10 @@
|
|||||||
href: 'javascript:;',
|
href: 'javascript:;',
|
||||||
textContent: '\uf196'
|
textContent: '\uf196'
|
||||||
});
|
});
|
||||||
Post.callbacks.push({
|
return Post.callbacks.push({
|
||||||
name: 'Post Hiding',
|
name: 'Post Hiding',
|
||||||
cb: this.node
|
cb: this.node
|
||||||
});
|
});
|
||||||
return $.get('hiddenThreads', null, function(_arg) {
|
|
||||||
var board, boardID, hiddenThreads, threadID, val, _base, _base1, _ref;
|
|
||||||
hiddenThreads = _arg.hiddenThreads;
|
|
||||||
if (!hiddenThreads) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ref = hiddenThreads.boards;
|
|
||||||
for (boardID in _ref) {
|
|
||||||
board = _ref[boardID];
|
|
||||||
for (threadID in board) {
|
|
||||||
val = board[threadID];
|
|
||||||
((_base = ((_base1 = PostHiding.db.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[threadID] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PostHiding.db.save();
|
|
||||||
return $["delete"]('hiddenThreads');
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var a, data, label;
|
var a, data, label;
|
||||||
@ -7534,7 +7479,7 @@
|
|||||||
var a, frag, hash, text;
|
var a, frag, hash, text;
|
||||||
frag = QuoteBacklink.frag.cloneNode(true);
|
frag = QuoteBacklink.frag.cloneNode(true);
|
||||||
a = frag.lastElementChild;
|
a = frag.lastElementChild;
|
||||||
a.href = "/" + quoter.board + "/res/" + quoter.thread + "#p" + quoter;
|
a.href = "/" + quoter.board + "/thread/" + quoter.thread + "#p" + quoter;
|
||||||
a.textContent = text = QuoteBacklink.funk(quoter.ID);
|
a.textContent = text = QuoteBacklink.funk(quoter.ID);
|
||||||
if (quoter.isDead) {
|
if (quoter.isDead) {
|
||||||
$.addClass(a, 'deadlink');
|
$.addClass(a, 'deadlink');
|
||||||
@ -8106,7 +8051,7 @@
|
|||||||
quoteID = "" + boardID + "." + postID;
|
quoteID = "" + boardID + "." + postID;
|
||||||
if (post = g.posts[quoteID]) {
|
if (post = g.posts[quoteID]) {
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
href: "/" + boardID + "/res/" + post.thread + "#p" + postID,
|
href: "/" + boardID + "/thread/" + post.thread + "#p" + postID,
|
||||||
className: post.isDead ? 'quotelink deadlink' : 'quotelink',
|
className: post.isDead ? 'quotelink deadlink' : 'quotelink',
|
||||||
textContent: quote
|
textContent: quote
|
||||||
});
|
});
|
||||||
@ -8975,7 +8920,9 @@
|
|||||||
_ref = $$('br', frag);
|
_ref = $$('br', frag);
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
node = _ref[_i];
|
node = _ref[_i];
|
||||||
$.replace(node, $.tn('\n>'));
|
if (node !== frag.lastElementChild) {
|
||||||
|
$.replace(node, $.tn('\n>'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ref1 = $$('s', frag);
|
_ref1 = $$('s', frag);
|
||||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||||
@ -10839,8 +10786,12 @@
|
|||||||
delete post.file.videoControls;
|
delete post.file.videoControls;
|
||||||
}
|
}
|
||||||
$.rmClass(post.nodes.root, 'expanded-image');
|
$.rmClass(post.nodes.root, 'expanded-image');
|
||||||
$.rmClass(thumb, 'expanding');
|
$.rmClass(post.file.thumb, 'expanding');
|
||||||
return post.file.isExpanded = false;
|
delete post.file.isExpanding;
|
||||||
|
delete post.file.isExpanded;
|
||||||
|
if (post.file.isVideo && post.file.fullImage) {
|
||||||
|
return post.file.fullImage.pause();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
expand: function(post, src, disableAutoplay) {
|
expand: function(post, src, disableAutoplay) {
|
||||||
var el, isVideo, thumb, _ref;
|
var el, isVideo, thumb, _ref;
|
||||||
@ -10956,19 +10907,40 @@
|
|||||||
return $.add(file.text, file.videoControls);
|
return $.add(file.text, file.videoControls);
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function() {
|
||||||
var URL, post, src, timeoutID;
|
var URL, error, post, src, timeoutID;
|
||||||
post = Get.postFromNode(this);
|
post = Get.postFromNode(this);
|
||||||
$.rm(this);
|
$.rm(this);
|
||||||
|
delete post.file.isReady;
|
||||||
delete post.file.fullImage;
|
delete post.file.fullImage;
|
||||||
if (!($.hasClass(post.file.thumb, 'expanding') || $.hasClass(post.nodes.root, 'expanded-image'))) {
|
if (!($.hasClass(post.file.thumb, 'expanding') || $.hasClass(post.nodes.root, 'expanded-image'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ImageExpand.contract(post);
|
ImageExpand.contract(post);
|
||||||
|
if (this.error && this.error.code !== this.error.MEDIA_ERR_NETWORK) {
|
||||||
|
error = (function() {
|
||||||
|
switch (this.error.code) {
|
||||||
|
case 1:
|
||||||
|
return 'MEDIA_ERR_ABORTED';
|
||||||
|
case 3:
|
||||||
|
return 'MEDIA_ERR_DECODE';
|
||||||
|
case 4:
|
||||||
|
return 'MEDIA_ERR_SRC_NOT_SUPPORTED';
|
||||||
|
case 5:
|
||||||
|
return 'MEDIA_ERR_ENCRYPTED';
|
||||||
|
}
|
||||||
|
}).call(this);
|
||||||
|
post.file.error = $.el('div', {
|
||||||
|
textContent: "Playback error: " + error,
|
||||||
|
className: 'warning'
|
||||||
|
});
|
||||||
|
$.after(post.file.thumb, post.file.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
src = this.src.split('/');
|
src = this.src.split('/');
|
||||||
if (src[2] === 'i.4cdn.org') {
|
if (src[2] === 'i.4cdn.org') {
|
||||||
URL = Redirect.to('file', {
|
URL = Redirect.to('file', {
|
||||||
boardID: src[3],
|
boardID: src[3],
|
||||||
filename: src[5]
|
filename: src[4].replace(/\?.+$/, '')
|
||||||
});
|
});
|
||||||
if (URL) {
|
if (URL) {
|
||||||
setTimeout(ImageExpand.expand, 10000, post, URL);
|
setTimeout(ImageExpand.expand, 10000, post, URL);
|
||||||
@ -11073,7 +11045,6 @@
|
|||||||
TrashQueue.remove(el);
|
TrashQueue.remove(el);
|
||||||
} else {
|
} else {
|
||||||
el = $.el((isVideo ? 'video' : 'img'), {
|
el = $.el((isVideo ? 'video' : 'img'), {
|
||||||
className: 'full-image',
|
|
||||||
src: post.file.URL
|
src: post.file.URL
|
||||||
});
|
});
|
||||||
post.file.fullImage = el;
|
post.file.fullImage = el;
|
||||||
@ -11103,10 +11074,11 @@
|
|||||||
el: el,
|
el: el,
|
||||||
latestEvent: e,
|
latestEvent: e,
|
||||||
endEvents: 'mouseout click',
|
endEvents: 'mouseout click',
|
||||||
asapTest: function() {
|
asapTest: post.file.isImage ? function() {
|
||||||
return el.videoHeight || el.naturalHeight;
|
return el.naturalHeight;
|
||||||
|
} : function() {
|
||||||
|
return el.readyState >= el.HAVE_CURRENT_DATA;
|
||||||
},
|
},
|
||||||
noRemove: true,
|
|
||||||
cb: function() {
|
cb: function() {
|
||||||
if (isVideo) {
|
if (isVideo) {
|
||||||
el.pause();
|
el.pause();
|
||||||
@ -11127,7 +11099,7 @@
|
|||||||
if (src[2] === 'i.4cdn.org') {
|
if (src[2] === 'i.4cdn.org') {
|
||||||
URL = Redirect.to('file', {
|
URL = Redirect.to('file', {
|
||||||
boardID: src[3],
|
boardID: src[3],
|
||||||
filename: src[5].replace(/\?.+$/, '')
|
filename: src[4].replace(/\?.+$/, '')
|
||||||
});
|
});
|
||||||
if (URL) {
|
if (URL) {
|
||||||
this.src = URL;
|
this.src = URL;
|
||||||
@ -12183,9 +12155,12 @@
|
|||||||
if ((_ref = ThreadUpdater.req) != null) {
|
if ((_ref = ThreadUpdater.req) != null) {
|
||||||
_ref.abort();
|
_ref.abort();
|
||||||
}
|
}
|
||||||
url = "//a.4cdn.org/" + ThreadUpdater.thread.board + "/res/" + ThreadUpdater.thread + ".json";
|
url = "//a.4cdn.org/" + ThreadUpdater.thread.board + "/thread/" + ThreadUpdater.thread + ".json";
|
||||||
return ThreadUpdater.req = $.ajax(url, {
|
return ThreadUpdater.req = $.ajax(url, {
|
||||||
onloadend: ThreadUpdater.cb.load
|
onabort: ThreadUpdater.cb.load,
|
||||||
|
onloadend: ThreadUpdater.cb.load,
|
||||||
|
ontimeout: ThreadUpdater.cb.load,
|
||||||
|
timeout: $.MINUTE
|
||||||
}, {
|
}, {
|
||||||
whenModified: true
|
whenModified: true
|
||||||
});
|
});
|
||||||
@ -12483,7 +12458,7 @@
|
|||||||
}
|
}
|
||||||
fetchCount = ThreadWatcher.fetchCount;
|
fetchCount = ThreadWatcher.fetchCount;
|
||||||
fetchCount.fetching++;
|
fetchCount.fetching++;
|
||||||
return $.ajax("//a.4cdn.org/" + boardID + "/res/" + threadID + ".json", {
|
return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
|
||||||
onloadend: function() {
|
onloadend: function() {
|
||||||
var status;
|
var status;
|
||||||
fetchCount.fetched++;
|
fetchCount.fetched++;
|
||||||
@ -12552,7 +12527,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
link = $.el('a', {
|
link = $.el('a', {
|
||||||
href: href || ("/" + boardID + "/res/" + threadID),
|
href: href || ("/" + boardID + "/thread/" + threadID),
|
||||||
textContent: data.excerpt,
|
textContent: data.excerpt,
|
||||||
title: data.excerpt
|
title: data.excerpt
|
||||||
});
|
});
|
||||||
@ -15254,7 +15229,7 @@
|
|||||||
var status;
|
var status;
|
||||||
ExpandThread.statuses[thread] = status = {};
|
ExpandThread.statuses[thread] = status = {};
|
||||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(__slice.call(a.textContent.match(/\d+/g))));
|
a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(__slice.call(a.textContent.match(/\d+/g))));
|
||||||
return status.req = $.cache("//a.4cdn.org/" + thread.board + "/res/" + thread + ".json", function() {
|
return status.req = $.cache("//a.4cdn.org/" + thread.board + "/thread/" + thread + ".json", function() {
|
||||||
delete status.req;
|
delete status.req;
|
||||||
return ExpandThread.parse(this, thread, a);
|
return ExpandThread.parse(this, thread, a);
|
||||||
});
|
});
|
||||||
@ -15754,7 +15729,7 @@
|
|||||||
return Conf[hotkey] = key;
|
return Conf[hotkey] = key;
|
||||||
},
|
},
|
||||||
keydown: function(e) {
|
keydown: function(e) {
|
||||||
var key, notification, notifications, op, target, thread, threadRoot, _i, _len, _ref;
|
var form, key, notification, notifications, op, target, thread, threadRoot, _i, _len, _ref;
|
||||||
if (!(key = Keybinds.keyCode(e))) {
|
if (!(key = Keybinds.keyCode(e))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -15848,7 +15823,9 @@
|
|||||||
ThreadUpdater.update();
|
ThreadUpdater.update();
|
||||||
break;
|
break;
|
||||||
case 'index':
|
case 'index':
|
||||||
Index.update();
|
if (Conf['JSON Navigation']) {
|
||||||
|
Index.update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Conf['Watch']:
|
case Conf['Watch']:
|
||||||
@ -15874,7 +15851,7 @@
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case Conf['Front page']:
|
case Conf['Front page']:
|
||||||
if (g.VIEW === 'index') {
|
if (Conf['JSON Navigation'] && g.VIEW === 'index') {
|
||||||
Index.userPageNav(0);
|
Index.userPageNav(0);
|
||||||
} else {
|
} else {
|
||||||
window.location = "/" + g.BOARD + "/";
|
window.location = "/" + g.BOARD + "/";
|
||||||
@ -15884,19 +15861,39 @@
|
|||||||
$.open("/" + g.BOARD + "/");
|
$.open("/" + g.BOARD + "/");
|
||||||
break;
|
break;
|
||||||
case Conf['Next page']:
|
case Conf['Next page']:
|
||||||
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'all pages')) {
|
if (g.VIEW !== 'index') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$('.next button, .next a', Index.pagelist).click();
|
if (Conf['JSON Navigation']) {
|
||||||
|
if (Conf['Index Mode'] !== 'all pages') {
|
||||||
|
$('.next button', Index.pagelist).click();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (form = $('.next form')) {
|
||||||
|
window.location = form.action;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Conf['Previous page']:
|
case Conf['Previous page']:
|
||||||
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'all pages')) {
|
if (g.VIEW !== 'index') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$('.prev button, .prev a', Index.pagelist).click();
|
if (Conf['JSON Navigation']) {
|
||||||
|
if (Conf['Index Mode'] !== 'all pages') {
|
||||||
|
$('.prev button', Index.pagelist).click();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (form = $('.prev form')) {
|
||||||
|
window.location = form.action;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Conf['Search form']:
|
case Conf['Search form']:
|
||||||
Index.searchInput.focus();
|
if (Conf['JSON Navigation']) {
|
||||||
|
Index.searchInput.focus();
|
||||||
|
} else {
|
||||||
|
$.id('search-btn').click();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Conf['Paged mode']:
|
case Conf['Paged mode']:
|
||||||
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'paged')) {
|
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'paged')) {
|
||||||
@ -15922,6 +15919,19 @@
|
|||||||
}
|
}
|
||||||
Index.cycleSortType();
|
Index.cycleSortType();
|
||||||
break;
|
break;
|
||||||
|
case Conf['Open catalog']:
|
||||||
|
if (Conf['External Catalog']) {
|
||||||
|
window.location = CatalogLinks.external(g.BOARD.ID);
|
||||||
|
} else {
|
||||||
|
if (!Conf['JSON Navigation']) {
|
||||||
|
return window.location = "/" + g.BOARD + "/catalog";
|
||||||
|
}
|
||||||
|
if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'catalog')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Index.setIndexMode('catalog');
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Conf['Next thread']:
|
case Conf['Next thread']:
|
||||||
if (g.VIEW !== 'index') {
|
if (g.VIEW !== 'index') {
|
||||||
return;
|
return;
|
||||||
@ -16054,7 +16064,7 @@
|
|||||||
if (g.VIEW !== 'index') {
|
if (g.VIEW !== 'index') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
url = "/" + thread.board + "/res/" + thread;
|
url = "/" + thread.board + "/thread/" + thread;
|
||||||
if (tab) {
|
if (tab) {
|
||||||
return $.open(url);
|
return $.open(url);
|
||||||
} else {
|
} else {
|
||||||
@ -16677,7 +16687,7 @@
|
|||||||
if (threadID) {
|
if (threadID) {
|
||||||
view = 'thread';
|
view = 'thread';
|
||||||
} else {
|
} else {
|
||||||
pageNum = view;
|
pageNum = +view;
|
||||||
view = 'index';
|
view = 'index';
|
||||||
}
|
}
|
||||||
path = this.pathname;
|
path = this.pathname;
|
||||||
@ -16686,9 +16696,8 @@
|
|||||||
}
|
}
|
||||||
Navigate.makeBreadCrumb(this.href, view, boardID, threadID);
|
Navigate.makeBreadCrumb(this.href, view, boardID, threadID);
|
||||||
if (this.id !== 'popState') {
|
if (this.id !== 'popState') {
|
||||||
history.pushState('internal', '', path);
|
Navigate.pushState(path);
|
||||||
}
|
}
|
||||||
Navigate.path = this.pathname;
|
|
||||||
Navigate.setMode(this);
|
Navigate.setMode(this);
|
||||||
if (!(view === 'index' && 'index' === g.VIEW && boardID === g.BOARD.ID)) {
|
if (!(view === 'index' && 'index' === g.VIEW && boardID === g.BOARD.ID)) {
|
||||||
Navigate.disconnect();
|
Navigate.disconnect();
|
||||||
@ -16812,6 +16821,10 @@
|
|||||||
return Main.handleErrors(errors);
|
return Main.handleErrors(errors);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
pushState: function(path) {
|
||||||
|
history.pushState(null, '', path);
|
||||||
|
return Navigate.path = window.location.pathname;
|
||||||
|
},
|
||||||
popstate: function() {
|
popstate: function() {
|
||||||
var a;
|
var a;
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
@ -17275,7 +17288,7 @@
|
|||||||
data = {
|
data = {
|
||||||
isReply: true,
|
isReply: true,
|
||||||
file: {
|
file: {
|
||||||
URL: '//i.4cdn.org/g/src/1334437723720.jpg',
|
URL: '//i.4cdn.org/g/1334437723720.jpg',
|
||||||
name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg',
|
name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg',
|
||||||
size: '276 KB',
|
size: '276 KB',
|
||||||
sizeInBytes: 276 * 1024,
|
sizeInBytes: 276 * 1024,
|
||||||
@ -17892,6 +17905,7 @@
|
|||||||
g.VIEW = (function() {
|
g.VIEW = (function() {
|
||||||
switch (pathname[2]) {
|
switch (pathname[2]) {
|
||||||
case 'res':
|
case 'res':
|
||||||
|
case 'thread':
|
||||||
return 'thread';
|
return 'thread';
|
||||||
case 'catalog':
|
case 'catalog':
|
||||||
return 'catalog';
|
return 'catalog';
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.7' />
|
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.8' />
|
||||||
</app>
|
</app>
|
||||||
</gupdate>
|
</gupdate>
|
||||||
|
|
||||||
|
|||||||
1071
css/style.css
Normal file
1071
css/style.css
Normal file
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,7 @@
|
|||||||
"userjs": "appchan-x.user.js"
|
"userjs": "appchan-x.user.js"
|
||||||
},
|
},
|
||||||
"min": {
|
"min": {
|
||||||
"chrome": "32",
|
"chrome": "33",
|
||||||
"firefox": "26",
|
"firefox": "26",
|
||||||
"greasemonkey": "1.14"
|
"greasemonkey": "1.14"
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@
|
|||||||
"grunt-concurrent": "~0.5.0",
|
"grunt-concurrent": "~0.5.0",
|
||||||
"grunt-contrib-clean": "~0.5.0",
|
"grunt-contrib-clean": "~0.5.0",
|
||||||
"grunt-contrib-coffee": "~0.10.1",
|
"grunt-contrib-coffee": "~0.10.1",
|
||||||
"grunt-contrib-compress": "~0.7.0",
|
"grunt-contrib-compress": "~0.8.0",
|
||||||
"grunt-contrib-concat": "~0.4.0",
|
"grunt-contrib-concat": "~0.4.0",
|
||||||
"grunt-contrib-copy": "~0.5.0",
|
"grunt-contrib-copy": "~0.5.0",
|
||||||
"grunt-contrib-watch": "~0.6.1",
|
"grunt-contrib-watch": "~0.6.1",
|
||||||
|
|||||||
@ -14,15 +14,6 @@ PostHiding =
|
|||||||
name: 'Post Hiding'
|
name: 'Post Hiding'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
# XXX tmp conversion
|
|
||||||
$.get 'hiddenThreads', null, ({hiddenThreads}) ->
|
|
||||||
return unless hiddenThreads
|
|
||||||
for boardID, board of hiddenThreads.boards
|
|
||||||
for threadID, val of board
|
|
||||||
((PostHiding.db.data.boards[boardID] or= {})[threadID] or= {})[threadID] = val
|
|
||||||
PostHiding.db.save()
|
|
||||||
$.delete 'hiddenThreads'
|
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return if !@isReply and g.VIEW isnt 'index' or @isClone
|
return if !@isReply and g.VIEW isnt 'index' or @isClone
|
||||||
|
|
||||||
|
|||||||
@ -42,14 +42,14 @@ Build =
|
|||||||
name: data.filename + data.ext
|
name: data.filename + data.ext
|
||||||
timestamp: "#{data.tim}#{data.ext}"
|
timestamp: "#{data.tim}#{data.ext}"
|
||||||
url: if boardID is 'f'
|
url: if boardID is 'f'
|
||||||
"//i.4cdn.org/#{boardID}/src/#{data.filename}#{data.ext}"
|
"//i.4cdn.org/#{boardID}/#{data.filename}#{data.ext}"
|
||||||
else
|
else
|
||||||
"//i.4cdn.org/#{boardID}/src/#{data.tim}#{data.ext}"
|
"//i.4cdn.org/#{boardID}/#{data.tim}#{data.ext}"
|
||||||
height: data.h
|
height: data.h
|
||||||
width: data.w
|
width: data.w
|
||||||
MD5: data.md5
|
MD5: data.md5
|
||||||
size: data.fsize
|
size: data.fsize
|
||||||
turl: "//#{Build.thumbRotate()}.t.4cdn.org/#{boardID}/thumb/#{data.tim}s.jpg"
|
turl: "//#{Build.thumbRotate()}.t.4cdn.org/#{boardID}/#{data.tim}s.jpg"
|
||||||
theight: data.tn_h
|
theight: data.tn_h
|
||||||
twidth: data.tn_w
|
twidth: data.tn_w
|
||||||
isSpoiler: !!data.spoiler
|
isSpoiler: !!data.spoiler
|
||||||
@ -184,19 +184,55 @@ Build =
|
|||||||
if isOP and g.VIEW is 'index'
|
if isOP and g.VIEW is 'index'
|
||||||
pageNum = Index.liveThreadData.keys.indexOf("#{postID}") // Index.threadsNumPerPage
|
pageNum = Index.liveThreadData.keys.indexOf("#{postID}") // Index.threadsNumPerPage
|
||||||
pageIcon = " <span class=page-num title='This thread is on page #{pageNum} in the original index.'>Page #{pageNum}</span>"
|
pageIcon = " <span class=page-num title='This thread is on page #{pageNum} in the original index.'>Page #{pageNum}</span>"
|
||||||
replyLink = " <span>[<a href='/#{boardID}/res/#{threadID}' class=replylink>Reply</a>]</span>"
|
replyLink = " <span>[<a href='/#{boardID}/thread/#{threadID}' class=replylink>Reply</a>]</span>"
|
||||||
else
|
else
|
||||||
pageIcon = replyLink = ''
|
pageIcon = replyLink = ''
|
||||||
|
|
||||||
container = $.el 'div',
|
container = $.el 'div',
|
||||||
id: "pc#{postID}"
|
id: "pc#{postID}"
|
||||||
className: "postContainer #{if isOP then 'op' else 'reply'}Container"
|
className: "postContainer #{if isOP then 'op' else 'reply'}Container"
|
||||||
innerHTML: <%= grunt.file.read('src/General/html/Build/post.html').replace(/>\s+/g, '>').replace(/\s+</g, '<').replace(/\s+/g, ' ').trim() %>
|
innerHTML: \
|
||||||
|
(if isOP then '' else "<div class=sideArrows>>></div>") +
|
||||||
|
"<div id=p#{postID} class='post #{if isOP then 'op' else 'reply'}#{
|
||||||
|
if capcode is 'admin_highlight'
|
||||||
|
' highlightPost'
|
||||||
|
else
|
||||||
|
''
|
||||||
|
}'>" +
|
||||||
|
|
||||||
|
(if isOP then fileHTML else '') +
|
||||||
|
|
||||||
|
"<div class=postInfo>" +
|
||||||
|
"<input type=checkbox name=#{postID} value=delete> " +
|
||||||
|
"<span class=subject>#{subject or ''}</span> " +
|
||||||
|
"<span class='nameBlock#{capcodeClass}'>" +
|
||||||
|
emailStart +
|
||||||
|
"<span class=name>#{name or ''}</span>" + tripcode +
|
||||||
|
capcodeStart + emailEnd + capcodeIcon + userID + flag +
|
||||||
|
' </span> ' +
|
||||||
|
"<span class=dateTime data-utc=#{dateUTC}>#{date}</span> " +
|
||||||
|
"<span class='postNum'>" +
|
||||||
|
"<a href=#{"/#{boardID}/thread/#{threadID}#p#{postID}"} title='Highlight this post'>No.</a>" +
|
||||||
|
"<a href='#{
|
||||||
|
if g.VIEW is 'thread' and g.THREADID is threadID
|
||||||
|
"javascript:quote(#{postID})"
|
||||||
|
else
|
||||||
|
"/#{boardID}/thread/#{threadID}#q#{postID}"
|
||||||
|
}' title='Quote this post'>#{postID}</a>" +
|
||||||
|
pageIcon + sticky + closed + replyLink +
|
||||||
|
'</span>' +
|
||||||
|
'</div>' +
|
||||||
|
|
||||||
|
(if isOP then '' else fileHTML) +
|
||||||
|
|
||||||
|
"<blockquote class=postMessage>#{comment or ''}</blockquote> " +
|
||||||
|
|
||||||
|
'</div>'
|
||||||
|
|
||||||
for quote in $$ '.quotelink', container
|
for quote in $$ '.quotelink', container
|
||||||
href = quote.getAttribute 'href'
|
href = quote.getAttribute 'href'
|
||||||
continue if href[0] is '/' # Cross-board quote, or board link
|
continue if href[0] is '/' # Cross-board quote, or board link
|
||||||
quote.href = "/#{boardID}/res/#{href}" # Fix pathnames
|
quote.href = "/#{boardID}/thread/#{href}" # Fix pathnames
|
||||||
|
|
||||||
container
|
container
|
||||||
|
|
||||||
@ -208,7 +244,7 @@ Build =
|
|||||||
$.el 'a',
|
$.el 'a',
|
||||||
className: 'summary'
|
className: 'summary'
|
||||||
textContent: text.join ' '
|
textContent: text.join ' '
|
||||||
href: "/#{boardID}/res/#{threadID}"
|
href: "/#{boardID}/thread/#{threadID}"
|
||||||
|
|
||||||
thread: (board, data, full) ->
|
thread: (board, data, full) ->
|
||||||
Build.spoilerRange[board] = data.custom_spoiler
|
Build.spoilerRange[board] = data.custom_spoiler
|
||||||
|
|||||||
@ -1029,11 +1029,11 @@ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
|
|||||||
# Board Navigation
|
# Board Navigation
|
||||||
'Front page': [
|
'Front page': [
|
||||||
'0'
|
'0'
|
||||||
'Jump to page 0.'
|
'Jump to front page.'
|
||||||
]
|
]
|
||||||
'Open front page': [
|
'Open front page': [
|
||||||
'Shift+0'
|
'Shift+0'
|
||||||
'Open page 0 in a new tab.'
|
'Open front page in a new tab.'
|
||||||
]
|
]
|
||||||
'Next page': [
|
'Next page': [
|
||||||
'Shift+Right'
|
'Shift+Right'
|
||||||
|
|||||||
@ -70,7 +70,7 @@ Get =
|
|||||||
|
|
||||||
root.textContent = "Loading post No.#{postID}..."
|
root.textContent = "Loading post No.#{postID}..."
|
||||||
if threadID
|
if threadID
|
||||||
$.cache "//a.4cdn.org/#{boardID}/res/#{threadID}.json", ->
|
$.cache "//a.4cdn.org/#{boardID}/thread/#{threadID}.json", ->
|
||||||
Get.fetchedPost @, boardID, threadID, postID, root, context
|
Get.fetchedPost @, boardID, threadID, postID, root, context
|
||||||
else if url = Redirect.to 'post', {boardID, postID}
|
else if url = Redirect.to 'post', {boardID, postID}
|
||||||
$.cache url,
|
$.cache url,
|
||||||
@ -200,7 +200,7 @@ Get =
|
|||||||
width: data.media.media_w
|
width: data.media.media_w
|
||||||
MD5: data.media.media_hash
|
MD5: data.media.media_hash
|
||||||
size: data.media.media_size
|
size: data.media.media_size
|
||||||
turl: data.media.thumb_link or "//t.4cdn.org/#{boardID}/thumb/#{data.media.preview_orig}"
|
turl: data.media.thumb_link or "//t.4cdn.org/#{boardID}/#{data.media.preview_orig}"
|
||||||
theight: data.media.preview_h
|
theight: data.media.preview_h
|
||||||
twidth: data.media.preview_w
|
twidth: data.media.preview_w
|
||||||
isSpoiler: data.media.spoiler is '1'
|
isSpoiler: data.media.spoiler is '1'
|
||||||
|
|||||||
@ -424,6 +424,7 @@ Index =
|
|||||||
+window.location.pathname.split('/')[2]
|
+window.location.pathname.split('/')[2]
|
||||||
|
|
||||||
userPageNav: (pageNum) ->
|
userPageNav: (pageNum) ->
|
||||||
|
Navigate.pushState if pageNum is 0 then './' else pageNum
|
||||||
if Conf['Refreshed Navigation'] and Conf['Index Mode'] isnt 'all pages'
|
if Conf['Refreshed Navigation'] and Conf['Index Mode'] isnt 'all pages'
|
||||||
Index.update pageNum
|
Index.update pageNum
|
||||||
else
|
else
|
||||||
@ -431,7 +432,7 @@ Index =
|
|||||||
|
|
||||||
pageNav: (pageNum) ->
|
pageNav: (pageNum) ->
|
||||||
return if Index.currentPage is pageNum and not Index.root.parentElement
|
return if Index.currentPage is pageNum and not Index.root.parentElement
|
||||||
history.pushState null, '', if pageNum is 0 then './' else pageNum
|
Navigate.pushState if pageNum is 0 then './' else pageNum
|
||||||
Index.pageLoad pageNum
|
Index.pageLoad pageNum
|
||||||
|
|
||||||
pageLoad: (pageNum) ->
|
pageLoad: (pageNum) ->
|
||||||
|
|||||||
@ -8,7 +8,7 @@ Main =
|
|||||||
return if g.BOARD.ID in ['z', 'fk']
|
return if g.BOARD.ID in ['z', 'fk']
|
||||||
g.VIEW =
|
g.VIEW =
|
||||||
switch pathname[2]
|
switch pathname[2]
|
||||||
when 'res'
|
when 'res', 'thread'
|
||||||
'thread'
|
'thread'
|
||||||
when 'catalog'
|
when 'catalog'
|
||||||
'catalog'
|
'catalog'
|
||||||
|
|||||||
@ -226,7 +226,7 @@ Navigate =
|
|||||||
if threadID
|
if threadID
|
||||||
view = 'thread'
|
view = 'thread'
|
||||||
else
|
else
|
||||||
pageNum = view
|
pageNum = +view
|
||||||
view = 'index' # path is "/boardID/". See the problem?
|
view = 'index' # path is "/boardID/". See the problem?
|
||||||
|
|
||||||
path = @pathname
|
path = @pathname
|
||||||
@ -234,8 +234,7 @@ Navigate =
|
|||||||
|
|
||||||
Navigate.makeBreadCrumb @href, view, boardID, threadID
|
Navigate.makeBreadCrumb @href, view, boardID, threadID
|
||||||
|
|
||||||
history.pushState 'internal', '', path unless @id is 'popState'
|
Navigate.pushState path unless @id is 'popState'
|
||||||
Navigate.path = @pathname
|
|
||||||
|
|
||||||
Navigate.setMode @
|
Navigate.setMode @
|
||||||
|
|
||||||
@ -347,6 +346,10 @@ Navigate =
|
|||||||
|
|
||||||
Main.handleErrors errors if errors
|
Main.handleErrors errors if errors
|
||||||
|
|
||||||
|
pushState: (path) ->
|
||||||
|
history.pushState null, '', path
|
||||||
|
Navigate.path = window.location.pathname
|
||||||
|
|
||||||
popstate: ->
|
popstate: ->
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
href: window.location
|
href: window.location
|
||||||
|
|||||||
@ -356,7 +356,7 @@ Settings =
|
|||||||
data =
|
data =
|
||||||
isReply: true
|
isReply: true
|
||||||
file:
|
file:
|
||||||
URL: '//i.4cdn.org/g/src/1334437723720.jpg'
|
URL: '//i.4cdn.org/g/1334437723720.jpg'
|
||||||
name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg'
|
name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg'
|
||||||
size: '276 KB'
|
size: '276 KB'
|
||||||
sizeInBytes: 276 * 1024
|
sizeInBytes: 276 * 1024
|
||||||
|
|||||||
@ -1,36 +0,0 @@
|
|||||||
"""#{if isOP then '' else "<div class=sideArrows>>></div>"}
|
|
||||||
<div id=p#{postID} class='post #{if isOP then 'op' else 'reply'}#{
|
|
||||||
if capcodeIcon is 'admin_highlight' then
|
|
||||||
' highlightPost'
|
|
||||||
else
|
|
||||||
''
|
|
||||||
}'>
|
|
||||||
|
|
||||||
#{if isOP then fileHTML else ''}
|
|
||||||
|
|
||||||
<div class='postInfo'>
|
|
||||||
<input type=checkbox name=#{postID} value=delete>
|
|
||||||
#{' '}<span class=subject>#{subject or ''}</span>#{' '}
|
|
||||||
<span class='nameBlock#{capcodeClass}'>
|
|
||||||
#{emailStart}
|
|
||||||
<span class=name>#{name or ''}</span>
|
|
||||||
#{tripcode + capcodeStart + emailEnd + capcodeIcon + userID + flag}
|
|
||||||
</span>#{" "}
|
|
||||||
<span class=dateTime data-utc=#{dateUTC}>#{date}</span>#{' '}
|
|
||||||
<span class='postNum'>
|
|
||||||
<a href=#{"/#{boardID}/res/#{threadID}#p#{postID}"} title='Highlight this post'>No.</a>
|
|
||||||
<a href='#{
|
|
||||||
if g.VIEW is 'thread' and g.THREADID is +threadID then
|
|
||||||
"javascript:quote(#{postID})"
|
|
||||||
else
|
|
||||||
"/#{boardID}/res/#{threadID}#q#{postID}"
|
|
||||||
}' title='Quote this post'>#{postID}</a>
|
|
||||||
#{pageIcon + sticky + closed + replyLink}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
#{if isOP then '' else fileHTML}
|
|
||||||
|
|
||||||
<blockquote class=postMessage>#{comment or ''}</blockquote>#{' '}
|
|
||||||
|
|
||||||
</div>"""
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
<a href="/#{thread.board}/res/#{thread.ID}" class="thumb"></a>
|
<a href="/#{thread.board}/thread/#{thread.ID}" class="thumb"></a>
|
||||||
<div class="thread-stats" title="Post count / File count / Page count">
|
<div class="thread-stats" title="Post count / File count / Page count">
|
||||||
<span class="post-count">#{postCount}</span> / <span class="file-count">#{fileCount}</span> / <span class="page-count">#{pageCount}</span>
|
<span class="post-count">#{postCount}</span> / <span class="file-count">#{fileCount}</span> / <span class="page-count">#{pageCount}</span>
|
||||||
<span class="thread-icons"></span>
|
<span class="thread-icons"></span>
|
||||||
|
|||||||
@ -1,21 +1,8 @@
|
|||||||
Polyfill =
|
Polyfill =
|
||||||
init: ->
|
init: ->
|
||||||
<% if (type === 'crx') { %>
|
<% if (type === 'crx') { %>
|
||||||
@notificationPermission()
|
|
||||||
@toBlob()
|
@toBlob()
|
||||||
@visibility()
|
|
||||||
<% } %>
|
<% } %>
|
||||||
notificationPermission: ->
|
|
||||||
return if !window.Notification or 'permission' of Notification or !window.webkitNotifications
|
|
||||||
Object.defineProperty Notification, 'permission',
|
|
||||||
get: ->
|
|
||||||
switch webkitNotifications.checkPermission()
|
|
||||||
when 0
|
|
||||||
'granted'
|
|
||||||
when 1
|
|
||||||
'default'
|
|
||||||
when 2
|
|
||||||
'denied'
|
|
||||||
toBlob: ->
|
toBlob: ->
|
||||||
HTMLCanvasElement::toBlob or= (cb) ->
|
HTMLCanvasElement::toBlob or= (cb) ->
|
||||||
data = atob @toDataURL()[22..]
|
data = atob @toDataURL()[22..]
|
||||||
@ -25,12 +12,3 @@ Polyfill =
|
|||||||
for i in [0...l] by 1
|
for i in [0...l] by 1
|
||||||
ui8a[i] = data.charCodeAt i
|
ui8a[i] = data.charCodeAt i
|
||||||
cb new Blob [ui8a], type: 'image/png'
|
cb new Blob [ui8a], type: 'image/png'
|
||||||
visibility: ->
|
|
||||||
# page visibility API
|
|
||||||
return if 'visibilityState' of d
|
|
||||||
Object.defineProperties HTMLDocument.prototype,
|
|
||||||
visibilityState:
|
|
||||||
get: -> @webkitVisibilityState
|
|
||||||
hidden:
|
|
||||||
get: -> @webkitHidden
|
|
||||||
$.on d, 'webkitvisibilitychange', -> $.event 'visibilitychange'
|
|
||||||
|
|||||||
@ -101,7 +101,7 @@ class Post
|
|||||||
return unless match = quotelink.href.match ///
|
return unless match = quotelink.href.match ///
|
||||||
boards\.4chan\.org/
|
boards\.4chan\.org/
|
||||||
([^/]+) # boardID
|
([^/]+) # boardID
|
||||||
/res/\d+#p
|
/thread/\d+#p
|
||||||
(\d+) # postID
|
(\d+) # postID
|
||||||
$
|
$
|
||||||
///
|
///
|
||||||
@ -134,7 +134,7 @@ class Post
|
|||||||
@file.thumbURL = if that.isArchived
|
@file.thumbURL = if that.isArchived
|
||||||
thumb.src
|
thumb.src
|
||||||
else
|
else
|
||||||
"#{location.protocol}//t.4cdn.org/#{@board}/thumb/#{@file.URL.match(/(\d+)\./)[1]}s.jpg"
|
"#{location.protocol}//t.4cdn.org/#{@board}/#{@file.URL.match(/(\d+)\./)[1]}s.jpg"
|
||||||
@file.name = if nameNode = $ 'span', fileText
|
@file.name = if nameNode = $ 'span', fileText
|
||||||
nameNode.title or nameNode.textContent
|
nameNode.title or nameNode.textContent
|
||||||
else
|
else
|
||||||
|
|||||||
@ -116,8 +116,10 @@ ImageExpand =
|
|||||||
$.rm post.file.videoControls
|
$.rm post.file.videoControls
|
||||||
delete post.file.videoControls
|
delete post.file.videoControls
|
||||||
$.rmClass post.nodes.root, 'expanded-image'
|
$.rmClass post.nodes.root, 'expanded-image'
|
||||||
$.rmClass thumb, 'expanding'
|
$.rmClass post.file.thumb, 'expanding'
|
||||||
post.file.isExpanded = false
|
delete post.file.isExpanding
|
||||||
|
delete post.file.isExpanded
|
||||||
|
post.file.fullImage.pause() if post.file.isVideo and post.file.fullImage
|
||||||
|
|
||||||
expand: (post, src, disableAutoplay) ->
|
expand: (post, src, disableAutoplay) ->
|
||||||
# Do not expand images of hidden/filtered replies, or already expanded pictures.
|
# Do not expand images of hidden/filtered replies, or already expanded pictures.
|
||||||
@ -198,6 +200,7 @@ ImageExpand =
|
|||||||
error: ->
|
error: ->
|
||||||
post = Get.postFromNode @
|
post = Get.postFromNode @
|
||||||
$.rm @
|
$.rm @
|
||||||
|
delete post.file.isReady
|
||||||
delete post.file.fullImage
|
delete post.file.fullImage
|
||||||
# Images can error:
|
# Images can error:
|
||||||
# - before the image started loading.
|
# - before the image started loading.
|
||||||
@ -207,11 +210,23 @@ ImageExpand =
|
|||||||
return
|
return
|
||||||
ImageExpand.contract post
|
ImageExpand.contract post
|
||||||
|
|
||||||
|
if @error and @error.code isnt @error.MEDIA_ERR_NETWORK # video
|
||||||
|
error = switch @error.code
|
||||||
|
when 1 then 'MEDIA_ERR_ABORTED'
|
||||||
|
when 3 then 'MEDIA_ERR_DECODE'
|
||||||
|
when 4 then 'MEDIA_ERR_SRC_NOT_SUPPORTED'
|
||||||
|
when 5 then 'MEDIA_ERR_ENCRYPTED'
|
||||||
|
post.file.error = $.el 'div',
|
||||||
|
textContent: "Playback error: #{error}"
|
||||||
|
className: 'warning'
|
||||||
|
$.after post.file.thumb, post.file.error
|
||||||
|
return
|
||||||
|
|
||||||
src = @src.split '/'
|
src = @src.split '/'
|
||||||
if src[2] is 'i.4cdn.org'
|
if src[2] is 'i.4cdn.org'
|
||||||
URL = Redirect.to 'file',
|
URL = Redirect.to 'file',
|
||||||
boardID: src[3]
|
boardID: src[3]
|
||||||
filename: src[5]
|
filename: src[4].replace /\?.+$/, ''
|
||||||
if URL
|
if URL
|
||||||
setTimeout ImageExpand.expand, 10000, post, URL
|
setTimeout ImageExpand.expand, 10000, post, URL
|
||||||
return
|
return
|
||||||
@ -229,7 +244,7 @@ ImageExpand =
|
|||||||
type: 'head'
|
type: 'head'
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
# XXX CORS for i.4cdn.org WHEN?
|
# XXX CORS for i.4cdn.org WHEN?
|
||||||
$.ajax "//a.4cdn.org/#{post.board}/res/#{post.thread}.json", onload: ->
|
$.ajax "//a.4cdn.org/#{post.board}/thread/#{post.thread}.json", onload: ->
|
||||||
return if @status isnt 200
|
return if @status isnt 200
|
||||||
for postObj in @response.posts
|
for postObj in @response.posts
|
||||||
break if postObj.no is post.ID
|
break if postObj.no is post.ID
|
||||||
|
|||||||
@ -25,7 +25,6 @@ ImageHover =
|
|||||||
TrashQueue.remove el
|
TrashQueue.remove el
|
||||||
else
|
else
|
||||||
el = $.el (if isVideo then 'video' else 'img'),
|
el = $.el (if isVideo then 'video' else 'img'),
|
||||||
className: 'full-image'
|
|
||||||
src: post.file.URL
|
src: post.file.URL
|
||||||
post.file.fullImage = el
|
post.file.fullImage = el
|
||||||
{thumb} = post.file
|
{thumb} = post.file
|
||||||
@ -46,8 +45,10 @@ ImageHover =
|
|||||||
el: el
|
el: el
|
||||||
latestEvent: e
|
latestEvent: e
|
||||||
endEvents: 'mouseout click'
|
endEvents: 'mouseout click'
|
||||||
asapTest: -> (el.videoHeight or el.naturalHeight)
|
asapTest: if post.file.isImage
|
||||||
noRemove: true
|
-> el.naturalHeight
|
||||||
|
else
|
||||||
|
-> el.readyState >= el.HAVE_CURRENT_DATA
|
||||||
cb: ->
|
cb: ->
|
||||||
if isVideo
|
if isVideo
|
||||||
el.pause()
|
el.pause()
|
||||||
@ -62,7 +63,7 @@ ImageHover =
|
|||||||
if src[2] is 'i.4cdn.org'
|
if src[2] is 'i.4cdn.org'
|
||||||
URL = Redirect.to 'file',
|
URL = Redirect.to 'file',
|
||||||
boardID: src[3]
|
boardID: src[3]
|
||||||
filename: src[5].replace /\?.+$/, ''
|
filename: src[4].replace /\?.+$/, ''
|
||||||
if URL
|
if URL
|
||||||
@src = URL
|
@src = URL
|
||||||
return
|
return
|
||||||
@ -80,7 +81,7 @@ ImageHover =
|
|||||||
type: 'head'
|
type: 'head'
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
# XXX CORS for i.4cdn.org WHEN?
|
# XXX CORS for i.4cdn.org WHEN?
|
||||||
$.ajax "//a.4cdn.org/#{post.board}/res/#{post.thread}.json", onload: ->
|
$.ajax "//a.4cdn.org/#{post.board}/thread/#{post.thread}.json", onload: ->
|
||||||
return if @status isnt 200
|
return if @status isnt 200
|
||||||
for postObj in @response.posts
|
for postObj in @response.posts
|
||||||
break if postObj.no is post.ID
|
break if postObj.no is post.ID
|
||||||
|
|||||||
@ -49,7 +49,7 @@ ExpandThread =
|
|||||||
expand: (thread, a, threadRoot) ->
|
expand: (thread, a, threadRoot) ->
|
||||||
ExpandThread.statuses[thread] = status = {}
|
ExpandThread.statuses[thread] = status = {}
|
||||||
a.textContent = ExpandThread.text '...', a.textContent.match(/\d+/g)...
|
a.textContent = ExpandThread.text '...', a.textContent.match(/\d+/g)...
|
||||||
status.req = $.cache "//a.4cdn.org/#{thread.board}/res/#{thread}.json", ->
|
status.req = $.cache "//a.4cdn.org/#{thread.board}/thread/#{thread}.json", ->
|
||||||
delete status.req
|
delete status.req
|
||||||
ExpandThread.parse @, thread, a
|
ExpandThread.parse @, thread, a
|
||||||
contract: (thread, a, threadRoot) ->
|
contract: (thread, a, threadRoot) ->
|
||||||
|
|||||||
@ -74,7 +74,7 @@ Keybinds =
|
|||||||
when 'thread'
|
when 'thread'
|
||||||
ThreadUpdater.update()
|
ThreadUpdater.update()
|
||||||
when 'index'
|
when 'index'
|
||||||
Index.update()
|
if Conf['JSON Navigation'] then Index.update()
|
||||||
when Conf['Watch']
|
when Conf['Watch']
|
||||||
ThreadWatcher.toggle thread
|
ThreadWatcher.toggle thread
|
||||||
# Images
|
# Images
|
||||||
@ -90,20 +90,33 @@ Keybinds =
|
|||||||
FappeTyme.cb.toggle.call {name: 'werk'}
|
FappeTyme.cb.toggle.call {name: 'werk'}
|
||||||
# Board Navigation
|
# Board Navigation
|
||||||
when Conf['Front page']
|
when Conf['Front page']
|
||||||
if g.VIEW is 'index'
|
if Conf['JSON Navigation'] and g.VIEW is 'index'
|
||||||
Index.userPageNav 0
|
Index.userPageNav 0
|
||||||
else
|
else
|
||||||
window.location = "/#{g.BOARD}/"
|
window.location = "/#{g.BOARD}/"
|
||||||
when Conf['Open front page']
|
when Conf['Open front page']
|
||||||
$.open "/#{g.BOARD}/"
|
$.open "/#{g.BOARD}/"
|
||||||
when Conf['Next page']
|
when Conf['Next page']
|
||||||
return unless g.VIEW is 'index' and Conf['Index Mode'] isnt 'all pages'
|
return unless g.VIEW is 'index'
|
||||||
$('.next button, .next a', Index.pagelist).click()
|
if Conf['JSON Navigation']
|
||||||
|
if Conf['Index Mode'] isnt 'all pages'
|
||||||
|
$('.next button', Index.pagelist).click()
|
||||||
|
else
|
||||||
|
if form = $ '.next form'
|
||||||
|
window.location = form.action
|
||||||
when Conf['Previous page']
|
when Conf['Previous page']
|
||||||
return unless g.VIEW is 'index' and Conf['Index Mode'] isnt 'all pages'
|
return unless g.VIEW is 'index'
|
||||||
$('.prev button, .prev a', Index.pagelist).click()
|
if Conf['JSON Navigation']
|
||||||
|
if Conf['Index Mode'] isnt 'all pages'
|
||||||
|
$('.prev button', Index.pagelist).click()
|
||||||
|
else
|
||||||
|
if form = $ '.prev form'
|
||||||
|
window.location = form.action
|
||||||
when Conf['Search form']
|
when Conf['Search form']
|
||||||
Index.searchInput.focus()
|
if Conf['JSON Navigation']
|
||||||
|
Index.searchInput.focus()
|
||||||
|
else
|
||||||
|
$.id('search-btn').click()
|
||||||
when Conf['Paged mode']
|
when Conf['Paged mode']
|
||||||
return unless g.VIEW is 'index' and Conf['Index Mode'] isnt 'paged'
|
return unless g.VIEW is 'index' and Conf['Index Mode'] isnt 'paged'
|
||||||
Index.setIndexMode 'paged'
|
Index.setIndexMode 'paged'
|
||||||
@ -116,6 +129,13 @@ Keybinds =
|
|||||||
when Conf['Cycle sort type']
|
when Conf['Cycle sort type']
|
||||||
return unless g.VIEW is 'index'
|
return unless g.VIEW is 'index'
|
||||||
Index.cycleSortType()
|
Index.cycleSortType()
|
||||||
|
when Conf['Open catalog']
|
||||||
|
if Conf['External Catalog']
|
||||||
|
window.location = CatalogLinks.external(g.BOARD.ID)
|
||||||
|
else
|
||||||
|
return window.location = "/#{g.BOARD}/catalog" unless Conf['JSON Navigation']
|
||||||
|
return unless g.VIEW is 'index' and Conf['Index Mode'] isnt 'catalog'
|
||||||
|
Index.setIndexMode 'catalog'
|
||||||
# Thread Navigation
|
# Thread Navigation
|
||||||
when Conf['Next thread']
|
when Conf['Next thread']
|
||||||
return if g.VIEW isnt 'index'
|
return if g.VIEW isnt 'index'
|
||||||
@ -219,7 +239,7 @@ Keybinds =
|
|||||||
|
|
||||||
open: (thread, tab) ->
|
open: (thread, tab) ->
|
||||||
return if g.VIEW isnt 'index'
|
return if g.VIEW isnt 'index'
|
||||||
url = "/#{thread.board}/res/#{thread}"
|
url = "/#{thread.board}/thread/#{thread}"
|
||||||
if tab
|
if tab
|
||||||
$.open url
|
$.open url
|
||||||
else
|
else
|
||||||
|
|||||||
@ -245,8 +245,13 @@ ThreadUpdater =
|
|||||||
else
|
else
|
||||||
ThreadUpdater.set 'timer', 'Update'
|
ThreadUpdater.set 'timer', 'Update'
|
||||||
ThreadUpdater.req?.abort()
|
ThreadUpdater.req?.abort()
|
||||||
url = "//a.4cdn.org/#{ThreadUpdater.thread.board}/res/#{ThreadUpdater.thread}.json"
|
url = "//a.4cdn.org/#{ThreadUpdater.thread.board}/thread/#{ThreadUpdater.thread}.json"
|
||||||
ThreadUpdater.req = $.ajax url, onloadend: ThreadUpdater.cb.load,
|
ThreadUpdater.req = $.ajax url,
|
||||||
|
onabort: ThreadUpdater.cb.load
|
||||||
|
onloadend: ThreadUpdater.cb.load
|
||||||
|
ontimeout: ThreadUpdater.cb.load
|
||||||
|
timeout: $.MINUTE
|
||||||
|
,
|
||||||
whenModified: true
|
whenModified: true
|
||||||
|
|
||||||
updateThreadStatus: (type, status) ->
|
updateThreadStatus: (type, status) ->
|
||||||
|
|||||||
@ -114,7 +114,7 @@ ThreadWatcher =
|
|||||||
return if data.isDead
|
return if data.isDead
|
||||||
{fetchCount} = ThreadWatcher
|
{fetchCount} = ThreadWatcher
|
||||||
fetchCount.fetching++
|
fetchCount.fetching++
|
||||||
$.ajax "//a.4cdn.org/#{boardID}/res/#{threadID}.json",
|
$.ajax "//a.4cdn.org/#{boardID}/thread/#{threadID}.json",
|
||||||
onloadend: ->
|
onloadend: ->
|
||||||
fetchCount.fetched++
|
fetchCount.fetched++
|
||||||
if fetchCount.fetched is fetchCount.fetching
|
if fetchCount.fetched is fetchCount.fetching
|
||||||
@ -153,7 +153,7 @@ ThreadWatcher =
|
|||||||
if data.isDead
|
if data.isDead
|
||||||
href = Redirect.to 'thread', {boardID, threadID}
|
href = Redirect.to 'thread', {boardID, threadID}
|
||||||
link = $.el 'a',
|
link = $.el 'a',
|
||||||
href: href or "/#{boardID}/res/#{threadID}"
|
href: href or "/#{boardID}/thread/#{threadID}"
|
||||||
textContent: data.excerpt
|
textContent: data.excerpt
|
||||||
title: data.excerpt
|
title: data.excerpt
|
||||||
|
|
||||||
|
|||||||
@ -219,7 +219,7 @@ QR =
|
|||||||
$.prepend frag, $.tn '[code]'
|
$.prepend frag, $.tn '[code]'
|
||||||
$.add frag, $.tn '[/code]'
|
$.add frag, $.tn '[/code]'
|
||||||
for node in $$ 'br', frag
|
for node in $$ 'br', frag
|
||||||
$.replace node, $.tn '\n>'
|
$.replace node, $.tn '\n>' unless node is frag.lastElementChild
|
||||||
for node in $$ 's', frag
|
for node in $$ 's', frag
|
||||||
$.replace node, [$.tn('[spoiler]'), node.childNodes..., $.tn '[/spoiler]']
|
$.replace node, [$.tn('[spoiler]'), node.childNodes..., $.tn '[/spoiler]']
|
||||||
for node in $$ '.prettyprint', frag
|
for node in $$ '.prettyprint', frag
|
||||||
|
|||||||
@ -56,7 +56,7 @@ QuoteBacklink =
|
|||||||
buildBacklink: (quoted, quoter) ->
|
buildBacklink: (quoted, quoter) ->
|
||||||
frag = QuoteBacklink.frag.cloneNode true
|
frag = QuoteBacklink.frag.cloneNode true
|
||||||
a = frag.lastElementChild
|
a = frag.lastElementChild
|
||||||
a.href = "/#{quoter.board}/res/#{quoter.thread}#p#{quoter}"
|
a.href = "/#{quoter.board}/thread/#{quoter.thread}#p#{quoter}"
|
||||||
a.textContent = text = QuoteBacklink.funk quoter.ID
|
a.textContent = text = QuoteBacklink.funk quoter.ID
|
||||||
if quoter.isDead
|
if quoter.isDead
|
||||||
$.addClass a, 'deadlink'
|
$.addClass a, 'deadlink'
|
||||||
|
|||||||
@ -44,7 +44,7 @@ Quotify =
|
|||||||
# Don't add 'deadlink' when quotifying in an archived post,
|
# Don't add 'deadlink' when quotifying in an archived post,
|
||||||
# and we don't know if the post died yet.
|
# and we don't know if the post died yet.
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
href: "/#{boardID}/res/#{post.thread}#p#{postID}"
|
href: "/#{boardID}/thread/#{post.thread}#p#{postID}"
|
||||||
className: if post.isDead then 'quotelink deadlink' else 'quotelink'
|
className: if post.isDead then 'quotelink deadlink' else 'quotelink'
|
||||||
textContent: quote
|
textContent: quote
|
||||||
$.extend a.dataset, {boardID, threadID: post.thread.ID, postID}
|
$.extend a.dataset, {boardID, threadID: post.thread.ID, postID}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user