Add Quote Inlining. Close #501.
This commit is contained in:
parent
320cb1269c
commit
94b9ff9c36
231
4chan_x.user.js
231
4chan_x.user.js
@ -73,7 +73,7 @@
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var $, $$, Board, Clone, Conf, Config, Main, Post, QuoteBacklink, Quotify, Thread, Time, UI, d, g,
|
||||
var $, $$, Board, Clone, Conf, Config, Get, Main, Post, QuoteBacklink, QuoteInline, Quotify, Thread, Time, UI, d, g,
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||||
|
||||
@ -628,16 +628,10 @@
|
||||
return this.ID;
|
||||
};
|
||||
|
||||
function Thread(root, board) {
|
||||
var postInfo;
|
||||
this.root = root;
|
||||
function Thread(ID, board) {
|
||||
this.board = board;
|
||||
this.ID = +root.id.slice(1);
|
||||
this.hr = root.nextElementSibling;
|
||||
this.ID = +ID;
|
||||
this.posts = {};
|
||||
postInfo = $('.postInfo', root.firstElementChild);
|
||||
this.isClosed = !!$('img[title=Closed]', postInfo);
|
||||
this.isSticky = !!$('img[title=Sticky]', postInfo);
|
||||
g.threads["" + board + "." + this] = board.threads[this] = this;
|
||||
}
|
||||
|
||||
@ -665,7 +659,8 @@
|
||||
post: post,
|
||||
info: info,
|
||||
comment: $('.postMessage', post),
|
||||
quotelinks: []
|
||||
quotelinks: [],
|
||||
backlinks: info.getElementsByClassName('backlink')
|
||||
};
|
||||
this.info = {};
|
||||
if (subject = $('.subject', info)) {
|
||||
@ -753,12 +748,11 @@
|
||||
};
|
||||
|
||||
Post.prototype.rmClone = function(index) {
|
||||
var clone, i, _i, _ref;
|
||||
clone = this.clones.splice(index, 1);
|
||||
var i, _i, _ref;
|
||||
this.clones.splice(index, 1);
|
||||
for (i = _i = index, _ref = this.clones.length; index <= _ref ? _i < _ref : _i > _ref; i = index <= _ref ? ++_i : --_i) {
|
||||
this.clones[i].nodes.root.setAttribute('data-clone', i);
|
||||
}
|
||||
return $.rm(clone.nodes.root);
|
||||
};
|
||||
|
||||
return Post;
|
||||
@ -770,7 +764,7 @@
|
||||
__extends(Clone, _super);
|
||||
|
||||
function Clone(origin) {
|
||||
var file, index, info, key, nodes, post, quotelink, root, val, _i, _j, _len, _len1, _ref, _ref1, _ref2;
|
||||
var file, index, info, inline, inlined, key, nodes, post, quotelink, root, val, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4;
|
||||
this.origin = origin;
|
||||
_ref = ['ID', 'board', 'thread', 'info', 'quotes', 'isReply'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
@ -786,8 +780,20 @@
|
||||
post: post,
|
||||
info: info,
|
||||
comment: $('.postMessage', post),
|
||||
quotelinks: []
|
||||
quotelinks: [],
|
||||
backlinks: info.getElementsByClassName('backlink')
|
||||
};
|
||||
_ref1 = $$('.inline', post);
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
inline = _ref1[_j];
|
||||
$.rm(inline);
|
||||
}
|
||||
_ref2 = $$('.inlined', post);
|
||||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
|
||||
inlined = _ref2[_k];
|
||||
$.rmClass(inlined, 'inlined');
|
||||
}
|
||||
$.rmClass(root, 'forwarded');
|
||||
if (nodes.subject) {
|
||||
this.nodes.subject = $('.subject', info);
|
||||
}
|
||||
@ -812,18 +818,18 @@
|
||||
if (nodes.date) {
|
||||
this.nodes.date = $('.dateTime', info);
|
||||
}
|
||||
_ref1 = $$('.quotelink', this.nodes.comment);
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
quotelink = _ref1[_j];
|
||||
_ref3 = $$('.quotelink', this.nodes.comment);
|
||||
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
|
||||
quotelink = _ref3[_l];
|
||||
if (quotelink.hash || $.hasClass(quotelink, 'deadlink')) {
|
||||
this.nodes.quotelinks.push(quotelink);
|
||||
}
|
||||
}
|
||||
if (origin.file) {
|
||||
this.file = {};
|
||||
_ref2 = origin.file;
|
||||
for (key in _ref2) {
|
||||
val = _ref2[key];
|
||||
_ref4 = origin.file;
|
||||
for (key in _ref4) {
|
||||
val = _ref4[key];
|
||||
this.file[key] = val;
|
||||
}
|
||||
file = $('.file', post);
|
||||
@ -832,7 +838,7 @@
|
||||
this.file.thumb = $('img[data-md5]', file);
|
||||
}
|
||||
this.isClone = true;
|
||||
index = origin.clones.push(this);
|
||||
index = origin.clones.push(this) - 1;
|
||||
root.setAttribute('data-clone', index);
|
||||
}
|
||||
|
||||
@ -920,6 +926,13 @@
|
||||
$.log(err, 'Resurrect Quotes');
|
||||
}
|
||||
}
|
||||
if (Conf['Quote Inline']) {
|
||||
try {
|
||||
QuoteInline.init();
|
||||
} catch (err) {
|
||||
$.log(err, 'Quote Inline');
|
||||
}
|
||||
}
|
||||
if (Conf['Quote Backlinks']) {
|
||||
try {
|
||||
QuoteBacklink.init();
|
||||
@ -949,7 +962,7 @@
|
||||
if (!$.hasClass(boardChild, 'thread')) {
|
||||
continue;
|
||||
}
|
||||
thread = new Thread(boardChild, g.BOARD);
|
||||
thread = new Thread(boardChild.id.slice(1), g.BOARD);
|
||||
threads.push(thread);
|
||||
_ref1 = boardChild.children;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
@ -993,7 +1006,75 @@
|
||||
return $.on(d, 'DOMNodeInserted', Main.addStyle);
|
||||
}
|
||||
},
|
||||
css: "/* general */\n.move {\n cursor: move;\n}\nlabel {\n cursor: pointer;\n}\n\n/* 4chan style fixes */\n.opContainer, .op {\n display: block !important;\n}\n.post {\n overflow: visible !important;\n}\n\n/* header */\nbody.fourchan_x {\n margin-top: 2.5em;\n}\n#boardNavDesktop.reply {\n border-width: 0 0 1px;\n padding: 4px;\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n transition: opacity .1s ease-in-out;\n -o-transition: opacity .1s ease-in-out;\n -moz-transition: opacity .1s ease-in-out;\n -webkit-transition: opacity .1s ease-in-out;\n z-index: 1;\n}\n#boardNavDesktop.reply:not(:hover) {\n opacity: .4;\n transition: opacity 1.5s .5s ease-in-out;\n -o-transition: opacity 1.5s .5s ease-in-out;\n -moz-transition: opacity 1.5s .5s ease-in-out;\n -webkit-transition: opacity 1.5s .5s ease-in-out;\n}\n#boardNavDesktop.reply a {\n margin: -1px;\n}\n#settings {\n float: right;\n}"
|
||||
css: "/* general */\n.move {\n cursor: move;\n}\nlabel {\n cursor: pointer;\n}\n.warning {\n color: red;\n}\n\n/* 4chan style fixes */\n.opContainer, .op {\n display: block !important;\n}\n.post {\n overflow: visible !important;\n}\n\n/* header */\nbody.fourchan_x {\n margin-top: 2.5em;\n}\n#boardNavDesktop.reply {\n border-width: 0 0 1px;\n padding: 4px;\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n transition: opacity .1s ease-in-out;\n -o-transition: opacity .1s ease-in-out;\n -moz-transition: opacity .1s ease-in-out;\n -webkit-transition: opacity .1s ease-in-out;\n z-index: 1;\n}\n#boardNavDesktop.reply:not(:hover) {\n opacity: .4;\n transition: opacity 1.5s .5s ease-in-out;\n -o-transition: opacity 1.5s .5s ease-in-out;\n -moz-transition: opacity 1.5s .5s ease-in-out;\n -webkit-transition: opacity 1.5s .5s ease-in-out;\n}\n#boardNavDesktop.reply a {\n margin: -1px;\n}\n#settings {\n float: right;\n}\n\n/* quotes */\n.inlined {\n opacity: .5;\n}\n.forwarded {\n display: none;\n}\n.inline {\n border: 1px solid rgba(128, 128, 128, 0.5);\n display: table;\n margin: 2px 0;\n}\n.inline .post {\n display: table !important;\n margin: 0 !important;\n padding: 1px 2px !important;\n border: 0 !important;\n}"
|
||||
};
|
||||
|
||||
Get = {
|
||||
post: function(board, threadID, postID, root) {
|
||||
var clone, origin;
|
||||
if (origin = g.posts["" + board + "." + postID]) {
|
||||
clone = origin.addClone();
|
||||
$.add(root, Get.cleanRoot(clone));
|
||||
Main.callbackNodes(Post, [clone]);
|
||||
return;
|
||||
}
|
||||
root.textContent = "Loading post No." + postID + "...";
|
||||
if (threadID) {
|
||||
return $.cache("/" + board + "/res/" + threadID, function() {
|
||||
return Get.parsePost(this, board, threadID, postID, root);
|
||||
});
|
||||
}
|
||||
},
|
||||
cleanRoot: function(clone) {
|
||||
var child, post, root, _i, _len, _ref, _ref1;
|
||||
_ref = clone.nodes, root = _ref.root, post = _ref.post;
|
||||
_ref1 = Array.prototype.slice.call(root.childNodes);
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
child = _ref1[_i];
|
||||
if (child !== post) {
|
||||
$.rm(child);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
},
|
||||
parsePost: function(req, board, threadID, postID, root) {
|
||||
var clone, doc, href, inBoard, inThread, link, pc, post, quote, status, _i, _len, _ref;
|
||||
status = req.status;
|
||||
if (status !== 200) {
|
||||
$.addClass(root, 'warning');
|
||||
root.textContent = status === 404 ? "Thread No." + threadID + " has not been found." : "Error " + req.status + ": " + req.statusText + ".";
|
||||
return;
|
||||
}
|
||||
doc = d.implementation.createHTMLDocument('');
|
||||
doc.documentElement.innerHTML = req.response;
|
||||
if (!(pc = doc.getElementById("pc" + postID))) {
|
||||
root.textContent = "Post No." + postID + " has not been found.";
|
||||
return;
|
||||
}
|
||||
pc = d.importNode(pc, true);
|
||||
_ref = $$('.quotelink', pc);
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
quote = _ref[_i];
|
||||
href = quote.getAttribute('href');
|
||||
if (href[0] === '/') {
|
||||
continue;
|
||||
}
|
||||
quote.href = "/" + board + "/res/" + href;
|
||||
}
|
||||
link = $('a[title="Highlight this post"]', pc);
|
||||
link.href = "/" + board + "/res/" + threadID + "#p" + postID;
|
||||
link.nextSibling.href = "/" + board + "/res/" + threadID + "#q" + postID;
|
||||
inBoard = g.boards[board] || new Board(board);
|
||||
inThread = g.threads["" + board + "." + threadID] || new Thread(threadID, inBoard);
|
||||
post = new Post(pc, inThread, inBoard);
|
||||
Main.callbackNodes(Post, [post]);
|
||||
if (!root.parentNode) {
|
||||
return;
|
||||
}
|
||||
clone = post.addClone();
|
||||
$.replace(root.firstChild, Get.cleanRoot(clone));
|
||||
return Main.callbackNodes(Post, [clone]);
|
||||
}
|
||||
};
|
||||
|
||||
Quotify = {
|
||||
@ -1044,6 +1125,100 @@
|
||||
}
|
||||
};
|
||||
|
||||
QuoteInline = {
|
||||
init: function() {
|
||||
return Post.prototype.callbacks.push({
|
||||
name: 'Quote Inline',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var link, _i, _j, _len, _len1, _ref, _ref1;
|
||||
_ref = this.nodes.quotelinks;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
link = _ref[_i];
|
||||
$.on(link, 'click', QuoteInline.toggle);
|
||||
}
|
||||
_ref1 = this.nodes.backlinks;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
link = _ref1[_j];
|
||||
$.on(link, 'click', QuoteInline.toggle);
|
||||
}
|
||||
},
|
||||
toggle: function(e) {
|
||||
var board, path, postID, threadID;
|
||||
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
path = this.pathname.split('/');
|
||||
board = path[1];
|
||||
threadID = path[3];
|
||||
postID = this.hash.slice(2);
|
||||
if ($.hasClass(this, 'inlined')) {
|
||||
QuoteInline.rm(this, board, threadID, postID);
|
||||
} else {
|
||||
if ($.x("ancestor::div[@id='p" + postID + "']", this)) {
|
||||
return;
|
||||
}
|
||||
QuoteInline.add(this, board, threadID, postID);
|
||||
}
|
||||
return this.classList.toggle('inlined');
|
||||
},
|
||||
add: function(quotelink, board, threadID, postID) {
|
||||
var inline, isBacklink, post, root;
|
||||
inline = $.el('div', {
|
||||
id: "i" + postID,
|
||||
className: 'inline'
|
||||
});
|
||||
root = (isBacklink = $.hasClass(quotelink, 'backlink')) ? quotelink.parentNode.parentNode : $.x('ancestor-or-self::*[parent::blockquote][1]', quotelink);
|
||||
$.after(root, inline);
|
||||
Get.post(board, threadID, postID, inline);
|
||||
if (!(board === g.BOARD.ID && $.x("ancestor::div[@id='t" + threadID + "']", quotelink))) {
|
||||
return;
|
||||
}
|
||||
post = g.posts["" + board + "." + postID];
|
||||
if (isBacklink && Conf['Forward Hiding']) {
|
||||
$.addClass(post.nodes.root, 'forwarded');
|
||||
return post.forwarded++ || (post.forwarded = 1);
|
||||
}
|
||||
},
|
||||
rm: function(quotelink, board, threadID, postID) {
|
||||
var el, inThreadID, index, inline, inlines, path, post, root, _i, _len;
|
||||
root = $.x("following::div[@id='i" + postID + "'][1]", quotelink);
|
||||
$.rm(root);
|
||||
if (!(el = root.firstElementChild)) {
|
||||
return;
|
||||
}
|
||||
post = g.posts["" + board + "." + postID];
|
||||
post.rmClone(el.dataset.clone);
|
||||
inThreadID = $.x('ancestor::div[@class="thread"]', quotelink).id.slice(1);
|
||||
if (Conf['Forward Hiding'] && board === g.BOARD.ID && threadID === inThreadID && $.hasClass(quotelink, 'backlink')) {
|
||||
if (!--post.forwarded) {
|
||||
delete post.forwarded;
|
||||
$.rmClass(post.nodes.root, 'forwarded');
|
||||
}
|
||||
}
|
||||
inlines = $$('.inlined', el);
|
||||
for (_i = 0, _len = inlines.length; _i < _len; _i++) {
|
||||
inline = inlines[_i];
|
||||
path = inline.pathname.split('/');
|
||||
board = path[1];
|
||||
threadID = path[3];
|
||||
postID = inline.hash.slice(2);
|
||||
index = $.x("following::div[@id='i" + postID + "'][1]/child::div", inline).dataset.clone;
|
||||
post = g.posts["" + board + "." + postID];
|
||||
post.rmClone(index);
|
||||
if (Conf['Forward Hiding'] && board === g.BOARD.ID && threadID === inThreadID && $.hasClass(inline, 'backlink')) {
|
||||
if (!--post.forwarded) {
|
||||
delete post.forwarded;
|
||||
$.rmClass(post.nodes.root, 'forwarded');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
QuoteBacklink = {
|
||||
init: function() {
|
||||
var format;
|
||||
@ -1083,6 +1258,9 @@
|
||||
for (_k = 0, _len2 = containers.length; _k < _len2; _k++) {
|
||||
container = containers[_k];
|
||||
link = a.cloneNode(true);
|
||||
if (Conf['Quote Inline']) {
|
||||
$.on(link, 'click', QuoteInline.toggle);
|
||||
}
|
||||
$.add(container, [$.tn(' '), link]);
|
||||
}
|
||||
}
|
||||
@ -1090,9 +1268,7 @@
|
||||
secondNode: function() {
|
||||
var container;
|
||||
if (this.isClone && this.origin.nodes.backlinkContainer) {
|
||||
container = $('.container', this.nodes.info);
|
||||
this.nodes.backlinkContainer = container;
|
||||
this.nodes.backlinks = container.getElementsByClassName('backlinks');
|
||||
this.nodes.backlinkContainer = $('.container', this.nodes.info);
|
||||
return;
|
||||
}
|
||||
if (!(Conf['OP Backlinks'] || this.isReply)) {
|
||||
@ -1100,7 +1276,6 @@
|
||||
}
|
||||
container = QuoteBacklink.getContainer("" + this.board + "." + this);
|
||||
this.nodes.backlinkContainer = container;
|
||||
this.nodes.backlinks = container.getElementsByClassName('backlinks');
|
||||
return $.add(this.nodes.info, container);
|
||||
},
|
||||
getContainer: function(id) {
|
||||
|
||||
245
script.coffee
245
script.coffee
@ -486,14 +486,15 @@ class Thread
|
||||
callbacks: []
|
||||
toString: -> @ID
|
||||
|
||||
constructor: (@root, @board) ->
|
||||
@ID = +root.id[1..]
|
||||
@hr = root.nextElementSibling
|
||||
constructor: (ID, @board) ->
|
||||
@ID = +ID
|
||||
@posts = {}
|
||||
|
||||
postInfo = $ '.postInfo', root.firstElementChild
|
||||
@isClosed = !!$ 'img[title=Closed]', postInfo
|
||||
@isSticky = !!$ 'img[title=Sticky]', postInfo
|
||||
# XXX Can't check when parsing single posts
|
||||
# move to Post constructor? unless @isReply
|
||||
# postInfo = $ '.postInfo', root.firstElementChild
|
||||
# @isClosed = !!$ 'img[title=Closed]', postInfo
|
||||
# @isSticky = !!$ 'img[title=Sticky]', postInfo
|
||||
|
||||
g.threads["#{board}.#{@}"] = board.threads[@] = @
|
||||
|
||||
@ -512,6 +513,7 @@ class Post
|
||||
info: info
|
||||
comment: $ '.postMessage', post
|
||||
quotelinks: []
|
||||
backlinks: info.getElementsByClassName 'backlink'
|
||||
|
||||
@info = {}
|
||||
if subject = $ '.subject', info
|
||||
@ -595,10 +597,10 @@ class Post
|
||||
addClone: ->
|
||||
new Clone @
|
||||
rmClone: (index) ->
|
||||
clone = @clones.splice index, 1
|
||||
@clones.splice index, 1
|
||||
for i in [index...@clones.length]
|
||||
@clones[i].nodes.root.setAttribute 'data-clone', i
|
||||
$.rm clone.nodes.root
|
||||
return
|
||||
|
||||
class Clone extends Post
|
||||
constructor: (@origin) ->
|
||||
@ -616,6 +618,17 @@ class Clone extends Post
|
||||
info: info
|
||||
comment: $ '.postMessage', post
|
||||
quotelinks: []
|
||||
backlinks: info.getElementsByClassName 'backlink'
|
||||
|
||||
# Remove inlined posts inside of this post.
|
||||
for inline in $$ '.inline', post
|
||||
$.rm inline
|
||||
for inlined in $$ '.inlined', post
|
||||
$.rmClass inlined, 'inlined'
|
||||
|
||||
# root.hidden = false # post hiding
|
||||
$.rmClass root, 'forwarded' # quote inlining
|
||||
# $.rmClass post, 'highlight' # keybind navigation
|
||||
|
||||
if nodes.subject
|
||||
@nodes.subject = $ '.subject', info
|
||||
@ -651,7 +664,7 @@ class Clone extends Post
|
||||
@file.thumb = $ 'img[data-md5]', file
|
||||
|
||||
@isClone = true
|
||||
index = origin.clones.push @
|
||||
index = origin.clones.push(@) - 1
|
||||
root.setAttribute 'data-clone', index
|
||||
|
||||
|
||||
@ -726,6 +739,13 @@ Main =
|
||||
# XXX handle error
|
||||
$.log err, 'Resurrect Quotes'
|
||||
|
||||
if Conf['Quote Inline']
|
||||
try
|
||||
QuoteInline.init()
|
||||
catch err
|
||||
# XXX handle error
|
||||
$.log err, 'Quote Inline'
|
||||
|
||||
if Conf['Quote Backlinks']
|
||||
try
|
||||
QuoteBacklink.init()
|
||||
@ -749,7 +769,7 @@ Main =
|
||||
|
||||
for boardChild in $('.board').children
|
||||
continue unless $.hasClass boardChild, 'thread'
|
||||
thread = new Thread boardChild, g.BOARD
|
||||
thread = new Thread boardChild.id[1..], g.BOARD
|
||||
threads.push thread
|
||||
for threadChild in boardChild.children
|
||||
continue unless $.hasClass threadChild, 'postContainer'
|
||||
@ -793,6 +813,9 @@ Main =
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
.warning {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* 4chan style fixes */
|
||||
.opContainer, .op {
|
||||
@ -832,10 +855,101 @@ body.fourchan_x {
|
||||
#settings {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* quotes */
|
||||
.inlined {
|
||||
opacity: .5;
|
||||
}
|
||||
.forwarded {
|
||||
display: none;
|
||||
}
|
||||
.inline {
|
||||
border: 1px solid rgba(128, 128, 128, 0.5);
|
||||
display: table;
|
||||
margin: 2px 0;
|
||||
}
|
||||
.inline .post {
|
||||
display: table !important;
|
||||
margin: 0 !important;
|
||||
padding: 1px 2px !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
Get =
|
||||
post: (board, threadID, postID, root) ->
|
||||
if origin = g.posts["#{board}.#{postID}"]
|
||||
clone = origin.addClone()
|
||||
$.add root, Get.cleanRoot clone
|
||||
Main.callbackNodes Post, [clone]
|
||||
return
|
||||
|
||||
root.textContent = "Loading post No.#{postID}..."
|
||||
if threadID
|
||||
$.cache "/#{board}/res/#{threadID}", ->
|
||||
Get.parsePost @, board, threadID, postID, root
|
||||
# else if url = Redirect.post board, postID
|
||||
# $.cache url, ->
|
||||
# Get.parseArchivedPost @, board, postID, root
|
||||
cleanRoot: (clone) ->
|
||||
{root, post} = clone.nodes
|
||||
for child in Array::slice.call root.childNodes
|
||||
$.rm child unless child is post
|
||||
root
|
||||
parsePost: (req, board, threadID, postID, root) ->
|
||||
{status} = req
|
||||
if status isnt 200
|
||||
# The thread can die by the time we check a quote.
|
||||
# XXX
|
||||
# if url = Redirect.post board, postID
|
||||
# $.cache url, ->
|
||||
# Get.parseArchivedPost @, board, postID, root
|
||||
# else
|
||||
$.addClass root, 'warning'
|
||||
root.textContent =
|
||||
if status is 404
|
||||
"Thread No.#{threadID} has not been found."
|
||||
else
|
||||
"Error #{req.status}: #{req.statusText}."
|
||||
return
|
||||
|
||||
doc = d.implementation.createHTMLDocument ''
|
||||
doc.documentElement.innerHTML = req.response
|
||||
|
||||
unless pc = doc.getElementById "pc#{postID}"
|
||||
# The post can be deleted by the time we check a quote.
|
||||
# XXX
|
||||
# if url = Redirect.post board, postID
|
||||
# $.cache url, ->
|
||||
# Get.parseArchivedPost @, board, postID, root
|
||||
# else
|
||||
root.textContent = "Post No.#{postID} has not been found."
|
||||
return
|
||||
pc = d.importNode pc, true
|
||||
|
||||
for quote in $$ '.quotelink', pc
|
||||
href = quote.getAttribute 'href'
|
||||
continue if href[0] is '/' # Cross-board quote, or board link
|
||||
quote.href = "/#{board}/res/#{href}" # Fix pathnames
|
||||
link = $ 'a[title="Highlight this post"]', pc
|
||||
link.href = "/#{board}/res/#{threadID}#p#{postID}"
|
||||
link.nextSibling.href = "/#{board}/res/#{threadID}#q#{postID}"
|
||||
|
||||
inBoard = g.boards[board] or
|
||||
new Board board
|
||||
inThread = g.threads["#{board}.#{threadID}"] or
|
||||
new Thread threadID, inBoard
|
||||
post = new Post pc, inThread, inBoard
|
||||
Main.callbackNodes Post, [post]
|
||||
|
||||
# Stop here if the container has been removed while loading.
|
||||
return unless root.parentNode
|
||||
clone = post.addClone()
|
||||
$.replace root.firstChild, Get.cleanRoot clone
|
||||
Main.callbackNodes Post, [clone]
|
||||
|
||||
Quotify =
|
||||
init: ->
|
||||
Post::callbacks.push
|
||||
@ -884,7 +998,6 @@ Quotify =
|
||||
# if board is g.BOARD and $.id "p#{ID}"
|
||||
# a.href = "#p#{ID}"
|
||||
# a.className = 'quotelink'
|
||||
# a.setAttribute 'onclick', "replyhl('#{ID}');"
|
||||
# else
|
||||
# a.href = Redirect.thread board, 0, ID
|
||||
# a.className = 'deadlink'
|
||||
@ -905,6 +1018,105 @@ Quotify =
|
||||
$.replace node, nodes
|
||||
return
|
||||
|
||||
QuoteInline =
|
||||
init: ->
|
||||
Post::callbacks.push
|
||||
name: 'Quote Inline'
|
||||
cb: @node
|
||||
node: ->
|
||||
for link in @nodes.quotelinks
|
||||
$.on link, 'click', QuoteInline.toggle
|
||||
for link in @nodes.backlinks
|
||||
$.on link, 'click', QuoteInline.toggle
|
||||
return
|
||||
toggle: (e) ->
|
||||
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
|
||||
e.preventDefault()
|
||||
# XXX quote resurrection
|
||||
# id = @dataset.id or @hash[2..]
|
||||
path = @pathname.split '/'
|
||||
board = path[1]
|
||||
threadID = path[3]
|
||||
postID = @hash[2..]
|
||||
if $.hasClass @, 'inlined'
|
||||
QuoteInline.rm @, board, threadID, postID
|
||||
else
|
||||
return if $.x "ancestor::div[@id='p#{postID}']", @
|
||||
QuoteInline.add @, board, threadID, postID
|
||||
@classList.toggle 'inlined'
|
||||
|
||||
add: (quotelink, board, threadID, postID) ->
|
||||
inline = $.el 'div',
|
||||
id: "i#{postID}"
|
||||
className: 'inline'
|
||||
|
||||
root =
|
||||
if isBacklink = $.hasClass quotelink, 'backlink'
|
||||
quotelink.parentNode.parentNode
|
||||
else
|
||||
$.x 'ancestor-or-self::*[parent::blockquote][1]', quotelink
|
||||
$.after root, inline
|
||||
Get.post board, threadID, postID, inline
|
||||
|
||||
return unless board is g.BOARD.ID and $.x "ancestor::div[@id='t#{threadID}']", quotelink
|
||||
post = g.posts["#{board}.#{postID}"]
|
||||
|
||||
# Hide forward post if it's a backlink of a post in this thread.
|
||||
# Will only unhide if there's no inlined backlinks of it anymore.
|
||||
if isBacklink and Conf['Forward Hiding']
|
||||
$.addClass post.nodes.root, 'forwarded'
|
||||
post.forwarded++ or post.forwarded = 1
|
||||
|
||||
# Decrease the unread count if this post is in the array of unread reply.
|
||||
# XXX
|
||||
# if (i = Unread.replies.indexOf el) isnt -1
|
||||
# Unread.replies.splice i, 1
|
||||
# Unread.update true
|
||||
|
||||
rm: (quotelink, board, threadID, postID) ->
|
||||
# Select the corresponding inlined quote, and remove it.
|
||||
root = $.x "following::div[@id='i#{postID}'][1]", quotelink
|
||||
$.rm root
|
||||
|
||||
# Stop if it's still loading.
|
||||
return unless el = root.firstElementChild
|
||||
|
||||
# Dereference clone.
|
||||
post = g.posts["#{board}.#{postID}"]
|
||||
post.rmClone el.dataset.clone
|
||||
|
||||
inThreadID = $.x('ancestor::div[@class="thread"]', quotelink).id[1..]
|
||||
|
||||
# Decrease forward count and unhide.
|
||||
if Conf['Forward Hiding'] and
|
||||
board is g.BOARD.ID and
|
||||
threadID is inThreadID and
|
||||
$.hasClass quotelink, 'backlink'
|
||||
unless --post.forwarded
|
||||
delete post.forwarded
|
||||
$.rmClass post.nodes.root, 'forwarded'
|
||||
|
||||
# Repeat.
|
||||
inlines = $$ '.inlined', el
|
||||
for inline in inlines
|
||||
# XXX resurrected quotes
|
||||
path = inline.pathname.split '/'
|
||||
board = path[1]
|
||||
threadID = path[3]
|
||||
postID = inline.hash[2..]
|
||||
index = $.x("following::div[@id='i#{postID}'][1]/child::div", inline).dataset.clone
|
||||
post = g.posts["#{board}.#{postID}"]
|
||||
post.rmClone index
|
||||
|
||||
if Conf['Forward Hiding'] and
|
||||
board is g.BOARD.ID and
|
||||
threadID is inThreadID and
|
||||
$.hasClass inline, 'backlink'
|
||||
unless --post.forwarded
|
||||
delete post.forwarded
|
||||
$.rmClass post.nodes.root, 'forwarded'
|
||||
return
|
||||
|
||||
QuoteBacklink =
|
||||
# Backlinks appending need to work for:
|
||||
# - previous, same, and following posts.
|
||||
@ -944,23 +1156,18 @@ QuoteBacklink =
|
||||
# XXX
|
||||
# if Conf['Quote Preview']
|
||||
# $.on link, 'mouseover', QuotePreview.mouseover
|
||||
# if Conf['Quote Inline']
|
||||
# $.on link, 'click', QuoteInline.toggle
|
||||
# else
|
||||
# link.setAttribute 'onclick', "replyhl('#{post.ID}');"
|
||||
if Conf['Quote Inline']
|
||||
$.on link, 'click', QuoteInline.toggle
|
||||
$.add container, [$.tn(' '), link]
|
||||
return
|
||||
secondNode: ->
|
||||
if @isClone and @origin.nodes.backlinkContainer
|
||||
container = $ '.container', @nodes.info
|
||||
@nodes.backlinkContainer = container
|
||||
@nodes.backlinks = container.getElementsByClassName 'backlinks'
|
||||
@nodes.backlinkContainer = $ '.container', @nodes.info
|
||||
return
|
||||
# Don't backlink the OP.
|
||||
return unless Conf['OP Backlinks'] or @isReply
|
||||
container = QuoteBacklink.getContainer "#{@board}.#{@}"
|
||||
@nodes.backlinkContainer = container
|
||||
@nodes.backlinks = container.getElementsByClassName 'backlinks'
|
||||
$.add @nodes.info, container
|
||||
getContainer: (id) ->
|
||||
@containers[id] or=
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user