Some QR fixes.

Use notifications for QR errors and successes! Close #562.
Add an entry to open the QR in the Header's menu.
This commit is contained in:
Nicolas Stepien 2013-02-12 03:29:16 +01:00
parent 34a11f2e74
commit 566b468327
3 changed files with 86 additions and 63 deletions

View File

@ -778,8 +778,12 @@
el.removeEventListener(event, handler, false); el.removeEventListener(event, handler, false);
} }
}, },
event: function(event, detail) { event: function(event, detail, root) {
return d.dispatchEvent(new CustomEvent(event, { if (root == null) {
root = d;
}
return root.dispatchEvent(new CustomEvent(event, {
bubbles: true,
detail: detail detail: detail
})); }));
}, },
@ -1005,7 +1009,9 @@
}; };
Notification.prototype.close = function() { Notification.prototype.close = function() {
return $.rm(this.el); if (this.el.parentNode) {
return $.rm(this.el);
}
}; };
return Notification; return Notification;
@ -1818,12 +1824,22 @@
QR = { QR = {
init: function() { init: function() {
var link;
if (!Conf['Quick Reply']) { if (!Conf['Quick Reply']) {
return; return;
} }
if (Conf['Hide Original Post Form']) { if (Conf['Hide Original Post Form']) {
Main.css += "#postForm, .postingMode {\n display: none;\n}"; Main.css += "#postForm, .postingMode {\n display: none;\n}";
} }
link = $.el('a', {
textContent: 'Open the QR',
href: 'javascript:;'
});
$.on(link, 'click', QR.open);
$.event('AddMenuEntry', {
type: 'header',
el: link
});
Post.prototype.callbacks.push({ Post.prototype.callbacks.push({
name: 'Quick Reply', name: 'Quick Reply',
cb: this.node cb: this.node
@ -1885,23 +1901,27 @@
}, },
error: function(err) { error: function(err) {
var el; var el;
el = $('.warning', QR.el);
if (typeof err === 'string') {
el.textContent = err;
} else {
el.innerHTML = null;
$.add(el, err);
}
QR.open(); QR.open();
if (typeof err === 'string') {
el = $.tn(err);
} else {
el = err;
el.removeAttribute('style');
}
if (QR.captcha.isEnabled && /captcha|verification/i.test(el.textContent)) { if (QR.captcha.isEnabled && /captcha|verification/i.test(el.textContent)) {
$('[autocomplete]', QR.el).focus(); $('[autocomplete]', QR.el).focus();
} }
if (d.hidden) { if (d.hidden) {
return alert(el.textContent); alert(el.textContent);
} }
return QR.lastNotification = new Notification('warning', el);
}, },
cleanError: function() { cleanError: function() {
return $('.warning', QR.el).textContent = null; var _ref;
if ((_ref = QR.lastNotification) != null) {
_ref.close();
}
return delete QR.lastNotification;
}, },
status: function(data) { status: function(data) {
var disabled, input, value; var disabled, input, value;
@ -2064,7 +2084,7 @@
range = caretPos + text.length; range = caretPos + text.length;
ta.setSelectionRange(range, range); ta.setSelectionRange(range, range);
ta.focus(); ta.focus();
return $.event(ta, new Event('input')); return ta.dispatchEvent(new Event('input'));
}, },
characterCount: function() { characterCount: function() {
var count, counter; var count, counter;
@ -2439,7 +2459,6 @@
<div class=textarea><textarea name=com title=Comment placeholder=Comment class=field></textarea><span id=charCount></span></div>\ <div class=textarea><textarea name=com title=Comment placeholder=Comment class=field></textarea><span id=charCount></span></div>\
<div><input type=file title="Shift+Click to remove the selected file." multiple size=16><input type=submit></div>\ <div><input type=file title="Shift+Click to remove the selected file." multiple size=16><input type=submit></div>\
<label id=spoilerLabel><input type=checkbox id=spoiler> Spoiler Image</label>\ <label id=spoilerLabel><input type=checkbox id=spoiler> Spoiler Image</label>\
<div class=warning></div>\
</form>'); </form>');
if (Conf['Remember QR size'] && $.engine === 'gecko') { if (Conf['Remember QR size'] && $.engine === 'gecko') {
$.on(ta = $('textarea', QR.el), 'mouseup', function() { $.on(ta = $('textarea', QR.el), 'mouseup', function() {
@ -2510,7 +2529,6 @@
$.on(spoiler.firstChild, 'change', function() { $.on(spoiler.firstChild, 'change', function() {
return $('input', QR.selected.el).click(); return $('input', QR.selected.el).click();
}); });
$.on($('.warning', QR.el), 'click', QR.cleanError);
new QR.reply().select(); new QR.reply().select();
_ref1 = ['name', 'email', 'sub', 'com']; _ref1 = ['name', 'email', 'sub', 'com'];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
@ -2528,9 +2546,7 @@
QR.cooldown.init(); QR.cooldown.init();
QR.captcha.init(); QR.captcha.init();
$.add(d.body, QR.el); $.add(d.body, QR.el);
return $.event(QR.el, new CustomEvent('QRDialogCreation', { return $.event(new CustomEvent('QRDialogCreation', null, QR.el));
bubbles: true
}));
}, },
submit: function(e) { submit: function(e) {
var callbacks, captcha, captchas, challenge, err, filetag, m, opts, post, reply, response, textOnly, threadID, _ref; var callbacks, captcha, captchas, challenge, err, filetag, m, opts, post, reply, response, textOnly, threadID, _ref;
@ -2651,19 +2667,19 @@
return QR.ajax = $.ajax($.id('postForm').parentNode.action, callbacks, opts); return QR.ajax = $.ajax($.id('postForm').parentNode.action, callbacks, opts);
}, },
response: function(html) { response: function(html) {
var ban, board, err, persona, postID, reply, threadID, _, _ref, _ref1; var ban, board, err, h1, persona, postID, reply, threadID, tmpDoc, _, _ref, _ref1;
doc = d.implementation.createHTMLDocument(''); tmpDoc = d.implementation.createHTMLDocument('');
doc.documentElement.innerHTML = html; tmpDoc.documentElement.innerHTML = html;
if (ban = $('.banType', doc)) { if (ban = $('.banType', tmpDoc)) {
board = $('.board', doc).innerHTML; board = $('.board', tmpDoc).innerHTML;
err = $.el('span', { err = $.el('span', {
innerHTML: ban.textContent.toLowerCase() === 'banned' ? ("You are banned on " + board + "! ;_;<br>") + "Click <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', doc).innerHTML) + ".<br>") + ("Reason: " + ($('.reason', doc).innerHTML)) innerHTML: ban.textContent.toLowerCase() === 'banned' ? ("You are banned on " + board + "! ;_;<br>") + "Click <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', tmpDoc).innerHTML) + ".<br>") + ("Reason: " + ($('.reason', tmpDoc).innerHTML))
}); });
} else if (err = doc.getElementById('errmsg')) { } else if (err = tmpDoc.getElementById('errmsg')) {
if ((_ref = $('a', err)) != null) { if ((_ref = $('a', err)) != null) {
_ref.target = '_blank'; _ref.target = '_blank';
} }
} else if (doc.title !== 'Post successful!') { } else if (tmpDoc.title !== 'Post successful!') {
err = 'Connection error with sys.4chan.org.'; err = 'Connection error with sys.4chan.org.';
} }
if (err) { if (err) {
@ -2682,6 +2698,8 @@
QR.error(err); QR.error(err);
return; return;
} }
h1 = $('h1', tmpDoc);
QR.lastNotification = new Notification('success', h1.textContent, 5);
reply = QR.replies[0]; reply = QR.replies[0];
persona = $.get('QR.persona', {}); persona = $.get('QR.persona', {});
persona = { persona = {
@ -2690,14 +2708,11 @@
sub: Conf['Remember Subject'] ? reply.sub : null sub: Conf['Remember Subject'] ? reply.sub : null
}; };
$.set('QR.persona', persona); $.set('QR.persona', persona);
_ref1 = doc.body.lastChild.textContent.match(/thread:(\d+),no:(\d+)/), _ = _ref1[0], threadID = _ref1[1], postID = _ref1[2]; _ref1 = h1.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = _ref1[0], threadID = _ref1[1], postID = _ref1[2];
$.event(QR.el, new CustomEvent('QRPostSuccessful', { $.event(new CustomEvent('QRPostSuccessful', {
bubbles: true, threadID: threadID,
detail: { postID: postID
threadID: threadID, }, QR.el));
postID: postID
}
}));
QR.cooldown.set({ QR.cooldown.set({
post: reply, post: reply,
isReply: threadID !== '0' isReply: threadID !== '0'

View File

@ -130,8 +130,8 @@ $.extend $,
for event in events.split ' ' for event in events.split ' '
el.removeEventListener event, handler, false el.removeEventListener event, handler, false
return return
event: (event, detail) -> event: (event, detail, root=d) ->
d.dispatchEvent new CustomEvent event, {detail} root.dispatchEvent new CustomEvent event, {bubbles: true, detail}
open: (url) -> open: (url) ->
(GM_openInTab or window.open) url, '_blank' (GM_openInTab or window.open) url, '_blank'
hidden: -> hidden: ->

View File

@ -95,7 +95,7 @@ class Notification
@type = type @type = type
close: -> close: ->
$.rm @el $.rm @el if @el.parentNode
Settings = Settings =
init: -> init: ->
@ -771,6 +771,14 @@ QR =
} }
""" """
link = $.el 'a',
textContent: 'Open the QR'
href: 'javascript:;'
$.on link, 'click', QR.open
$.event 'AddMenuEntry',
type: 'header'
el: link
Post::callbacks.push Post::callbacks.push
name: 'Quick Reply' name: 'Quick Reply'
cb: @node cb: @node
@ -818,19 +826,20 @@ QR =
@checked and QR.hide() or QR.unhide() @checked and QR.hide() or QR.unhide()
error: (err) -> error: (err) ->
el = $ '.warning', QR.el
if typeof err is 'string'
el.textContent = err
else
el.innerHTML = null
$.add el, err
QR.open() QR.open()
if typeof err is 'string'
el = $.tn err
else
el = err
el.removeAttribute 'style'
if QR.captcha.isEnabled and /captcha|verification/i.test el.textContent if QR.captcha.isEnabled and /captcha|verification/i.test el.textContent
# Focus the captcha input on captcha error. # Focus the captcha input on captcha error.
$('[autocomplete]', QR.el).focus() $('[autocomplete]', QR.el).focus()
alert el.textContent if d.hidden alert el.textContent if d.hidden
QR.lastNotification = new Notification 'warning', el
cleanError: -> cleanError: ->
$('.warning', QR.el).textContent = null QR.lastNotification?.close()
delete QR.lastNotification
status: (data={}) -> status: (data={}) ->
return unless QR.el return unless QR.el
@ -978,7 +987,7 @@ QR =
ta.focus() ta.focus()
# Fire the 'input' event # Fire the 'input' event
$.event ta, new Event 'input' ta.dispatchEvent new Event 'input'
characterCount: -> characterCount: ->
counter = QR.charaCounter counter = QR.charaCounter
@ -1262,7 +1271,6 @@ QR =
<div class=textarea><textarea name=com title=Comment placeholder=Comment class=field></textarea><span id=charCount></span></div> <div class=textarea><textarea name=com title=Comment placeholder=Comment class=field></textarea><span id=charCount></span></div>
<div><input type=file title="Shift+Click to remove the selected file." multiple size=16><input type=submit></div> <div><input type=file title="Shift+Click to remove the selected file." multiple size=16><input type=submit></div>
<label id=spoilerLabel><input type=checkbox id=spoiler> Spoiler Image</label> <label id=spoilerLabel><input type=checkbox id=spoiler> Spoiler Image</label>
<div class=warning></div>
</form>' </form>'
if Conf['Remember QR size'] and $.engine is 'gecko' if Conf['Remember QR size'] and $.engine is 'gecko'
@ -1320,7 +1328,6 @@ QR =
$.on fileInput, 'change', QR.fileInput $.on fileInput, 'change', QR.fileInput
$.on fileInput, 'click', (e) -> if e.shiftKey then QR.selected.rmFile() or e.preventDefault() $.on fileInput, 'click', (e) -> if e.shiftKey then QR.selected.rmFile() or e.preventDefault()
$.on spoiler.firstChild, 'change', -> $('input', QR.selected.el).click() $.on spoiler.firstChild, 'change', -> $('input', QR.selected.el).click()
$.on $('.warning', QR.el), 'click', QR.cleanError
new QR.reply().select() new QR.reply().select()
# save selected reply's data # save selected reply's data
@ -1341,8 +1348,7 @@ QR =
# Create a custom event when the QR dialog is first initialized. # Create a custom event when the QR dialog is first initialized.
# Use it to extend the QR's functionalities, or for XTRM RICE. # Use it to extend the QR's functionalities, or for XTRM RICE.
$.event QR.el, new CustomEvent 'QRDialogCreation', $.event new CustomEvent 'QRDialogCreation', null, QR.el
bubbles: true
submit: (e) -> submit: (e) ->
e?.preventDefault() e?.preventDefault()
@ -1453,20 +1459,20 @@ QR =
QR.ajax = $.ajax $.id('postForm').parentNode.action, callbacks, opts QR.ajax = $.ajax $.id('postForm').parentNode.action, callbacks, opts
response: (html) -> response: (html) ->
doc = d.implementation.createHTMLDocument '' tmpDoc = d.implementation.createHTMLDocument ''
doc.documentElement.innerHTML = html tmpDoc.documentElement.innerHTML = html
if ban = $ '.banType', doc # banned/warning if ban = $ '.banType', tmpDoc # banned/warning
board = $('.board', doc).innerHTML board = $('.board', tmpDoc).innerHTML
err = $.el 'span', innerHTML: err = $.el 'span', innerHTML:
if ban.textContent.toLowerCase() is 'banned' if ban.textContent.toLowerCase() is 'banned'
"You are banned on #{board}! ;_;<br>" + "You are banned on #{board}! ;_;<br>" +
"Click <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason." "Click <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason."
else else
"You were issued a warning on #{board} as #{$('.nameBlock', doc).innerHTML}.<br>" + "You were issued a warning on #{board} as #{$('.nameBlock', tmpDoc).innerHTML}.<br>" +
"Reason: #{$('.reason', doc).innerHTML}" "Reason: #{$('.reason', tmpDoc).innerHTML}"
else if err = doc.getElementById 'errmsg' # error! else if err = tmpDoc.getElementById 'errmsg' # error!
$('a', err)?.target = '_blank' # duplicate image link $('a', err)?.target = '_blank' # duplicate image link
else if doc.title isnt 'Post successful!' else if tmpDoc.title isnt 'Post successful!'
err = 'Connection error with sys.4chan.org.' err = 'Connection error with sys.4chan.org.'
if err if err
@ -1493,6 +1499,9 @@ QR =
QR.error err QR.error err
return return
h1 = $ 'h1', tmpDoc
QR.lastNotification = new Notification 'success', h1.textContent, 5
reply = QR.replies[0] reply = QR.replies[0]
persona = $.get 'QR.persona', {} persona = $.get 'QR.persona', {}
@ -1502,14 +1511,13 @@ QR =
sub: if Conf['Remember Subject'] then reply.sub else null sub: if Conf['Remember Subject'] then reply.sub else null
$.set 'QR.persona', persona $.set 'QR.persona', persona
[_, threadID, postID] = doc.body.lastChild.textContent.match /thread:(\d+),no:(\d+)/ [_, threadID, postID] = h1.nextSibling.textContent.match /thread:(\d+),no:(\d+)/
# Post/upload confirmed as successful. # Post/upload confirmed as successful.
$.event QR.el, new CustomEvent 'QRPostSuccessful', $.event new CustomEvent 'QRPostSuccessful', {
bubbles: true threadID
detail: postID
threadID: threadID }, QR.el
postID: postID
QR.cooldown.set QR.cooldown.set
post: reply post: reply