start keybinds rewrite
This commit is contained in:
parent
34c53d5819
commit
7c7d256f3e
154
4chan_x.js
154
4chan_x.js
@ -59,7 +59,7 @@
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var $, $$, NAMESPACE, a, as, autoWatch, callback, changeCheckbox, changeValue, config, d, delform, el, expand, expandComment, expandThread, g, imageClick, imageExpand, imageExpandClick, imageHover, imageResize, imageThumb, imageToggle, imageType, imageTypeChange, keyModeInsert, keyModeNormal, keydown, keypress, log, nav, navtopr, nodeInserted, omitted, onloadComment, onloadThread, option, options, parseResponse, pathname, qr, recaptcha, recaptchaListener, recaptchaReload, redirect, replyHiding, replyNav, report, request, scroll, scrollThread, span, temp, text, threadHiding, tzOffset, ui, updateAuto, updateCallback, updateFavicon, updateInterval, updateNow, updateTime, updateTitle, updateVerbose, updater, updaterMake, watcher, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _m, _ref, _ref2, _ref3, _ref4;
|
||||
var $, $$, NAMESPACE, a, as, autoWatch, callback, changeCheckbox, changeValue, config, d, delform, el, expand, expandComment, expandThread, g, imageClick, imageExpand, imageExpandClick, imageHover, imageResize, imageThumb, imageToggle, imageType, imageTypeChange, keyModeNormal, keybinds, log, nav, navtopr, nodeInserted, omitted, onloadComment, onloadThread, option, options, parseResponse, pathname, qr, recaptcha, recaptchaListener, recaptchaReload, redirect, replyHiding, replyNav, report, request, scroll, scrollThread, span, temp, text, threadHiding, tzOffset, ui, updateAuto, updateCallback, updateFavicon, updateInterval, updateNow, updateTime, updateTitle, updateVerbose, updater, updaterMake, watcher, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _m, _ref, _ref2, _ref3, _ref4;
|
||||
var __slice = Array.prototype.slice;
|
||||
if (typeof console != "undefined" && console !== null) {
|
||||
log = console.log;
|
||||
@ -75,7 +75,7 @@
|
||||
'Image Expansion': [true, 'Expand images'],
|
||||
'Image Hover': [false, 'Show full image on mouseover'],
|
||||
'Image Preloading': [false, 'Preload Images'],
|
||||
'Keybinds': [false, 'Binds actions to keys'],
|
||||
'Keybinds': [true, 'Binds actions to keys'],
|
||||
'Localize Time': [true, 'Show times based on your timezone'],
|
||||
'Persistent QR': [false, 'Quick reply won\'t disappear after posting. Only in replies.'],
|
||||
'Post in Title': [true, 'Show the op\'s post in the tab title'],
|
||||
@ -662,42 +662,90 @@
|
||||
thumb.className = '';
|
||||
return $.remove(thumb.nextSibling);
|
||||
};
|
||||
keydown = function(e) {
|
||||
var kc;
|
||||
kc = e.keyCode;
|
||||
g.keyCode = kc;
|
||||
return g.char = String.fromCharCode(kc);
|
||||
};
|
||||
keypress = function(e) {
|
||||
var _ref;
|
||||
if ((_ref = d.activeElement.nodeName) === 'TEXTAREA' || _ref === 'INPUT') {
|
||||
return keyModeInsert(e);
|
||||
} else {
|
||||
return keyModeNormal(e);
|
||||
}
|
||||
};
|
||||
keyModeInsert = function(e) {
|
||||
var char, kc, range, selEnd, selStart, ta, valEnd, valMid, valStart, value;
|
||||
kc = g.keyCode;
|
||||
char = g.char;
|
||||
if (kc === 27) {
|
||||
$.remove($('#qr'));
|
||||
return e.preventDefault();
|
||||
} else if (e.ctrlKey && char === "S") {
|
||||
ta = d.activeElement;
|
||||
if (ta.nodeName !== 'TEXTAREA') {
|
||||
return;
|
||||
keybinds = {
|
||||
init: function() {
|
||||
$.bind(d, 'keydown', keybinds.cb.keydown);
|
||||
return $.bind(d, 'keypress', keybinds.cb.keypress);
|
||||
},
|
||||
cb: {
|
||||
keydown: function(e) {
|
||||
var kc, key, _ref;
|
||||
if ((_ref = d.activeElement.nodeName) === 'TEXTAREA' || _ref === 'INPUT') {
|
||||
keybinds.mode = keybinds.insert;
|
||||
} else {
|
||||
keybinds.mode = keybinds.normal;
|
||||
}
|
||||
kc = e.keyCode;
|
||||
if ((65 <= kc && kc <= 90)) {
|
||||
key = String.fromCharCode(kc);
|
||||
if (!e.shiftKey) {
|
||||
key = key.toLowerCase();
|
||||
}
|
||||
if (e.ctrlKey) {
|
||||
key = '^' + key;
|
||||
}
|
||||
} else {
|
||||
if (kc === 27) {
|
||||
key = '<Esc>';
|
||||
}
|
||||
}
|
||||
return keybinds.key = key;
|
||||
},
|
||||
keypress: function(e) {
|
||||
return keybinds.mode(e);
|
||||
}
|
||||
},
|
||||
insert: function(e) {
|
||||
var range, selEnd, selStart, ta, valEnd, valMid, valStart, value;
|
||||
switch (keybinds.key) {
|
||||
case '<Esc>':
|
||||
e.preventDefault();
|
||||
return $.remove($('#qr'));
|
||||
case '^s':
|
||||
ta = d.activeElement;
|
||||
if (ta.nodeName !== 'TEXTAREA') {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
value = ta.value;
|
||||
selStart = ta.selectionStart;
|
||||
selEnd = ta.selectionEnd;
|
||||
valStart = value.slice(0, selStart) + '[spoiler]';
|
||||
valMid = value.slice(selStart, selEnd);
|
||||
valEnd = '[/spoiler]' + value.slice(selEnd);
|
||||
ta.value = valStart + valMid + valEnd;
|
||||
range = valStart.length + valMid.length;
|
||||
return ta.setSelectionRange(range, range);
|
||||
}
|
||||
},
|
||||
normal: function(e) {
|
||||
var thread;
|
||||
switch (keybinds.key) {
|
||||
case 'I':
|
||||
break;
|
||||
case 'J':
|
||||
break;
|
||||
case 'K':
|
||||
break;
|
||||
case 'M':
|
||||
break;
|
||||
case 'i':
|
||||
break;
|
||||
case 'm':
|
||||
break;
|
||||
case 'n':
|
||||
return nav.down();
|
||||
case 'o':
|
||||
break;
|
||||
case 'p':
|
||||
return nav.up();
|
||||
case 'u':
|
||||
break;
|
||||
case 'w':
|
||||
thread = nav.getThread()[0];
|
||||
return watcher.toggle(thread);
|
||||
case 'x':
|
||||
}
|
||||
value = ta.value;
|
||||
selStart = ta.selectionStart;
|
||||
selEnd = ta.selectionEnd;
|
||||
valStart = value.slice(0, selStart) + '[spoiler]';
|
||||
valMid = value.slice(selStart, selEnd);
|
||||
valEnd = '[/spoiler]' + value.slice(selEnd);
|
||||
ta.value = valStart + valMid + valEnd;
|
||||
range = valStart.length + valMid.length;
|
||||
ta.setSelectionRange(range, range);
|
||||
return e.preventDefault();
|
||||
}
|
||||
};
|
||||
keyModeNormal = function(e) {
|
||||
@ -708,16 +756,6 @@
|
||||
char = g.char;
|
||||
hash = location.hash;
|
||||
switch (char) {
|
||||
case "0":
|
||||
return location.pathname = "/" + g.BOARD;
|
||||
case "G":
|
||||
if (e.shiftKey) {
|
||||
return window.scrollTo(0, 99999);
|
||||
} else {
|
||||
window.scrollTo(0, 0);
|
||||
return location.hash = '';
|
||||
}
|
||||
break;
|
||||
case "I":
|
||||
if (g.REPLY) {
|
||||
if (!(qrLink = $('td.replyhl span[id] a:not(:first-child)'))) {
|
||||
@ -1729,7 +1767,7 @@
|
||||
}
|
||||
favicon = $.el('img', {
|
||||
src: src,
|
||||
className: 'pointer'
|
||||
className: 'favicon'
|
||||
});
|
||||
$.bind(favicon, 'click', watcher.cb.toggle);
|
||||
_results.push($.before(input, favicon));
|
||||
@ -1750,7 +1788,7 @@
|
||||
},
|
||||
cb: {
|
||||
toggle: function(e) {
|
||||
return watcher.toggle(e.target);
|
||||
return watcher.toggle(e.target.parentNode);
|
||||
},
|
||||
x: function(e) {
|
||||
var board, id, _, _ref;
|
||||
@ -1758,8 +1796,9 @@
|
||||
return watcher.unwatch(board, id);
|
||||
}
|
||||
},
|
||||
toggle: function(favicon) {
|
||||
var id;
|
||||
toggle: function(thread) {
|
||||
var favicon, id;
|
||||
favicon = $('img.favicon', thread);
|
||||
id = favicon.nextSibling.name;
|
||||
if (favicon.src === g.favEmpty) {
|
||||
return watcher.watch(id, favicon);
|
||||
@ -1848,7 +1887,7 @@
|
||||
div.dialog > div.move {\
|
||||
cursor: move;\
|
||||
}\
|
||||
label, a, .pointer {\
|
||||
label, a, {\
|
||||
cursor: pointer;\
|
||||
}\
|
||||
\
|
||||
@ -1931,6 +1970,9 @@
|
||||
.new {\
|
||||
background: lime;\
|
||||
}\
|
||||
.favicon {\
|
||||
cursor: pointer;\
|
||||
}\
|
||||
');
|
||||
if (location.hostname === 'sys.4chan.org') {
|
||||
qr.sys();
|
||||
@ -2088,8 +2130,7 @@
|
||||
for (_i = 0, _len = arr.length; _i < _len; _i++) {
|
||||
el = arr[_i];
|
||||
a = $.el('a', {
|
||||
textContent: '[ ! ]',
|
||||
className: 'pointer'
|
||||
textContent: '[ ! ]'
|
||||
});
|
||||
$.bind(a, 'click', report);
|
||||
$.after(el, a);
|
||||
@ -2119,8 +2160,7 @@
|
||||
});
|
||||
}
|
||||
if ($.config('Keybinds')) {
|
||||
$.bind(d, 'keydown', keydown);
|
||||
$.bind(d, 'keypress', keypress);
|
||||
keybinds.init();
|
||||
}
|
||||
if ($.config('Thread Updater')) {
|
||||
updater.init();
|
||||
@ -2176,7 +2216,7 @@
|
||||
for (_k = 0, _len3 = omitted.length; _k < _len3; _k++) {
|
||||
span = omitted[_k];
|
||||
a = $.el('a', {
|
||||
className: 'pointer omittedposts',
|
||||
className: 'omittedposts',
|
||||
textContent: "+ " + span.textContent
|
||||
});
|
||||
$.bind(a, 'click', expandThread);
|
||||
|
||||
140
script.coffee
140
script.coffee
@ -1,4 +1,4 @@
|
||||
# TODO floating nav buttons FUCKING AWESOME
|
||||
# TODO
|
||||
# option to skip post form directly to contents on first page,
|
||||
# like what happens when using thread nav to go to next page
|
||||
# (floating) qr no-quote button?
|
||||
@ -6,6 +6,7 @@
|
||||
# XXX error on FUCKING CHROME
|
||||
{log} = console if console?
|
||||
|
||||
# TODO put keybinds back to false when done
|
||||
config =
|
||||
main:
|
||||
checkbox:
|
||||
@ -17,7 +18,7 @@ config =
|
||||
'Image Expansion': [true, 'Expand images']
|
||||
'Image Hover': [false, 'Show full image on mouseover']
|
||||
'Image Preloading': [false, 'Preload Images']
|
||||
'Keybinds': [false, 'Binds actions to keys']
|
||||
'Keybinds': [true, 'Binds actions to keys']
|
||||
'Localize Time': [true, 'Show times based on your timezone']
|
||||
'Persistent QR': [false, 'Quick reply won\'t disappear after posting. Only in replies.']
|
||||
'Post in Title': [true, 'Show the op\'s post in the tab title']
|
||||
@ -481,53 +482,98 @@ imageThumb = (thumb) ->
|
||||
thumb.className = ''
|
||||
$.remove thumb.nextSibling
|
||||
|
||||
keydown = (e) ->
|
||||
kc = e.keyCode
|
||||
g.keyCode = kc
|
||||
g.char = String.fromCharCode kc
|
||||
keybinds =
|
||||
init: ->
|
||||
$.bind d, 'keydown', keybinds.cb.keydown
|
||||
$.bind d, 'keypress', keybinds.cb.keypress
|
||||
|
||||
keypress = (e) ->
|
||||
if d.activeElement.nodeName in ['TEXTAREA', 'INPUT']
|
||||
keyModeInsert e
|
||||
else
|
||||
keyModeNormal e
|
||||
cb:
|
||||
keydown: (e) ->
|
||||
if d.activeElement.nodeName in ['TEXTAREA', 'INPUT']
|
||||
keybinds.mode = keybinds.insert
|
||||
else
|
||||
keybinds.mode = keybinds.normal
|
||||
|
||||
keyModeInsert = (e) ->
|
||||
kc = g.keyCode
|
||||
char = g.char
|
||||
if kc is 27 #escape
|
||||
$.remove $ '#qr'
|
||||
e.preventDefault()
|
||||
else if e.ctrlKey and char is "S"
|
||||
ta = d.activeElement
|
||||
return unless ta.nodeName is 'TEXTAREA'
|
||||
kc = e.keyCode
|
||||
if 65 <= kc <= 90 #A-Z
|
||||
key = String.fromCharCode kc
|
||||
if !e.shiftKey
|
||||
key = key.toLowerCase()
|
||||
if e.ctrlKey then key = '^' + key
|
||||
else
|
||||
if kc is 27
|
||||
key = '<Esc>'
|
||||
keybinds.key = key
|
||||
|
||||
value = ta.value
|
||||
selStart = ta.selectionStart
|
||||
selEnd = ta.selectionEnd
|
||||
keypress: (e) ->
|
||||
keybinds.mode e
|
||||
|
||||
valStart = value[0...selStart] + '[spoiler]'
|
||||
valMid = value[selStart...selEnd]
|
||||
valEnd = '[/spoiler]' + value[selEnd..]
|
||||
insert: (e) ->
|
||||
switch keybinds.key
|
||||
when '<Esc>'
|
||||
e.preventDefault()
|
||||
$.remove $ '#qr'
|
||||
when '^s'
|
||||
ta = d.activeElement
|
||||
return unless ta.nodeName is 'TEXTAREA'
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
value = ta.value
|
||||
selStart = ta.selectionStart
|
||||
selEnd = ta.selectionEnd
|
||||
|
||||
valStart = value[0...selStart] + '[spoiler]'
|
||||
valMid = value[selStart...selEnd]
|
||||
valEnd = '[/spoiler]' + value[selEnd..]
|
||||
|
||||
ta.value = valStart + valMid + valEnd
|
||||
range = valStart.length + valMid.length
|
||||
ta.setSelectionRange range, range
|
||||
|
||||
normal: (e) ->
|
||||
switch keybinds.key
|
||||
when 'I'
|
||||
#qr no text
|
||||
return
|
||||
when 'J'
|
||||
#highlight next
|
||||
return
|
||||
when 'K'
|
||||
#highlight prev
|
||||
return
|
||||
when 'M'
|
||||
#expand all
|
||||
return
|
||||
when 'i'
|
||||
#qr
|
||||
return
|
||||
when 'm'
|
||||
#expand img
|
||||
return
|
||||
when 'n'
|
||||
nav.down()
|
||||
when 'o'
|
||||
#open in new tab
|
||||
return
|
||||
when 'p'
|
||||
nav.up()
|
||||
when 'u'
|
||||
#update now
|
||||
return
|
||||
when 'w'
|
||||
[thread] = nav.getThread()
|
||||
watcher.toggle thread
|
||||
when 'x'
|
||||
#toggle hide thread
|
||||
return
|
||||
|
||||
ta.value = valStart + valMid + valEnd
|
||||
range = valStart.length + valMid.length
|
||||
ta.setSelectionRange range, range
|
||||
e.preventDefault()
|
||||
|
||||
keyModeNormal = (e) ->
|
||||
return if e.ctrlKey or e.altKey
|
||||
char = g.char
|
||||
hash = location.hash
|
||||
switch char
|
||||
when "0"
|
||||
location.pathname = "/#{g.BOARD}"
|
||||
when "G"
|
||||
if e.shiftKey
|
||||
window.scrollTo 0, 99999
|
||||
else
|
||||
window.scrollTo 0, 0
|
||||
location.hash = ''
|
||||
when "I"
|
||||
if g.REPLY
|
||||
unless qrLink = $ 'td.replyhl span[id] a:not(:first-child)'
|
||||
@ -1337,7 +1383,7 @@ watcher =
|
||||
src = g.favEmpty
|
||||
favicon = $.el 'img',
|
||||
src: src
|
||||
className: 'pointer'
|
||||
className: 'favicon'
|
||||
$.bind favicon, 'click', watcher.cb.toggle
|
||||
$.before input, favicon
|
||||
|
||||
@ -1354,13 +1400,14 @@ watcher =
|
||||
|
||||
cb:
|
||||
toggle: (e) ->
|
||||
watcher.toggle e.target
|
||||
watcher.toggle e.target.parentNode
|
||||
x: (e) ->
|
||||
[board, _, id] = e.target.nextElementSibling
|
||||
.getAttribute('href').substring(1).split('/')
|
||||
watcher.unwatch board, id
|
||||
|
||||
toggle: (favicon) ->
|
||||
toggle: (thread) ->
|
||||
favicon = $ 'img.favicon', thread
|
||||
id = favicon.nextSibling.name
|
||||
if favicon.src == g.favEmpty
|
||||
watcher.watch id, favicon
|
||||
@ -1453,7 +1500,7 @@ $.addStyle '
|
||||
div.dialog > div.move {
|
||||
cursor: move;
|
||||
}
|
||||
label, a, .pointer {
|
||||
label, a, {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@ -1536,6 +1583,9 @@ $.addStyle '
|
||||
.new {
|
||||
background: lime;
|
||||
}
|
||||
.favicon {
|
||||
cursor: pointer;
|
||||
}
|
||||
'
|
||||
|
||||
if location.hostname is 'sys.4chan.org'
|
||||
@ -1653,7 +1703,6 @@ if $.config 'Quick Report'
|
||||
for el in arr
|
||||
a = $.el 'a',
|
||||
textContent: '[ ! ]'
|
||||
className: 'pointer'
|
||||
$.bind a, 'click', report
|
||||
$.after el, a
|
||||
$.after el, $.tn(' ')
|
||||
@ -1674,8 +1723,7 @@ if $.config 'Anonymize'
|
||||
$.remove trip
|
||||
|
||||
if $.config 'Keybinds'
|
||||
$.bind d, 'keydown', keydown
|
||||
$.bind d, 'keypress', keypress
|
||||
keybinds.init()
|
||||
|
||||
if $.config 'Thread Updater'
|
||||
updater.init()
|
||||
@ -1716,7 +1764,7 @@ else #not reply
|
||||
omitted = $$('span.omittedposts')
|
||||
for span in omitted
|
||||
a = $.el 'a',
|
||||
className: 'pointer omittedposts'
|
||||
className: 'omittedposts'
|
||||
textContent: "+ #{span.textContent}"
|
||||
$.bind a, 'click', expandThread
|
||||
$.replace(span, a)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user