GM2 incoming!
This commit is contained in:
parent
ace1dc878c
commit
41c22af15f
@ -1,3 +1,5 @@
|
||||
- Compatibility fixes for Greasemonkey v2.
|
||||
|
||||
### 3.20.14 - *2014-06-13*
|
||||
|
||||
- The QR won't duplicate single-word captchas anymore if you've input numbers only (like a street address).
|
||||
|
||||
@ -136,6 +136,10 @@ $.off = (el, events, handler) ->
|
||||
el.removeEventListener event, handler, false
|
||||
return
|
||||
$.event = (event, detail, root=d) ->
|
||||
<% if (type === 'userscript') { %>
|
||||
if detail? and typeof cloneInto is 'function'
|
||||
detail = cloneInto detail, d.defaultView
|
||||
<% } %>
|
||||
root.dispatchEvent new CustomEvent event, {bubbles: true, detail}
|
||||
<% if (type === 'userscript') { %>
|
||||
$.open = GM_openInTab
|
||||
|
||||
@ -167,7 +167,6 @@ Filter =
|
||||
textContent: 'Filter'
|
||||
|
||||
entry =
|
||||
type: 'post'
|
||||
el: div
|
||||
order: 50
|
||||
open: (post) ->
|
||||
@ -192,7 +191,7 @@ Filter =
|
||||
# Add a sub entry for each filter type.
|
||||
entry.subEntries.push Filter.menu.createSubEntry type[0], type[1]
|
||||
|
||||
$.event 'AddMenuEntry', entry
|
||||
Menu.menu.addEntry entry
|
||||
|
||||
createSubEntry: (text, type) ->
|
||||
el = $.el 'a',
|
||||
|
||||
@ -87,8 +87,7 @@ PostHiding =
|
||||
makeStub =
|
||||
el: $.el 'label', innerHTML: "<input type=checkbox name=makeStub checked=#{Conf['Stubs']}> Make stub"
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
Menu.menu.addEntry
|
||||
el: $.el 'div',
|
||||
textContent: 'Hide post'
|
||||
className: 'hide-post-link'
|
||||
@ -116,8 +115,7 @@ PostHiding =
|
||||
@el.firstChild.checked = if 'hideRecursively' of data then data.hideRecursively else Conf['Recursive Hiding']
|
||||
true
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
Menu.menu.addEntry
|
||||
el: $.el 'div',
|
||||
textContent: 'Unhide post'
|
||||
className: 'show-post-link'
|
||||
@ -131,8 +129,7 @@ PostHiding =
|
||||
subEntries: [apply, thisPost, replies]
|
||||
|
||||
return if g.VIEW isnt 'index'
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
Menu.menu.addEntry
|
||||
el: $.el 'a', href: 'javascript:;'
|
||||
order: 20
|
||||
open: (post) ->
|
||||
|
||||
@ -8,7 +8,7 @@ Header =
|
||||
@hitzone = $ '#header-bar-hitzone', @bar
|
||||
@noticesRoot = $ '#notifications', headerEl
|
||||
|
||||
@menu = new UI.Menu 'header'
|
||||
@menu = new UI.Menu()
|
||||
menuButton = $.el 'a',
|
||||
className: 'menu-button'
|
||||
innerHTML: '<i class="fa fa-bars"></i>'
|
||||
@ -61,8 +61,7 @@ Header =
|
||||
$.sync 'Top Board List', @setTopBoardList
|
||||
$.sync 'Bottom Board List', @setBotBoardList
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'header'
|
||||
@menu.addEntry
|
||||
el: $.el 'span', textContent: 'Header'
|
||||
order: 105
|
||||
subEntries: [
|
||||
@ -313,9 +312,8 @@ Header =
|
||||
Header.menu.toggle e, @, g
|
||||
|
||||
createNotification: (e) ->
|
||||
{type, content, lifetime, cb} = e.detail
|
||||
{type, content, lifetime} = e.detail
|
||||
notice = new Notice type, content, lifetime
|
||||
cb notice if cb
|
||||
|
||||
areNotificationsEnabled: false
|
||||
enableDesktopNotifications: ->
|
||||
|
||||
@ -53,8 +53,7 @@ Index =
|
||||
when 'Show Replies'
|
||||
$.on input, 'change', @cb.replies
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'header'
|
||||
Header.menu.addEntry
|
||||
el: $.el 'span',
|
||||
textContent: 'Index Navigation'
|
||||
order: 90
|
||||
@ -115,8 +114,7 @@ Index =
|
||||
init: ->
|
||||
return if g.VIEW isnt 'index' or !Conf['Menu'] or g.BOARD.ID is 'f'
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
Menu.menu.addEntry
|
||||
el: $.el 'a', href: 'javascript:;'
|
||||
order: 19
|
||||
open: ({thread}) ->
|
||||
@ -615,7 +613,6 @@ Index =
|
||||
Index.buildHRs nodes
|
||||
$.rmAll Index.root
|
||||
$.add Index.root, nodes
|
||||
$.event 'IndexBuild', nodes
|
||||
|
||||
isSearching: false
|
||||
clearSearch: ->
|
||||
|
||||
@ -120,7 +120,6 @@ Main =
|
||||
initFeature 'Linkify', Linkify
|
||||
# c.timeEnd 'All initializations'
|
||||
|
||||
$.on d, 'AddCallback', Main.addCallback
|
||||
$.ready Main.initReady
|
||||
|
||||
initStyle: ->
|
||||
@ -230,20 +229,6 @@ Main =
|
||||
# c.profileEnd callback.name
|
||||
Main.handleErrors errors if errors
|
||||
|
||||
addCallback: (e) ->
|
||||
obj = e.detail
|
||||
unless typeof obj.callback.name is 'string'
|
||||
throw new Error "Invalid callback name: #{obj.callback.name}"
|
||||
switch obj.type
|
||||
when 'Post'
|
||||
Klass = Post
|
||||
when 'Thread'
|
||||
Klass = Thread
|
||||
else
|
||||
return
|
||||
obj.callback.isAddon = true
|
||||
Klass.callbacks.push obj.callback
|
||||
|
||||
handleErrors: (errors) ->
|
||||
unless errors instanceof Array
|
||||
error = errors
|
||||
|
||||
@ -6,8 +6,7 @@ Settings =
|
||||
textContent: '<%= meta.name %> Settings'
|
||||
href: 'javascript:;'
|
||||
$.on link, 'click', Settings.open
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'header'
|
||||
Header.menu.addEntry
|
||||
el: link
|
||||
order: 111
|
||||
|
||||
@ -18,8 +17,7 @@ Settings =
|
||||
Settings.addSection 'Rice', Settings.rice
|
||||
Settings.addSection 'Archives', Settings.archives
|
||||
Settings.addSection 'Keybinds', Settings.keybinds
|
||||
$.on d, 'AddSettingsSection', Settings.addSection
|
||||
$.on d, 'OpenSettings', (e) -> Settings.open e.detail
|
||||
$.on d, 'OpenSettings', (e) -> Settings.open e.detail
|
||||
|
||||
settings = JSON.parse(localStorage.getItem '4chan-settings') or {}
|
||||
return if settings.disableAll
|
||||
@ -65,8 +63,6 @@ Settings =
|
||||
|
||||
sections: []
|
||||
addSection: (title, open) ->
|
||||
if typeof title isnt 'string'
|
||||
{title, open} = title.detail
|
||||
hyphenatedTitle = title.toLowerCase().replace /\s+/g, '-'
|
||||
Settings.sections.push {title, hyphenatedTitle, open}
|
||||
openSection: ->
|
||||
|
||||
@ -15,9 +15,7 @@ UI = do ->
|
||||
currentMenu = null
|
||||
lastToggledButton = null
|
||||
|
||||
constructor: (@type) ->
|
||||
# Doc here: https://github.com/MayhemYDG/4chan-x/wiki/Menu-API
|
||||
$.on d, 'AddMenuEntry', @addEntry
|
||||
constructor: ->
|
||||
@entries = []
|
||||
|
||||
makeMenu: ->
|
||||
@ -172,9 +170,7 @@ UI = do ->
|
||||
$.addClass submenu, 'right'
|
||||
$.rmClass submenu, 'left'
|
||||
|
||||
addEntry: (e) =>
|
||||
entry = e.detail
|
||||
return if entry.type isnt @type
|
||||
addEntry: (entry) ->
|
||||
@parseEntry entry
|
||||
@entries.push entry
|
||||
|
||||
|
||||
@ -223,8 +223,7 @@ ImageExpand =
|
||||
for name, conf of Config.imageExpansion
|
||||
subEntries.push createSubEntry name, conf[1]
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'header'
|
||||
Header.menu.addEntry
|
||||
el: el
|
||||
order: 80
|
||||
subEntries: subEntries
|
||||
|
||||
@ -6,7 +6,6 @@ ArchiveLink =
|
||||
textContent: 'Archive'
|
||||
|
||||
entry =
|
||||
type: 'post'
|
||||
el: div
|
||||
order: 90
|
||||
open: ({ID, thread, board}) ->
|
||||
@ -25,7 +24,7 @@ ArchiveLink =
|
||||
# Add a sub entry for each type.
|
||||
entry.subEntries.push @createSubEntry type[0], type[1]
|
||||
|
||||
$.event 'AddMenuEntry', entry
|
||||
Menu.menu.addEntry entry
|
||||
|
||||
createSubEntry: (text, type) ->
|
||||
el = $.el 'a',
|
||||
|
||||
@ -26,8 +26,7 @@ DeleteLink =
|
||||
$.on fileEl, 'click', DeleteLink.delete
|
||||
true
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
Menu.menu.addEntry
|
||||
el: div
|
||||
order: 40
|
||||
open: (post) ->
|
||||
|
||||
@ -5,8 +5,7 @@ DownloadLink =
|
||||
a = $.el 'a',
|
||||
className: 'download-link'
|
||||
textContent: 'Download file'
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
Menu.menu.addEntry
|
||||
el: a
|
||||
order: 70
|
||||
open: ({file}) ->
|
||||
|
||||
@ -2,8 +2,7 @@ Labels =
|
||||
init: ->
|
||||
return if !Conf['Menu']
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
Menu.menu.addEntry
|
||||
el: $.el 'div', textContent: 'Labels'
|
||||
order: 60
|
||||
open: (post, addSubEntry) ->
|
||||
|
||||
@ -8,7 +8,7 @@ Menu =
|
||||
href: 'javascript:;'
|
||||
@frag = $.nodes [$.tn(' '), a]
|
||||
|
||||
@menu = new UI.Menu 'post'
|
||||
@menu = new UI.Menu()
|
||||
Post.callbacks.push
|
||||
name: 'Menu'
|
||||
cb: @node
|
||||
|
||||
@ -7,8 +7,7 @@ ReportLink =
|
||||
href: 'javascript:;'
|
||||
textContent: 'Report this post'
|
||||
$.on a, 'click', ReportLink.report
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
Menu.menu.addEntry
|
||||
el: a
|
||||
order: 10
|
||||
open: (post) ->
|
||||
|
||||
@ -18,7 +18,7 @@ Fourchan =
|
||||
window.addEventListener('jsmath', function(e) {
|
||||
if (jsMath.loaded) {
|
||||
// process one post
|
||||
jsMath.ProcessBeforeShowing(e.detail);
|
||||
jsMath.ProcessBeforeShowing(document.getElementById(e.detail));
|
||||
} else {
|
||||
// load jsMath and process whole document
|
||||
jsMath.Autoload.Script.Push('ProcessBeforeShowing', [null]);
|
||||
@ -39,4 +39,4 @@ Fourchan =
|
||||
return
|
||||
math: ->
|
||||
return if @isClone or !$ '.math', @nodes.comment
|
||||
$.event 'jsmath', @nodes.post, window
|
||||
$.event 'jsmath', @nodes.post.id, window
|
||||
|
||||
@ -11,14 +11,13 @@ PSAHiding =
|
||||
return
|
||||
|
||||
entry =
|
||||
type: 'header'
|
||||
el: $.el 'a',
|
||||
textContent: 'Show announcement'
|
||||
className: 'show-announcement'
|
||||
href: 'javascript:;'
|
||||
order: 50
|
||||
open: -> psa.hidden
|
||||
$.event 'AddMenuEntry', entry
|
||||
Header.menu.addEntry entry
|
||||
$.on entry.el, 'click', PSAHiding.toggle
|
||||
|
||||
PSAHiding.btn = btn = $.el 'a',
|
||||
|
||||
@ -107,7 +107,6 @@ ThreadUpdater =
|
||||
ThreadUpdater.thread.kill()
|
||||
$.event 'ThreadUpdate',
|
||||
404: true
|
||||
thread: ThreadUpdater.thread
|
||||
else
|
||||
ThreadUpdater.outdateCount++
|
||||
ThreadUpdater.setInterval()
|
||||
@ -203,8 +202,6 @@ ThreadUpdater =
|
||||
nodes.push node
|
||||
posts.push new Post node, ThreadUpdater.thread, ThreadUpdater.thread.board
|
||||
|
||||
deletedPosts = []
|
||||
deletedFiles = []
|
||||
# Check for deleted posts/files.
|
||||
for ID, post of ThreadUpdater.thread.posts
|
||||
# XXX tmp fix for 4chan's racing condition
|
||||
@ -215,18 +212,14 @@ ThreadUpdater =
|
||||
post.resurrect()
|
||||
else unless ID in index
|
||||
post.kill()
|
||||
deletedPosts.push post
|
||||
else if post.file and !post.file.isDead and ID not in files
|
||||
post.kill true
|
||||
deletedFiles.push post
|
||||
|
||||
sendEvent = ->
|
||||
$.event 'ThreadUpdate',
|
||||
404: false
|
||||
thread: ThreadUpdater.thread
|
||||
newPosts: posts
|
||||
deletedPosts: deletedPosts
|
||||
deletedFiles: deletedFiles
|
||||
threadID: ThreadUpdater.thread.fullID
|
||||
newPosts: posts.map (post) -> post.fullID
|
||||
postCount: OP.replies + 1
|
||||
fileCount: OP.images + (!!ThreadUpdater.thread.OP.file and !ThreadUpdater.thread.OP.file.isDead)
|
||||
|
||||
|
||||
@ -65,12 +65,12 @@ ThreadWatcher =
|
||||
[boardID, threadID] = @parentNode.dataset.fullID.split '.'
|
||||
ThreadWatcher.rm boardID, +threadID
|
||||
post: (e) ->
|
||||
{board, postID, threadID} = e.detail
|
||||
{boardID, threadID, postID} = e.detail
|
||||
if postID is threadID
|
||||
if Conf['Auto Watch']
|
||||
$.set 'AutoWatch', threadID
|
||||
else if Conf['Auto Watch Reply']
|
||||
ThreadWatcher.add board.threads[threadID]
|
||||
ThreadWatcher.add g.threads[boardID + '.' + threadID]
|
||||
onIndexRefresh: ->
|
||||
boardID = g.BOARD.ID
|
||||
for threadID, data of ThreadWatcher.db.data.boards[boardID] when not data.isDead and threadID not of g.BOARD.threads
|
||||
@ -81,10 +81,9 @@ ThreadWatcher =
|
||||
ThreadWatcher.db.set {boardID, threadID, val: data}
|
||||
ThreadWatcher.refresh()
|
||||
onThreadRefresh: (e) ->
|
||||
{thread} = e.detail
|
||||
return unless e.detail[404] and ThreadWatcher.db.get {boardID: thread.board.ID, threadID: thread.ID}
|
||||
# Update 404 status.
|
||||
ThreadWatcher.add thread
|
||||
ThreadWatcher.add g.threads[e.detail.threadID]
|
||||
|
||||
fetchCount:
|
||||
fetched: 0
|
||||
@ -204,18 +203,17 @@ ThreadWatcher =
|
||||
refreshers: []
|
||||
init: ->
|
||||
return if !Conf['Thread Watcher']
|
||||
menu = new UI.Menu 'thread watcher'
|
||||
menu = new UI.Menu()
|
||||
$.on $('.menu-button', ThreadWatcher.dialog), 'click', (e) ->
|
||||
menu.toggle e, @, ThreadWatcher
|
||||
@addHeaderMenuEntry()
|
||||
@addMenuEntries()
|
||||
@addMenuEntries menu
|
||||
|
||||
addHeaderMenuEntry: ->
|
||||
return if g.VIEW isnt 'thread'
|
||||
entryEl = $.el 'a',
|
||||
href: 'javascript:;'
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'header'
|
||||
Header.menu.addEntry
|
||||
el: entryEl
|
||||
order: 60
|
||||
$.on entryEl, 'click', -> ThreadWatcher.toggle g.threads["#{g.BOARD}.#{g.THREADID}"]
|
||||
@ -228,14 +226,13 @@ ThreadWatcher =
|
||||
$.rmClass entryEl, rmClass
|
||||
entryEl.textContent = text
|
||||
|
||||
addMenuEntries: ->
|
||||
addMenuEntries: (menu) ->
|
||||
entries = []
|
||||
|
||||
# `Open all` entry
|
||||
entries.push
|
||||
cb: ThreadWatcher.cb.openAll
|
||||
entry:
|
||||
type: 'thread watcher'
|
||||
el: $.el 'a',
|
||||
textContent: 'Open all threads'
|
||||
refresh: -> (if ThreadWatcher.list.firstElementChild then $.rmClass else $.addClass) @el, 'disabled'
|
||||
@ -244,7 +241,6 @@ ThreadWatcher =
|
||||
entries.push
|
||||
cb: ThreadWatcher.cb.checkThreads
|
||||
entry:
|
||||
type: 'thread watcher'
|
||||
el: $.el 'a',
|
||||
textContent: 'Check 404\'d threads'
|
||||
refresh: -> (if $('div:not(.dead-thread)', ThreadWatcher.list) then $.rmClass else $.addClass) @el, 'disabled'
|
||||
@ -253,7 +249,6 @@ ThreadWatcher =
|
||||
entries.push
|
||||
cb: ThreadWatcher.cb.pruneDeads
|
||||
entry:
|
||||
type: 'thread watcher'
|
||||
el: $.el 'a',
|
||||
textContent: 'Prune 404\'d threads'
|
||||
refresh: -> (if $('.dead-thread', ThreadWatcher.list) then $.rmClass else $.addClass) @el, 'disabled'
|
||||
@ -264,7 +259,6 @@ ThreadWatcher =
|
||||
subEntries.push @createSubEntry name, conf[1]
|
||||
entries.push
|
||||
entry:
|
||||
type: 'thread watcher'
|
||||
el: $.el 'span',
|
||||
textContent: 'Settings'
|
||||
subEntries: subEntries
|
||||
@ -273,7 +267,7 @@ ThreadWatcher =
|
||||
entry.el.href = 'javascript:;' if entry.el.nodeName is 'A'
|
||||
$.on entry.el, 'click', cb if cb
|
||||
@refreshers.push refresh.bind entry if refresh
|
||||
$.event 'AddMenuEntry', entry
|
||||
menu.addEntry entry
|
||||
return
|
||||
createSubEntry: (name, desc) ->
|
||||
entry =
|
||||
|
||||
@ -107,7 +107,7 @@ Unread =
|
||||
if e.detail[404]
|
||||
Unread.update()
|
||||
else
|
||||
Unread.addPosts e.detail.newPosts
|
||||
Unread.addPosts e.detail.newPosts.map (fullID) -> g.posts[fullID]
|
||||
|
||||
readSinglePost: (post) ->
|
||||
return if (i = Unread.posts.indexOf post) is -1
|
||||
|
||||
@ -29,11 +29,6 @@ QR =
|
||||
QR.nodes.com.focus()
|
||||
Header.addShortcut sc, 2
|
||||
|
||||
$.on d, 'QRGetSelectedPost', ({detail: cb}) ->
|
||||
cb QR.selected
|
||||
$.on d, 'QRAddPreSubmitHook', ({detail: cb}) ->
|
||||
QR.preSubmitHooks.push cb
|
||||
|
||||
<% if (type === 'crx') { %>
|
||||
$.on d, 'paste', QR.paste
|
||||
<% } %>
|
||||
@ -384,9 +379,8 @@ QR =
|
||||
|
||||
# Create a custom event when the QR dialog is first initialized.
|
||||
# Use it to extend the QR's functionalities, or for XTRM RICE.
|
||||
$.event 'QRDialogCreation', null, dialog
|
||||
$.event 'QRDialogCreation'
|
||||
|
||||
preSubmitHooks: []
|
||||
submit: (e) ->
|
||||
e?.preventDefault()
|
||||
|
||||
@ -419,9 +413,6 @@ QR =
|
||||
err = 'No file selected.'
|
||||
else if post.file and thread.fileLimit
|
||||
err = 'Max limit of image replies has been reached.'
|
||||
else for hook in QR.preSubmitHooks
|
||||
if err = hook post, thread
|
||||
break
|
||||
|
||||
if QR.captcha.isEnabled and !err
|
||||
{challenge, response} = QR.captcha.getOne()
|
||||
@ -562,17 +553,17 @@ QR =
|
||||
|
||||
QR.db.set
|
||||
boardID: g.BOARD.ID
|
||||
threadID: threadID
|
||||
postID: postID
|
||||
threadID
|
||||
postID
|
||||
val: true
|
||||
|
||||
# Post/upload confirmed as successful.
|
||||
$.event 'QRPostSuccessful', {
|
||||
board: g.BOARD
|
||||
boardID: g.BOARD.ID
|
||||
threadID
|
||||
postID
|
||||
}
|
||||
$.event 'QRPostSuccessful_', {threadID, postID}
|
||||
$.event 'QRPostSuccessful_', {boardID: g.BOARD.ID, threadID, postID}
|
||||
|
||||
# Enable auto-posting if we have stuff left to post, disable it otherwise.
|
||||
postsCount = QR.posts.length - 1
|
||||
|
||||
@ -109,7 +109,6 @@ QR.post = class
|
||||
rectList = @nodes.el.parentNode.getBoundingClientRect()
|
||||
@nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width/2 - rectList.left - rectList.width/2
|
||||
@load()
|
||||
$.event 'QRPostSelection', @
|
||||
load: ->
|
||||
# Load this post's values.
|
||||
for name in ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user