Merge branch 'v3'

Conflicts:
	CHANGELOG.md
	LICENSE
	builds/4chan-X.meta.js
	builds/appchan-x.user.js
	builds/crx/manifest.json
	builds/crx/script.js
	latest.js
	package.json
	src/Menu/Menu.coffee
This commit is contained in:
Zixaphir 2014-01-13 13:25:43 -07:00
commit 94dd0e555f
12 changed files with 206 additions and 203 deletions

View File

@ -1,5 +1,6 @@
**seaweeedchan**:
- Convert infinite scrolling into an Index Mode, rather than being forced
- Fix Menu errors on older Firefox versions, such as the ESR
**Zixaphir**:
- Fix an issue where changing the current archive would crash the redirect features.

View File

@ -1,5 +1,5 @@
/*
* appchan x - Version 2.8.0 - 2014-01-12
* appchan x - Version 2.8.0 - 2014-01-13
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE

21
builds/4chan-X.meta.js Executable file
View File

@ -0,0 +1,21 @@
// ==UserScript==
// @name 4chan X
// @version 1.3.2
// @minGMVer 1.13
// @minFFVer 26
// @namespace 4chan-X
// @description Cross-browser userscript for maximum lurking on 4chan.
// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
// @match *://boards.4chan.org/*
// @match *://sys.4chan.org/*
// @match *://a.4cdn.org/*
// @match *://i.4cdn.org/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_openInTab
// @run-at document-start
// @updateURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.meta.js
// @downloadURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.user.js
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC
// ==/UserScript==

View File

@ -22,7 +22,7 @@
// ==/UserScript==
/*
* appchan x - Version 2.8.0 - 2014-01-12
* appchan x - Version 2.8.0 - 2014-01-13
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@ -117,15 +117,17 @@
__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; },
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Array.prototype.indexOf = function(val) {
var i;
i = this.length;
while (i--) {
Array.prototype.indexOf = function(val, i) {
var len;
i || (i = 0);
len = this.length;
while (i < len) {
if (this[i] === val) {
return i;
}
i++;
}
return i;
return -1;
};
__indexOf = [].indexOf;
@ -4576,7 +4578,7 @@
});
this.navLinks = $.el('div', {
className: 'navLinks',
innerHTML: "<a href=.././ id=returnlink>Return</a> [<a href=javascript:; id=cataloglink>Catalog</a>] <a href=\"#bottom\" id=bottomlink>Bottom</a> <time id=\"index-last-refresh\" title=\"Last index refresh\">...</time> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" class=\"fa\" href=\"javascript:;\">\uf057</a>"
innerHTML: "<span class=brackets-wrap id=returnlink><a href=.././>Return</a></span> <span class=brackets-wrap id=cataloglink><a href=javascript:;>Catalog</a></span> <span class=brackets-wrap id=bottomlink><a href=\"#bottom\">Bottom</a></span> <span class=brackets-wrap id=\"index-last-refresh\"><time title=\"Last index refresh\">...</time></span> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" class=\"fa\" href=\"javascript:;\">\uf057</a>"
});
this.searchInput = $('#index-search', this.navLinks);
this.currentPage = this.getCurrentPage();
@ -4584,8 +4586,8 @@
$.on(this.pagelist, 'click', this.cb.pageNav);
$.on(this.searchInput, 'input', this.onSearchInput);
$.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch);
$.on($('#returnlink', this.navLinks), 'click', Navigate.navigate);
$.on($('#cataloglink', this.navLinks), 'click', function() {
$.on($('#returnlink a', this.navLinks), 'click', Navigate.navigate);
$.on($('#cataloglink a', this.navLinks), 'click', function() {
return window.location = "//boards.4chan.org/" + g.BOARD + "/catalog";
});
if (g.VIEW === 'index') {
@ -4861,7 +4863,7 @@
}
return;
}
timeEl = $('#index-last-refresh', Index.navLinks);
timeEl = $('#index-last-refresh time', Index.navLinks);
timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
RelativeDates.update(timeEl);
return Index.scrollToIndex();
@ -5397,36 +5399,36 @@
};
},
allQuotelinksLinkingTo: function(post) {
var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
var ID, handleQuotes, quote, quotedPost, quotelinks, quoterPost, _i, _len, _ref, _ref1, _ref2;
quotelinks = [];
handleQuotes = function(post, type) {
var clone, _i, _len, _ref;
quotelinks.push.apply(quotelinks, post.nodes[type]);
_ref = post.clones;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
clone = _ref[_i];
quotelinks.push.apply(quotelinks, clone.nodes[type]);
}
};
_ref = g.posts;
for (ID in _ref) {
quoterPost = _ref[ID];
if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
_ref2 = [quoterPost].concat(quoterPost.clones);
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
quoterPost = _ref2[_i];
quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks);
}
handleQuotes(quoterPost, 'quotelinks');
}
}
if (Conf['Quote Backlinks']) {
_ref3 = post.quotes;
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
quote = _ref3[_j];
if (!(quotedPost = g.posts[quote])) {
continue;
}
_ref4 = [quotedPost].concat(quotedPost.clones);
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
quotedPost = _ref4[_k];
quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks));
_ref2 = post.quotes;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
quote = _ref2[_i];
if (quotedPost = g.posts[quote]) {
handleQuotes(quotedPost, 'backlinks');
}
}
}
return quotelinks.filter(function(quotelink) {
var boardID, postID, _ref5;
_ref5 = Get.postDataFromLink(quotelink), boardID = _ref5.boardID, postID = _ref5.postID;
var boardID, postID, _ref3;
_ref3 = Get.postDataFromLink(quotelink), boardID = _ref3.boardID, postID = _ref3.postID;
return boardID === post.board.ID && postID === post.ID;
});
},
@ -7100,28 +7102,14 @@
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
return;
}
if (Conf['Quote Hash Navigation']) {
this.node = function() {
var link, _i, _len, _ref;
_ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
link = _ref[_i];
if (!this.isClone) {
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
}
$.on(link, 'click', QuoteInline.toggle);
}
};
} else {
this.node = function() {
var link, _i, _len, _ref;
_ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
link = _ref[_i];
$.on(link, 'click', QuoteInline.toggle);
}
};
}
this.process = Conf['Quote Hash Navigation'] ? function(link, clone) {
if (!clone) {
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
}
return $.on(link, 'click', QuoteInline.toggle);
} : function(link) {
return $.on(link, 'click', QuoteInline.toggle);
};
if (Conf['Comment Expansion']) {
ExpandComment.callbacks.push(this.node);
}
@ -7130,14 +7118,27 @@
cb: this.node
});
},
node: function() {
var isClone, link, process, _i, _j, _len, _len1, _ref, _ref1;
process = QuoteInline.process;
isClone = this.isClone;
_ref = this.nodes.quotelinks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
link = _ref[_i];
process(link, isClone);
}
_ref1 = this.nodes.backlinks;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
link = _ref1[_j];
process(link, isClone);
}
},
qiQuote: function(link, hidden) {
return [
$.tn(' '), $.el('a', {
className: hidden ? 'hashlink filtered' : 'hashlink',
textContent: '#',
href: link.href
})
];
return $.el('a', {
className: "hashlink" + (hidden ? ' filtered' : ''),
textContent: '#',
href: link.href
});
},
toggle: function(e) {
var boardID, context, postID, threadID, _ref;
@ -10905,21 +10906,16 @@
return $.add(this.nodes.info, Menu.makeButton());
},
makeButton: (function() {
var frag;
frag = null;
var a;
a = $.el('a', {
className: 'menu-button',
innerHTML: '<i class=fa>\uf107</i>',
href: 'javascript:;'
});
return function() {
var clone;
if (frag == null) {
frag = $.nodes([
$.tn(' '), $.el('a', {
className: 'menu-button',
innerHTML: '<i class=fa>\uf107</i>',
href: 'javascript:;'
})
]);
}
clone = frag.cloneNode(true);
$.on(clone.lastElementChild, 'click', Menu.toggle);
clone = a.cloneNode(true);
$.on(clone, 'click', Menu.toggle);
return clone;
};
})(),

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript
/*
* appchan x - Version 2.8.0 - 2014-01-12
* appchan x - Version 2.8.0 - 2014-01-13
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@ -95,15 +95,17 @@
__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; },
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Array.prototype.indexOf = function(val) {
var i;
i = this.length;
while (i--) {
Array.prototype.indexOf = function(val, i) {
var len;
i || (i = 0);
len = this.length;
while (i < len) {
if (this[i] === val) {
return i;
}
i++;
}
return i;
return -1;
};
__indexOf = [].indexOf;
@ -4587,7 +4589,7 @@
});
this.navLinks = $.el('div', {
className: 'navLinks',
innerHTML: "<a href=.././ id=returnlink>Return</a> [<a href=javascript:; id=cataloglink>Catalog</a>] <a href=\"#bottom\" id=bottomlink>Bottom</a> <time id=\"index-last-refresh\" title=\"Last index refresh\">...</time> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" class=\"fa\" href=\"javascript:;\">\uf057</a>"
innerHTML: "<span class=brackets-wrap id=returnlink><a href=.././>Return</a></span> <span class=brackets-wrap id=cataloglink><a href=javascript:;>Catalog</a></span> <span class=brackets-wrap id=bottomlink><a href=\"#bottom\">Bottom</a></span> <span class=brackets-wrap id=\"index-last-refresh\"><time title=\"Last index refresh\">...</time></span> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" class=\"fa\" href=\"javascript:;\">\uf057</a>"
});
this.searchInput = $('#index-search', this.navLinks);
this.currentPage = this.getCurrentPage();
@ -4595,8 +4597,8 @@
$.on(this.pagelist, 'click', this.cb.pageNav);
$.on(this.searchInput, 'input', this.onSearchInput);
$.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch);
$.on($('#returnlink', this.navLinks), 'click', Navigate.navigate);
$.on($('#cataloglink', this.navLinks), 'click', function() {
$.on($('#returnlink a', this.navLinks), 'click', Navigate.navigate);
$.on($('#cataloglink a', this.navLinks), 'click', function() {
return window.location = "//boards.4chan.org/" + g.BOARD + "/catalog";
});
if (g.VIEW === 'index') {
@ -4872,7 +4874,7 @@
}
return;
}
timeEl = $('#index-last-refresh', Index.navLinks);
timeEl = $('#index-last-refresh time', Index.navLinks);
timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
RelativeDates.update(timeEl);
return Index.scrollToIndex();
@ -5408,36 +5410,36 @@
};
},
allQuotelinksLinkingTo: function(post) {
var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
var ID, handleQuotes, quote, quotedPost, quotelinks, quoterPost, _i, _len, _ref, _ref1, _ref2;
quotelinks = [];
handleQuotes = function(post, type) {
var clone, _i, _len, _ref;
quotelinks.push.apply(quotelinks, post.nodes[type]);
_ref = post.clones;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
clone = _ref[_i];
quotelinks.push.apply(quotelinks, clone.nodes[type]);
}
};
_ref = g.posts;
for (ID in _ref) {
quoterPost = _ref[ID];
if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
_ref2 = [quoterPost].concat(quoterPost.clones);
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
quoterPost = _ref2[_i];
quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks);
}
handleQuotes(quoterPost, 'quotelinks');
}
}
if (Conf['Quote Backlinks']) {
_ref3 = post.quotes;
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
quote = _ref3[_j];
if (!(quotedPost = g.posts[quote])) {
continue;
}
_ref4 = [quotedPost].concat(quotedPost.clones);
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
quotedPost = _ref4[_k];
quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks));
_ref2 = post.quotes;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
quote = _ref2[_i];
if (quotedPost = g.posts[quote]) {
handleQuotes(quotedPost, 'backlinks');
}
}
}
return quotelinks.filter(function(quotelink) {
var boardID, postID, _ref5;
_ref5 = Get.postDataFromLink(quotelink), boardID = _ref5.boardID, postID = _ref5.postID;
var boardID, postID, _ref3;
_ref3 = Get.postDataFromLink(quotelink), boardID = _ref3.boardID, postID = _ref3.postID;
return boardID === post.board.ID && postID === post.ID;
});
},
@ -7104,28 +7106,14 @@
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
return;
}
if (Conf['Quote Hash Navigation']) {
this.node = function() {
var link, _i, _len, _ref;
_ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
link = _ref[_i];
if (!this.isClone) {
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
}
$.on(link, 'click', QuoteInline.toggle);
}
};
} else {
this.node = function() {
var link, _i, _len, _ref;
_ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
link = _ref[_i];
$.on(link, 'click', QuoteInline.toggle);
}
};
}
this.process = Conf['Quote Hash Navigation'] ? function(link, clone) {
if (!clone) {
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
}
return $.on(link, 'click', QuoteInline.toggle);
} : function(link) {
return $.on(link, 'click', QuoteInline.toggle);
};
if (Conf['Comment Expansion']) {
ExpandComment.callbacks.push(this.node);
}
@ -7134,14 +7122,27 @@
cb: this.node
});
},
node: function() {
var isClone, link, process, _i, _j, _len, _len1, _ref, _ref1;
process = QuoteInline.process;
isClone = this.isClone;
_ref = this.nodes.quotelinks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
link = _ref[_i];
process(link, isClone);
}
_ref1 = this.nodes.backlinks;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
link = _ref1[_j];
process(link, isClone);
}
},
qiQuote: function(link, hidden) {
return [
$.tn(' '), $.el('a', {
className: hidden ? 'hashlink filtered' : 'hashlink',
textContent: '#',
href: link.href
})
];
return $.el('a', {
className: "hashlink" + (hidden ? ' filtered' : ''),
textContent: '#',
href: link.href
});
},
toggle: function(e) {
var boardID, context, postID, threadID, _ref;
@ -10889,21 +10890,16 @@
return $.add(this.nodes.info, Menu.makeButton());
},
makeButton: (function() {
var frag;
frag = null;
var a;
a = $.el('a', {
className: 'menu-button',
innerHTML: '<i class=fa>\uf107</i>',
href: 'javascript:;'
});
return function() {
var clone;
if (frag == null) {
frag = $.nodes([
$.tn(' '), $.el('a', {
className: 'menu-button',
innerHTML: '<i class=fa>\uf107</i>',
href: 'javascript:;'
})
]);
}
clone = frag.cloneNode(true);
$.on(clone.lastElementChild, 'click', Menu.toggle);
clone = a.cloneNode(true);
$.on(clone, 'click', Menu.toggle);
return clone;
};
})(),

View File

@ -1,9 +1,11 @@
# I am bad at JavaScript and if you reuse this, so are you.
Array::indexOf = (val) ->
i = @length
while i--
Array::indexOf = (val, i) ->
i or= 0
len = @length
while i < len
return i if @[i] is val
return i
i++
return -1
# Update CoffeeScript's reference to [].indexOf
# Reserved keywords are ignored in embedded javascript.

View File

@ -40,24 +40,22 @@ Get =
allQuotelinksLinkingTo: (post) ->
# Get quotelinks & backlinks linking to the given post.
quotelinks = []
handleQuotes = (post, type) ->
quotelinks.push post.nodes[type]...
quotelinks.push clone.nodes[type]... for clone in post.clones
return
# First:
# In every posts,
# if it did quote this post,
# get all their backlinks.
for ID, quoterPost of g.posts
if post.fullID in quoterPost.quotes
for quoterPost in [quoterPost].concat quoterPost.clones
quotelinks.push.apply quotelinks, quoterPost.nodes.quotelinks
handleQuotes quoterPost, 'quotelinks' for ID, quoterPost of g.posts when post.fullID in quoterPost.quotes
# Second:
# If we have quote backlinks:
# in all posts this post quoted
# and their clones,
# get all of their backlinks.
if Conf['Quote Backlinks']
for quote in post.quotes
continue unless quotedPost = g.posts[quote]
for quotedPost in [quotedPost].concat quotedPost.clones
quotelinks.push.apply quotelinks, [quotedPost.nodes.backlinks...]
handleQuotes quotedPost, 'backlinks' for quote in post.quotes when quotedPost = g.posts[quote]
# Third:
# Filter out irrelevant quotelinks.
quotelinks.filter (quotelink) ->

View File

@ -83,9 +83,8 @@ Index =
$.on @pagelist, 'click', @cb.pageNav
$.on @searchInput, 'input', @onSearchInput
$.on $('#index-search-clear', @navLinks), 'click', @clearSearch
$.on $('#returnlink', @navLinks), 'click', Navigate.navigate
$.on $('#cataloglink', @navLinks), 'click', -> window.location = "//boards.4chan.org/#{g.BOARD}/catalog"
$.on $('#returnlink a', @navLinks), 'click', Navigate.navigate
$.on $('#cataloglink a', @navLinks), 'click', -> window.location = "//boards.4chan.org/#{g.BOARD}/catalog"
@update() if g.VIEW is 'index'
$.asap (-> $('.board', doc) or d.readyState isnt 'loading'), ->
@ -287,7 +286,7 @@ Index =
new Notice 'error', 'Index refresh failed.', 1
return
timeEl = $ '#index-last-refresh', Index.navLinks
timeEl = $ '#index-last-refresh time', Index.navLinks
timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified'
RelativeDates.update timeEl
Index.scrollToIndex()

View File

@ -90,6 +90,11 @@ div.navLinks {
.reply > .file > .fileText {
margin: 0 20px;
}
.hashlink::before {
content: ' ';
visibility: hidden;
}
.inline + .hashlink,
[hidden] {
display: none !important;
}
@ -273,12 +278,12 @@ div.center:not(.ad-cnt) {
font-weight: bold;
}
/* 4chan X link brackets */
.brackets-wrap::after {
content: "]";
}
.brackets-wrap::before {
content: "[";
}
.brackets-wrap::after {
content: "]";
}
/* Notifications */
#notifications {
position: fixed;
@ -508,16 +513,6 @@ div.center:not(.ad-cnt) {
.thread #index-search {
display: none;
}
#returnlink::before,
#bottomlink::before,
#index-last-refresh::before {
content: '[';
}
#returnlink::after,
#bottomlink::after,
#index-last-refresh::after {
content: ']';
}
/* Announcement Hiding */
:root.hide-announcement #globalMessage {
@ -1115,7 +1110,7 @@ a:only-of-type > .remove {
.reply .menu-button,
.op .menu-button,
#thread-watcher .menu-button {
margin-left: -5px !important;
margin-left: -1px !important;
position: relative;
}
.op .menu-button,

