Merge branch 'v3' of git://github.com/MayhemYDG/4chan-x into v3
Conflicts: css/style.css src/config.coffee src/qr.coffee
This commit is contained in:
commit
478a75d03e
@ -1,6 +1,6 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 4chan X
|
// @name 4chan X
|
||||||
// @version 3.0.4
|
// @version 3.0.6
|
||||||
// @namespace 4chan-X
|
// @namespace 4chan-X
|
||||||
// @description Cross-browser extension for productive lurking on 4chan.
|
// @description Cross-browser extension for productive lurking on 4chan.
|
||||||
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
|
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
|
||||||
|
|||||||
209
4chan-X.user.js
209
4chan-X.user.js
File diff suppressed because one or more lines are too long
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,3 +1,15 @@
|
|||||||
|
### 3.0.6 - *2013-04-14*
|
||||||
|
|
||||||
|
- Fix regression concerning thread selection when quoting on the index.
|
||||||
|
|
||||||
|
### 3.0.5 - *2013-04-14*
|
||||||
|
|
||||||
|
- `Scroll to Last Read Post` is now optional, enabled by default.
|
||||||
|
- The QR won't auto-hide when auto-hide is enabled and one of its input is focused. Doesn't work on Firefox.
|
||||||
|
- Added the `Remember QR Size` setting back in, disabled by default. Only on Firefox.
|
||||||
|
- Fix QR remembering the file spoiler state when it shouldn't.
|
||||||
|
- Fix QR cooldown in Opera.
|
||||||
|
|
||||||
### 3.0.4 - *2013-04-11*
|
### 3.0.4 - *2013-04-11*
|
||||||
|
|
||||||
- More minor fixes.
|
- More minor fixes.
|
||||||
@ -9,7 +21,7 @@
|
|||||||
### 3.0.2 - *2013-04-09*
|
### 3.0.2 - *2013-04-09*
|
||||||
|
|
||||||
- Added a setting in the Header's menu to move it at the bottom of the screen.
|
- Added a setting in the Header's menu to move it at the bottom of the screen.
|
||||||
- Added Cooldown setting back in.
|
- Added the `Cooldown` setting back in.
|
||||||
- Fixed the Header going above posts when following quotelinks for example.
|
- Fixed the Header going above posts when following quotelinks for example.
|
||||||
- Fixed a bug where dead quotelinks would disappear.
|
- Fixed a bug where dead quotelinks would disappear.
|
||||||
|
|
||||||
|
|||||||
@ -542,6 +542,15 @@ a[href="javascript:;"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* QR */
|
/* QR */
|
||||||
|
:root.hide-original-post-form #postForm,
|
||||||
|
:root.hide-original-post-form .postingMode,
|
||||||
|
:root.hide-original-post-form #togglePostForm,
|
||||||
|
#qr.autohide:not(.has-focus):not(:hover) > form {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#qr select, #dump-button, .remove, .captcha-img {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
#qr {
|
#qr {
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -553,9 +562,6 @@ a[href="javascript:;"] {
|
|||||||
#qrtab {
|
#qrtab {
|
||||||
border-radius: 3px 3px 0 0;
|
border-radius: 3px 3px 0 0;
|
||||||
}
|
}
|
||||||
.autohide:not(:hover):not(.focus) > form {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
#qrtab {
|
#qrtab {
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -138,8 +138,11 @@ $.extend $,
|
|||||||
el.classList.toggle className
|
el.classList.toggle className
|
||||||
hasClass: (el, className) ->
|
hasClass: (el, className) ->
|
||||||
el.classList.contains className
|
el.classList.contains className
|
||||||
rm: (el) ->
|
rm: do ->
|
||||||
el.parentNode.removeChild el
|
if 'remove' of Element.prototype
|
||||||
|
(el) -> el.remove()
|
||||||
|
else
|
||||||
|
(el) -> el.parentNode?.removeChild el
|
||||||
tn: (s) ->
|
tn: (s) ->
|
||||||
d.createTextNode s
|
d.createTextNode s
|
||||||
frag: ->
|
frag: ->
|
||||||
|
|||||||
@ -4,7 +4,8 @@ UI = do ->
|
|||||||
className: 'dialog'
|
className: 'dialog'
|
||||||
innerHTML: html
|
innerHTML: html
|
||||||
id: id
|
id: id
|
||||||
el.style.cssText = localStorage.getItem("#{g.NAMESPACE}#{id}.position") or position
|
$.get "#{id}.position", position, (item) ->
|
||||||
|
el.style.cssText = item["#{id}.position"]
|
||||||
move = $ '.move', el
|
move = $ '.move', el
|
||||||
$.on move, 'touchstart mousedown', dragstart
|
$.on move, 'touchstart mousedown', dragstart
|
||||||
for child in move.children
|
for child in move.children
|
||||||
@ -276,7 +277,7 @@ UI = do ->
|
|||||||
else # mouseup
|
else # mouseup
|
||||||
$.off d, 'mousemove', @move
|
$.off d, 'mousemove', @move
|
||||||
$.off d, 'mouseup', @up
|
$.off d, 'mouseup', @up
|
||||||
localStorage.setItem "#{g.NAMESPACE}#{@id}.position", @style.cssText
|
$.set "#{@id}.position", @style.cssText
|
||||||
|
|
||||||
hoverstart = ({root, el, latestEvent, endEvents, asapTest, cb}) ->
|
hoverstart = ({root, el, latestEvent, endEvents, asapTest, cb}) ->
|
||||||
o = {
|
o = {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "4chan-X",
|
"name": "4chan-X",
|
||||||
"version": "3.0.4",
|
"version": "3.0.6",
|
||||||
"description": "Cross-browser extension for productive lurking on 4chan.",
|
"description": "Cross-browser extension for productive lurking on 4chan.",
|
||||||
"meta": {
|
"meta": {
|
||||||
"name": "4chan X",
|
"name": "4chan X",
|
||||||
|
|||||||
@ -221,6 +221,12 @@ Config =
|
|||||||
false
|
false
|
||||||
'Remember the subject field, instead of resetting after posting.'
|
'Remember the subject field, instead of resetting after posting.'
|
||||||
]
|
]
|
||||||
|
<% if (type === 'userscript') { %>
|
||||||
|
'Remember QR Size': [
|
||||||
|
false
|
||||||
|
'Remember the size of the Quick reply.'
|
||||||
|
]
|
||||||
|
<% } %>
|
||||||
'Remember Spoiler': [
|
'Remember Spoiler': [
|
||||||
false
|
false
|
||||||
'Remember the spoiler state, instead of resetting after posting.'
|
'Remember the spoiler state, instead of resetting after posting.'
|
||||||
|
|||||||
@ -95,6 +95,7 @@ Header =
|
|||||||
|
|
||||||
hashScroll: ->
|
hashScroll: ->
|
||||||
return unless post = $.id @location.hash[1..]
|
return unless post = $.id @location.hash[1..]
|
||||||
|
return if (Get.postFromRoot post).isHidden
|
||||||
Header.scrollToPost post
|
Header.scrollToPost post
|
||||||
|
|
||||||
scrollToPost: (post) ->
|
scrollToPost: (post) ->
|
||||||
@ -145,7 +146,7 @@ class Notification
|
|||||||
setTimeout @close, @timeout * $.SECOND if @timeout
|
setTimeout @close, @timeout * $.SECOND if @timeout
|
||||||
|
|
||||||
close = ->
|
close = ->
|
||||||
$.rm @el if @el.parentNode
|
$.rm @el
|
||||||
|
|
||||||
CatalogLinks =
|
CatalogLinks =
|
||||||
init: ->
|
init: ->
|
||||||
@ -1536,7 +1537,7 @@ ReportLink =
|
|||||||
|
|
||||||
DeleteLink =
|
DeleteLink =
|
||||||
init: ->
|
init: ->
|
||||||
return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Delete Link'] or !Conf['Quick Reply']
|
return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Delete Link']
|
||||||
|
|
||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
className: 'delete-link'
|
className: 'delete-link'
|
||||||
@ -1588,20 +1589,22 @@ DeleteLink =
|
|||||||
else
|
else
|
||||||
$.id('delPassword').value
|
$.id('delPassword').value
|
||||||
|
|
||||||
|
fileOnly = $.hasClass @, 'delete-file'
|
||||||
|
|
||||||
form =
|
form =
|
||||||
mode: 'usrdel'
|
mode: 'usrdel'
|
||||||
onlyimgdel: $.hasClass @, 'delete-file'
|
onlyimgdel: fileOnly
|
||||||
pwd: pwd
|
pwd: pwd
|
||||||
form[post.ID] = 'delete'
|
form[post.ID] = 'delete'
|
||||||
|
|
||||||
link = @
|
link = @
|
||||||
$.ajax $.id('delform').action.replace("/#{g.BOARD}/", "/#{post.board}/"),
|
$.ajax $.id('delform').action.replace("/#{g.BOARD}/", "/#{post.board}/"),
|
||||||
onload: -> DeleteLink.load link, post, @response
|
onload: -> DeleteLink.load link, post, fileOnly, @response
|
||||||
onerror: -> DeleteLink.error link
|
onerror: -> DeleteLink.error link
|
||||||
,
|
,
|
||||||
cred: true
|
cred: true
|
||||||
form: $.formData form
|
form: $.formData form
|
||||||
load: (link, post, html) ->
|
load: (link, post, fileOnly, html) ->
|
||||||
tmpDoc = d.implementation.createHTMLDocument ''
|
tmpDoc = d.implementation.createHTMLDocument ''
|
||||||
tmpDoc.documentElement.innerHTML = html
|
tmpDoc.documentElement.innerHTML = html
|
||||||
if tmpDoc.title is '4chan - Banned' # Ban/warn check
|
if tmpDoc.title is '4chan - Banned' # Ban/warn check
|
||||||
@ -1612,7 +1615,7 @@ DeleteLink =
|
|||||||
else
|
else
|
||||||
if tmpDoc.title is 'Updating index...'
|
if tmpDoc.title is 'Updating index...'
|
||||||
# We're 100% sure.
|
# We're 100% sure.
|
||||||
(post.origin or post).kill()
|
(post.origin or post).kill fileOnly
|
||||||
s = 'Deleted'
|
s = 'Deleted'
|
||||||
link.textContent = s
|
link.textContent = s
|
||||||
error: (link) ->
|
error: (link) ->
|
||||||
@ -1924,7 +1927,13 @@ Keybinds =
|
|||||||
|
|
||||||
Nav =
|
Nav =
|
||||||
init: ->
|
init: ->
|
||||||
return if g.VIEW is 'index' and !Conf['Index Navigation'] or g.VIEW is 'thread' and !Conf['Reply Navigation']
|
switch g.VIEW
|
||||||
|
when 'index'
|
||||||
|
return unless Conf['Index Navigation']
|
||||||
|
when 'thread'
|
||||||
|
return unless Conf['Reply Navigation']
|
||||||
|
else # catalog
|
||||||
|
return
|
||||||
|
|
||||||
span = $.el 'span',
|
span = $.el 'span',
|
||||||
id: 'navlinks'
|
id: 'navlinks'
|
||||||
@ -3693,18 +3702,22 @@ Unread =
|
|||||||
threadID: @ID
|
threadID: @ID
|
||||||
defaultValue: 0
|
defaultValue: 0
|
||||||
Unread.addPosts posts
|
Unread.addPosts posts
|
||||||
if (hash = location.hash.match /\d+/) and post = @posts[hash[0]]
|
|
||||||
Header.scrollToPost post.nodes.root
|
|
||||||
else if Unread.posts.length
|
|
||||||
# Scroll to before the first unread post.
|
|
||||||
$.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root).scrollIntoView false
|
|
||||||
else if posts.length
|
|
||||||
# Scroll to the last read post.
|
|
||||||
Header.scrollToPost posts[posts.length - 1].nodes.root
|
|
||||||
$.on d, 'ThreadUpdate', Unread.onUpdate
|
$.on d, 'ThreadUpdate', Unread.onUpdate
|
||||||
$.on d, 'scroll visibilitychange', Unread.read
|
$.on d, 'scroll visibilitychange', Unread.read
|
||||||
$.on d, 'visibilitychange', Unread.setLine if Conf['Unread Line']
|
$.on d, 'visibilitychange', Unread.setLine if Conf['Unread Line']
|
||||||
|
|
||||||
|
return unless Conf['Scroll to Last Read Post']
|
||||||
|
# Let the header's onload callback handle it.
|
||||||
|
return if (hash = location.hash.match /\d+/) and hash[0] of @posts
|
||||||
|
if Unread.posts.length
|
||||||
|
# Scroll to before the first unread post.
|
||||||
|
while root = $.x 'preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root
|
||||||
|
break unless (Get.postFromRoot root).isHidden
|
||||||
|
root.scrollIntoView false
|
||||||
|
else if posts.length
|
||||||
|
# Scroll to the last read post.
|
||||||
|
Header.scrollToPost posts[posts.length - 1].nodes.root
|
||||||
|
|
||||||
sync: ->
|
sync: ->
|
||||||
lastReadPost = Unread.db.get
|
lastReadPost = Unread.db.get
|
||||||
boardID: Unread.thread.board.ID
|
boardID: Unread.thread.board.ID
|
||||||
@ -3790,7 +3803,7 @@ Unread =
|
|||||||
{root} = post.nodes
|
{root} = post.nodes
|
||||||
if root isnt $ '.thread > .replyContainer', root.parentNode # not the first reply
|
if root isnt $ '.thread > .replyContainer', root.parentNode # not the first reply
|
||||||
$.before root, Unread.hr
|
$.before root, Unread.hr
|
||||||
else if Unread.hr.parentNode
|
else
|
||||||
$.rm Unread.hr
|
$.rm Unread.hr
|
||||||
|
|
||||||
update: <% if (type === 'crx') { %>(dontrepeat) <% } %>->
|
update: <% if (type === 'crx') { %>(dontrepeat) <% } %>->
|
||||||
|
|||||||
@ -402,7 +402,7 @@ Main =
|
|||||||
|
|
||||||
# c.timeEnd 'All initializations'
|
# c.timeEnd 'All initializations'
|
||||||
|
|
||||||
$.on d, 'AddCallback', Main.addCallback
|
$.on d, 'AddCallback', Main.addCallback
|
||||||
$.ready Main.initReady
|
$.ready Main.initReady
|
||||||
|
|
||||||
initStyle: ->
|
initStyle: ->
|
||||||
|
|||||||
106
src/qr.coffee
106
src/qr.coffee
@ -11,9 +11,9 @@ QR =
|
|||||||
href: 'javascript:;'
|
href: 'javascript:;'
|
||||||
$.on sc, 'click', ->
|
$.on sc, 'click', ->
|
||||||
if !QR.nodes or QR.nodes.el.hidden
|
if !QR.nodes or QR.nodes.el.hidden
|
||||||
|
$.event 'CloseMenu'
|
||||||
QR.open()
|
QR.open()
|
||||||
QR.nodes.com.focus()
|
QR.nodes.com.focus()
|
||||||
QR.resetThreadSelector()
|
|
||||||
else
|
else
|
||||||
QR.close()
|
QR.close()
|
||||||
$.toggleClass @, 'disabled'
|
$.toggleClass @, 'disabled'
|
||||||
@ -21,8 +21,7 @@ QR =
|
|||||||
Header.addShortcut sc
|
Header.addShortcut sc
|
||||||
|
|
||||||
if Conf['Hide Original Post Form']
|
if Conf['Hide Original Post Form']
|
||||||
$.asap (-> doc), ->
|
$.asap (-> doc), -> $.addClass doc, 'hide-original-post-form'
|
||||||
$.addClass doc, 'hide-original-post-form'
|
|
||||||
|
|
||||||
$.on d, '4chanXInitFinished', @initReady
|
$.on d, '4chanXInitFinished', @initReady
|
||||||
|
|
||||||
@ -79,6 +78,10 @@ QR =
|
|||||||
QR.status()
|
QR.status()
|
||||||
if !Conf['Remember Spoiler'] and QR.nodes.spoiler.checked
|
if !Conf['Remember Spoiler'] and QR.nodes.spoiler.checked
|
||||||
QR.nodes.spoiler.click()
|
QR.nodes.spoiler.click()
|
||||||
|
focusin: ->
|
||||||
|
$.addClass QR.nodes.el, 'has-focus'
|
||||||
|
focusout: ->
|
||||||
|
$.rmClass QR.nodes.el, 'has-focus'
|
||||||
hide: ->
|
hide: ->
|
||||||
d.activeElement.blur()
|
d.activeElement.blur()
|
||||||
$.addClass QR.nodes.el, 'autohide'
|
$.addClass QR.nodes.el, 'autohide'
|
||||||
@ -207,7 +210,7 @@ QR =
|
|||||||
|
|
||||||
now = Date.now()
|
now = Date.now()
|
||||||
post = QR.posts[0]
|
post = QR.posts[0]
|
||||||
isReply = QR.nodes.thread.value isnt 'new'
|
isReply = post.thread isnt 'new'
|
||||||
isSage = /sage/i.test post.email
|
isSage = /sage/i.test post.email
|
||||||
hasFile = !!post.file
|
hasFile = !!post.file
|
||||||
seconds = null
|
seconds = null
|
||||||
@ -266,19 +269,19 @@ QR =
|
|||||||
text += ">#{s}\n"
|
text += ">#{s}\n"
|
||||||
|
|
||||||
QR.open()
|
QR.open()
|
||||||
ta = QR.nodes.com
|
{com, thread} = QR.nodes
|
||||||
QR.nodes.thread.value = OP.ID unless ta.value
|
thread.value = OP.ID unless com.value
|
||||||
|
|
||||||
caretPos = ta.selectionStart
|
caretPos = com.selectionStart
|
||||||
# Replace selection for text.
|
# Replace selection for text.
|
||||||
ta.value = ta.value[...caretPos] + text + ta.value[ta.selectionEnd..]
|
com.value = com.value[...caretPos] + text + com.value[com.selectionEnd..]
|
||||||
# Move the caret to the end of the new quote.
|
# Move the caret to the end of the new quote.
|
||||||
range = caretPos + text.length
|
range = caretPos + text.length
|
||||||
ta.setSelectionRange range, range
|
com.setSelectionRange range, range
|
||||||
ta.focus()
|
com.focus()
|
||||||
|
|
||||||
# Fire the 'input' event
|
QR.selected.save com
|
||||||
$.event 'input', null, ta
|
QR.selected.save thread
|
||||||
|
|
||||||
characterCount: ->
|
characterCount: ->
|
||||||
counter = QR.nodes.charCount
|
counter = QR.nodes.charCount
|
||||||
@ -351,11 +354,6 @@ QR =
|
|||||||
post = new QR.post()
|
post = new QR.post()
|
||||||
post.setFile file
|
post.setFile file
|
||||||
$.addClass QR.nodes.el, 'dump'
|
$.addClass QR.nodes.el, 'dump'
|
||||||
resetThreadSelector: ->
|
|
||||||
if g.VIEW is 'thread'
|
|
||||||
QR.nodes.thread.value = g.THREADID
|
|
||||||
else
|
|
||||||
QR.nodes.thread.value = 'new'
|
|
||||||
|
|
||||||
posts: []
|
posts: []
|
||||||
post: class
|
post: class
|
||||||
@ -373,8 +371,12 @@ QR =
|
|||||||
spoiler: $ 'input', el
|
spoiler: $ 'input', el
|
||||||
span: el.lastChild
|
span: el.lastChild
|
||||||
|
|
||||||
@nodes.spoiler.checked = @spoiler
|
<% if (type === 'userscript') { %>
|
||||||
|
# XXX Firefox lacks focusin/focusout support.
|
||||||
|
for elm in $$ '*', el
|
||||||
|
$.on elm, 'blur', QR.focusout
|
||||||
|
$.on elm, 'focus', QR.focusin
|
||||||
|
<% } %>
|
||||||
$.on el, 'click', @select.bind @
|
$.on el, 'click', @select.bind @
|
||||||
$.on @nodes.rm, 'click', (e) => e.stopPropagation(); @rm()
|
$.on @nodes.rm, 'click', (e) => e.stopPropagation(); @rm()
|
||||||
$.on @nodes.label, 'click', (e) => e.stopPropagation()
|
$.on @nodes.label, 'click', (e) => e.stopPropagation()
|
||||||
@ -386,9 +388,14 @@ QR =
|
|||||||
for event in ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop']
|
for event in ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop']
|
||||||
$.on el, event.toLowerCase(), @[event]
|
$.on el, event.toLowerCase(), @[event]
|
||||||
|
|
||||||
|
@thread = if g.VIEW is 'thread'
|
||||||
|
g.THREADID
|
||||||
|
else
|
||||||
|
'new'
|
||||||
|
|
||||||
prev = QR.posts[QR.posts.length - 1]
|
prev = QR.posts[QR.posts.length - 1]
|
||||||
QR.posts.push @
|
QR.posts.push @
|
||||||
@spoiler = if prev and Conf['Remember Spoiler']
|
@nodes.spoiler.checked = @spoiler = if prev and Conf['Remember Spoiler']
|
||||||
prev.spoiler
|
prev.spoiler
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
@ -420,7 +427,7 @@ QR =
|
|||||||
lock: (lock=true) ->
|
lock: (lock=true) ->
|
||||||
@isLocked = lock
|
@isLocked = lock
|
||||||
return unless @ is QR.selected
|
return unless @ is QR.selected
|
||||||
for name in ['name', 'email', 'sub', 'com', 'spoiler']
|
for name in ['thread', 'name', 'email', 'sub', 'com', 'spoiler']
|
||||||
QR.nodes[name].disabled = lock
|
QR.nodes[name].disabled = lock
|
||||||
@nodes.rm.style.visibility =
|
@nodes.rm.style.visibility =
|
||||||
QR.nodes.fileRM.style.visibility = if lock then 'hidden' else ''
|
QR.nodes.fileRM.style.visibility = if lock then 'hidden' else ''
|
||||||
@ -443,11 +450,14 @@ QR =
|
|||||||
@load()
|
@load()
|
||||||
load: ->
|
load: ->
|
||||||
# Load this post's values.
|
# Load this post's values.
|
||||||
for name in ['name', 'email', 'sub', 'com']
|
for name in ['thread', 'name', 'email', 'sub', 'com']
|
||||||
QR.nodes[name].value = @[name] or null
|
QR.nodes[name].value = @[name] or null
|
||||||
@showFileData()
|
@showFileData()
|
||||||
QR.characterCount()
|
QR.characterCount()
|
||||||
save: (input) ->
|
save: (input) ->
|
||||||
|
if input.type is 'checkbox'
|
||||||
|
@spoiler = input.checked
|
||||||
|
return
|
||||||
{value} = input
|
{value} = input
|
||||||
@[input.dataset.name] = value
|
@[input.dataset.name] = value
|
||||||
return if input.nodeName isnt 'TEXTAREA'
|
return if input.nodeName isnt 'TEXTAREA'
|
||||||
@ -461,7 +471,7 @@ QR =
|
|||||||
return unless @ is QR.selected
|
return unless @ is QR.selected
|
||||||
# Do this in case people use extensions
|
# Do this in case people use extensions
|
||||||
# that do not trigger the `input` event.
|
# that do not trigger the `input` event.
|
||||||
for name in ['name', 'email', 'sub', 'com']
|
for name in ['thread', 'name', 'email', 'sub', 'com', 'spoiler']
|
||||||
@save QR.nodes[name]
|
@save QR.nodes[name]
|
||||||
return
|
return
|
||||||
setFile: (@file) ->
|
setFile: (@file) ->
|
||||||
@ -542,7 +552,7 @@ QR =
|
|||||||
@showFileData()
|
@showFileData()
|
||||||
return unless window.URL
|
return unless window.URL
|
||||||
URL.revokeObjectURL @URL
|
URL.revokeObjectURL @URL
|
||||||
showFileData: (hide) ->
|
showFileData: ->
|
||||||
if @file
|
if @file
|
||||||
QR.nodes.filename.textContent = @filename
|
QR.nodes.filename.textContent = @filename
|
||||||
QR.nodes.filename.title = @filename
|
QR.nodes.filename.title = @filename
|
||||||
@ -628,6 +638,12 @@ QR =
|
|||||||
# start with an uncached captcha
|
# start with an uncached captcha
|
||||||
@reload()
|
@reload()
|
||||||
|
|
||||||
|
<% if (type === 'userscript') { %>
|
||||||
|
# XXX Firefox lacks focusin/focusout support.
|
||||||
|
$.on input, 'blur', QR.focusout
|
||||||
|
$.on input, 'focus', QR.focusin
|
||||||
|
<% } %>
|
||||||
|
|
||||||
$.addClass QR.nodes.el, 'has-captcha'
|
$.addClass QR.nodes.el, 'has-captcha'
|
||||||
$.after QR.nodes.com.parentNode, [imgContainer, input]
|
$.after QR.nodes.com.parentNode, [imgContainer, input]
|
||||||
sync: (@captchas) ->
|
sync: (@captchas) ->
|
||||||
@ -702,7 +718,7 @@ QR =
|
|||||||
<div class=move>
|
<div class=move>
|
||||||
<input type=checkbox id=autohide title=Auto-hide>
|
<input type=checkbox id=autohide title=Auto-hide>
|
||||||
<a href=javascript:; class=close title=Close>×</a>
|
<a href=javascript:; class=close title=Close>×</a>
|
||||||
<select title='Create a new thread / Reply'>
|
<select data-name=thread title='Create a new thread / Reply'>
|
||||||
<option value=new>New thread</option>
|
<option value=new>New thread</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -797,10 +813,17 @@ QR =
|
|||||||
$.add nodes.thread, $.el 'option',
|
$.add nodes.thread, $.el 'option',
|
||||||
value: thread
|
value: thread
|
||||||
textContent: "Thread No.#{thread}"
|
textContent: "Thread No.#{thread}"
|
||||||
QR.resetThreadSelector()
|
|
||||||
|
|
||||||
$.on nodes.filename.parentNode, 'click keyup', QR.openFileInput
|
$.on nodes.filename.parentNode, 'click keyup', QR.openFileInput
|
||||||
|
|
||||||
|
<% if (type === 'userscript') { %>
|
||||||
|
# XXX Firefox lacks focusin/focusout support.
|
||||||
|
for elm in $$ '*', QR.nodes.el
|
||||||
|
$.on elm, 'blur', QR.focusout
|
||||||
|
$.on elm, 'focus', QR.focusin
|
||||||
|
<% } %>
|
||||||
|
$.on QR.nodes.el, 'focusin', QR.focusin
|
||||||
|
$.on QR.nodes.el, 'focusout', QR.focusout
|
||||||
$.on nodes.autohide, 'change', QR.toggleHide
|
$.on nodes.autohide, 'change', QR.toggleHide
|
||||||
$.on nodes.close, 'click', QR.close
|
$.on nodes.close, 'click', QR.close
|
||||||
$.on nodes.dumpButton, 'click', -> nodes.el.classList.toggle 'dump'
|
$.on nodes.dumpButton, 'click', -> nodes.el.classList.toggle 'dump'
|
||||||
@ -809,13 +832,21 @@ QR =
|
|||||||
$.on nodes.fileRM, 'click', -> QR.selected.rmFile()
|
$.on nodes.fileRM, 'click', -> QR.selected.rmFile()
|
||||||
$.on nodes.spoiler, 'change', -> QR.selected.nodes.spoiler.click()
|
$.on nodes.spoiler, 'change', -> QR.selected.nodes.spoiler.click()
|
||||||
$.on nodes.fileInput, 'change', QR.fileInput
|
$.on nodes.fileInput, 'change', QR.fileInput
|
||||||
|
|
||||||
new QR.post true
|
|
||||||
# save selected post's data
|
# save selected post's data
|
||||||
for name in ['name', 'email', 'sub', 'com']
|
for name in ['name', 'email', 'sub', 'com']
|
||||||
$.on nodes[name], 'input', -> QR.selected.save @
|
$.on nodes[name], 'input', -> QR.selected.save @
|
||||||
$.on nodes[name], 'focus', -> $.addClass nodes.el, 'focus'
|
$.on nodes.thread, 'change', -> QR.selected.save @
|
||||||
$.on nodes[name], 'blur', -> $.rmClass nodes.el, 'focus'
|
|
||||||
|
<% if (type === 'userscript') { %>
|
||||||
|
if Conf['Remember QR Size']
|
||||||
|
$.get 'QR Size', '', (item) ->
|
||||||
|
nodes.com.style.cssText = item['QR Size']
|
||||||
|
$.on nodes.com, 'mouseup', (e) ->
|
||||||
|
return if e.button isnt 0
|
||||||
|
$.set 'QR Size', @style.cssText
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
new QR.post true
|
||||||
|
|
||||||
QR.status()
|
QR.status()
|
||||||
QR.cooldown.init()
|
QR.cooldown.init()
|
||||||
@ -842,7 +873,7 @@ QR =
|
|||||||
post.forceSave()
|
post.forceSave()
|
||||||
if g.BOARD.ID is 'f'
|
if g.BOARD.ID is 'f'
|
||||||
filetag = QR.nodes.flashTag.value
|
filetag = QR.nodes.flashTag.value
|
||||||
threadID = QR.nodes.thread.value
|
threadID = post.thread
|
||||||
thread = g.BOARD.threads[threadID]
|
thread = g.BOARD.threads[threadID]
|
||||||
|
|
||||||
# prevent errors
|
# prevent errors
|
||||||
@ -930,6 +961,11 @@ QR =
|
|||||||
QR.status()
|
QR.status()
|
||||||
|
|
||||||
response: ->
|
response: ->
|
||||||
|
<% if (type === 'userjs') { %>
|
||||||
|
# The upload.onload callback is not called
|
||||||
|
# or at least not in time with Opera.
|
||||||
|
QR.req.upload.onload()
|
||||||
|
<% } %>
|
||||||
{req} = QR
|
{req} = QR
|
||||||
delete QR.req
|
delete QR.req
|
||||||
|
|
||||||
@ -971,6 +1007,12 @@ QR =
|
|||||||
# Too many frequent mistyped captchas will auto-ban you!
|
# Too many frequent mistyped captchas will auto-ban you!
|
||||||
# On connection error, the post most likely didn't go through.
|
# On connection error, the post most likely didn't go through.
|
||||||
QR.cooldown.set delay: 2
|
QR.cooldown.set delay: 2
|
||||||
|
else if err.textContent and m = err.textContent.match /wait\s(\d+)\ssecond/i
|
||||||
|
QR.cooldown.auto = if QR.captcha.isEnabled
|
||||||
|
!!QR.captcha.captchas.length
|
||||||
|
else
|
||||||
|
true
|
||||||
|
QR.cooldown.set delay: m[1]
|
||||||
else # stop auto-posting
|
else # stop auto-posting
|
||||||
QR.cooldown.auto = false
|
QR.cooldown.auto = false
|
||||||
QR.status()
|
QR.status()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user