View File

@ -1,6 +1,6 @@
<a href=.././ id=returnlink>Return</a>
[<a href=javascript:; id=cataloglink>Catalog</a>]
<a href="#bottom" id=bottomlink>Bottom</a>
<time id="index-last-refresh" title="Last index refresh">...</time>
<span class=brackets-wrap id=returnlink><a href=.././>Return</a></span>
<span class=brackets-wrap id=cataloglink><a href=javascript:;>Catalog</a></span>
<span class=brackets-wrap id=bottomlink><a href="#bottom">Bottom</a></span>
<span class=brackets-wrap id="index-last-refresh"><time title="Last index refresh">...</time></span>
<input type="search" id="index-search" class="field" placeholder="Search">
<a id="index-search-clear" class="fa" href="javascript:;">\uf057</a>

View File

@ -14,18 +14,13 @@ Menu =
$.add @nodes.info, Menu.makeButton()
makeButton: do ->
frag = null
a = $.el 'a',
className: 'menu-button'
innerHTML: '<i class=fa>\uf107</i>'
href: 'javascript:;'
->
unless frag?
frag = $.nodes [
$.tn(' ')
$.el 'a',
className: 'menu-button'
innerHTML: '<i class=fa>\uf107</i>'
href: 'javascript:;'
]
clone = frag.cloneNode true
$.on clone.lastElementChild, 'click', Menu.toggle
clone = a.cloneNode true
$.on clone, 'click', Menu.toggle
clone
toggle: (e) ->

View File

@ -2,18 +2,14 @@ QuoteInline =
init: ->
return if g.VIEW is 'catalog' or !Conf['Quote Inlining']
if Conf['Quote Hash Navigation']
@node = ->
for link in @nodes.quotelinks.concat [@nodes.backlinks...]
$.after link, QuoteInline.qiQuote link, $.hasClass link, 'filtered' unless @isClone
$.on link, 'click', QuoteInline.toggle
return
@process = if Conf['Quote Hash Navigation']
(link, clone) ->
$.after link, QuoteInline.qiQuote link, $.hasClass link, 'filtered' unless clone
$.on link, 'click', QuoteInline.toggle
else
@node = ->
for link in @nodes.quotelinks.concat [@nodes.backlinks...]
$.on link, 'click', QuoteInline.toggle
return
(link) ->
$.on link, 'click', QuoteInline.toggle
if Conf['Comment Expansion']
ExpandComment.callbacks.push @node
@ -22,14 +18,18 @@ QuoteInline =
name: 'Quote Inlining'
cb: @node
node: ->
{process} = QuoteInline
{isClone} = @
process link, isClone for link in @nodes.quotelinks
process link, isClone for link in @nodes.backlinks
return
qiQuote: (link, hidden) ->
[
$.tn(' ')
$.el 'a',
className: if hidden then 'hashlink filtered' else 'hashlink'
textContent: '#'
href: link.href
]
$.el 'a',
className: "hashlink#{if hidden then ' filtered' else ''}"
textContent: '#'
href: link.href
toggle: (e) ->
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0