Merge branch 'master' into zixaphir-merge
Conflicts: src/Quotelinks/QuoteThreading.coffee
This commit is contained in:
commit
a993cb8244
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,8 +1,24 @@
|
||||
The attributions below are for work that has been incorporated into the script and do not indicate direct involvement in this fork. All changes to the script are the fault of the maintainer (ccd0).
|
||||
Sometimes the changelog has notes (not comprehensive) acknowledging people's work. This does not mean the changes are their fault, only that their code was used. All changes to the script are chosen by and the fault of the maintainer (ccd0).
|
||||
|
||||
The links to individual versions below are to copies of the script with the update URL removed. If you want automatic updates, install the script from the links on the [main page](https://github.com/ccd0/4chan-x).
|
||||
|
||||
<!-- v1.9.23.x -->
|
||||
### v1.9.23.0
|
||||
*2015-02-02* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.23.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.23.0/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
|
||||
- `WEBM Metadata` option (on by default): Adds a link to display the title in the WebM metadata.
|
||||
|
||||
<!-- v1.9.22.x -->
|
||||
### v1.9.22.6
|
||||
*2015-02-02* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.22.6/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.22.6/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
|
||||
- Make `Image Hover` and `Image Hover in Catalog` independent options again.
|
||||
|
||||
### v1.9.22.5
|
||||
*2015-02-01* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.22.5/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.22.5/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
|
||||
- Make scroll wheel volume adjustments finer at low volumes.
|
||||
|
||||
### v1.9.22.4
|
||||
*2015-02-01* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.22.4/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.22.4/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 4chan X - Version 1.9.22.4
|
||||
* 4chan X - Version 1.9.23.0
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.9.22.4
|
||||
// @version 1.9.23.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.9.22.4
|
||||
// @version 1.9.23.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.9.22.4' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.9.23.0' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.9.22.4' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.9.23.0' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"meta": {
|
||||
"name": "4chan X",
|
||||
"version": "1.9.22.4",
|
||||
"version": "1.9.23.0",
|
||||
"repo": "https://github.com/ccd0/4chan-x/",
|
||||
"page": "https://github.com/ccd0/4chan-x",
|
||||
"downloads": "https://ccd0.github.io/4chan-x/builds/",
|
||||
|
||||
@ -182,12 +182,10 @@ Config =
|
||||
'Image Hover in Catalog': [
|
||||
false
|
||||
'Show full image / video on mouseover in <%= meta.name %> catalog.'
|
||||
1
|
||||
]
|
||||
'Mouse Wheel Volume': [
|
||||
true
|
||||
'Adjust volume of hovering videos with mouse wheel.'
|
||||
1
|
||||
]
|
||||
'Gallery': [
|
||||
true
|
||||
@ -207,6 +205,10 @@ Config =
|
||||
true
|
||||
'Add sauce links to images.'
|
||||
]
|
||||
'WEBM Metadata': [
|
||||
true
|
||||
'Add link to fetch title metadata from webm videos.'
|
||||
]
|
||||
'Reveal Spoiler Thumbnails': [
|
||||
false
|
||||
'Replace spoiler thumbnails with the original image.'
|
||||
|
||||
@ -10,8 +10,51 @@ CrossOrigin = do ->
|
||||
callbacks[id] = cb
|
||||
<% } %>
|
||||
|
||||
file: do ->
|
||||
makeBlob = (urlBlob, contentType, contentDisposition, url) ->
|
||||
binary: (url, cb, headers={}) ->
|
||||
<% if (type === 'crx') { %>
|
||||
if /^https:\/\//.test(url) or location.protocol is 'http:'
|
||||
xhr = new XMLHttpRequest()
|
||||
xhr.open 'GET', url, true
|
||||
xhr.setRequestHeader key, value for key, value of headers
|
||||
xhr.responseType = 'arraybuffer'
|
||||
xhr.onload = ->
|
||||
return cb null unless @readyState is @DONE and @status in [200, 206]
|
||||
contentType = @getResponseHeader 'Content-Type'
|
||||
contentDisposition = @getResponseHeader 'Content-Disposition'
|
||||
cb new Uint8Array(@response), contentType, contentDisposition
|
||||
xhr.onerror = xhr.onabort = ->
|
||||
cb null
|
||||
xhr.send()
|
||||
else
|
||||
eventPageRequest url, 'arraybuffer', ({response, contentType, contentDisposition, error}) ->
|
||||
return cb null if error
|
||||
cb new Uint8Array(response), contentType, contentDisposition
|
||||
<% } %>
|
||||
<% if (type === 'userscript') { %>
|
||||
GM_xmlhttpRequest
|
||||
method: "GET"
|
||||
url: url
|
||||
headers: headers
|
||||
overrideMimeType: "text/plain; charset=x-user-defined"
|
||||
onload: (xhr) ->
|
||||
r = xhr.responseText
|
||||
data = new Uint8Array r.length
|
||||
i = 0
|
||||
while i < r.length
|
||||
data[i] = r.charCodeAt i
|
||||
i++
|
||||
contentType = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)?[1]
|
||||
contentDisposition = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)?[1]
|
||||
cb data, contentType, contentDisposition
|
||||
onerror: ->
|
||||
cb null
|
||||
onabort: ->
|
||||
cb null
|
||||
<% } %>
|
||||
|
||||
file: (url, cb) ->
|
||||
CrossOrigin.binary url, (data, contentType, contentDisposition) ->
|
||||
return cb null unless data?
|
||||
name = url.match(/([^\/]+)\/*$/)?[1]
|
||||
mime = contentType?.match(/[^;]*/)[0] or 'application/octet-stream'
|
||||
match =
|
||||
@ -19,45 +62,9 @@ CrossOrigin = do ->
|
||||
contentType?.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)?[1]
|
||||
if match
|
||||
name = match.replace /\\"/g, '"'
|
||||
blob = new Blob([urlBlob], {type: mime})
|
||||
blob = new Blob([data], {type: mime})
|
||||
blob.name = name
|
||||
blob
|
||||
|
||||
(url, cb) ->
|
||||
<% if (type === 'crx') { %>
|
||||
if /^https:\/\//.test(url) or location.protocol is 'http:'
|
||||
$.ajax url,
|
||||
responseType: 'blob'
|
||||
onload: ->
|
||||
return cb null unless @readyState is @DONE and @status is 200
|
||||
contentType = @getResponseHeader 'Content-Type'
|
||||
contentDisposition = @getResponseHeader 'Content-Disposition'
|
||||
cb (makeBlob @response, contentType, contentDisposition, url)
|
||||
onerror: ->
|
||||
cb null
|
||||
else
|
||||
eventPageRequest url, 'arraybuffer', ({response, contentType, contentDisposition, error}) ->
|
||||
return cb null if error
|
||||
cb (makeBlob new Uint8Array(response), contentType, contentDisposition, url)
|
||||
<% } %>
|
||||
<% if (type === 'userscript') { %>
|
||||
GM_xmlhttpRequest
|
||||
method: "GET"
|
||||
url: url
|
||||
overrideMimeType: "text/plain; charset=x-user-defined"
|
||||
onload: (xhr) ->
|
||||
r = xhr.responseText
|
||||
data = new Uint8Array r.length
|
||||
i = 0
|
||||
while i < r.length
|
||||
data[i] = r.charCodeAt i
|
||||
i++
|
||||
contentType = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)?[1]
|
||||
contentDisposition = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)?[1]
|
||||
cb (makeBlob data, contentType, contentDisposition, url)
|
||||
onerror: ->
|
||||
cb null
|
||||
<% } %>
|
||||
cb blob
|
||||
|
||||
json: do ->
|
||||
callbacks = {}
|
||||
|
||||
@ -342,6 +342,7 @@ Main =
|
||||
['Image Loading', ImageLoader]
|
||||
['Image Hover', ImageHover]
|
||||
['Volume Control', Volume]
|
||||
['WEBM Metadata', Metadata]
|
||||
['Comment Expansion', ExpandComment]
|
||||
['Thread Expansion', ExpandThread]
|
||||
['Thread Excerpt', ThreadExcerpt]
|
||||
|
||||
@ -928,6 +928,9 @@ span.hide-announcement {
|
||||
.fileThumb > .warning {
|
||||
clear: both;
|
||||
}
|
||||
a.webm-title.ready {
|
||||
text-decoration: underline;
|
||||
}
|
||||
input[name="Default Volume"] {
|
||||
width: 4em;
|
||||
height: 1ex;
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
ImageHover =
|
||||
init: ->
|
||||
return unless Conf['Image Hover'] and g.VIEW in ['index', 'thread']
|
||||
|
||||
Post.callbacks.push
|
||||
name: 'Image Hover'
|
||||
cb: @node
|
||||
|
||||
return if g.VIEW not in ['index', 'thread']
|
||||
if Conf['Image Hover']
|
||||
Post.callbacks.push
|
||||
name: 'Image Hover'
|
||||
cb: @node
|
||||
if Conf['Image Hover in Catalog']
|
||||
CatalogThread.callbacks.push
|
||||
name: 'Image Hover'
|
||||
@ -82,8 +81,8 @@ ImageHover =
|
||||
wheel: (e) ->
|
||||
return unless el = $.id 'ihover'
|
||||
return if el.muted or not $.hasAudio el
|
||||
{volume} = el
|
||||
volume += 0.1 if e.deltaY < 0
|
||||
volume -= 0.1 if e.deltaY > 0
|
||||
el.volume = $.minmax volume, 0, 1
|
||||
volume = el.volume + 0.1
|
||||
volume *= 1.1 if e.deltaY < 0
|
||||
volume /= 1.1 if e.deltaY > 0
|
||||
el.volume = $.minmax volume - 0.1, 0, 1
|
||||
e.preventDefault()
|
||||
|
||||
64
src/Images/Metadata.coffee
Normal file
64
src/Images/Metadata.coffee
Normal file
@ -0,0 +1,64 @@
|
||||
Metadata =
|
||||
init: ->
|
||||
return unless Conf['WEBM Metadata'] and g.VIEW in ['index', 'thread'] and g.BOARD.ID isnt 'f'
|
||||
|
||||
Post.callbacks.push
|
||||
name: 'WEBM Metadata'
|
||||
cb: @node
|
||||
|
||||
node: ->
|
||||
return unless @file and /webm$/i.test @file.URL
|
||||
if @isClone
|
||||
link = $ '.webm-title', @file.text
|
||||
else
|
||||
link = $.el 'a',
|
||||
className: 'webm-title ready'
|
||||
href: 'javascript:;'
|
||||
textContent: 'title'
|
||||
$.add @file.text, [$.tn('\u00A0'), link]
|
||||
$.on link, 'click', Metadata[if link.dataset.title? then 'toggle' else 'load']
|
||||
|
||||
load: ->
|
||||
$.off @, 'click', Metadata.load
|
||||
$.rmClass @, 'ready'
|
||||
@textContent = '...'
|
||||
CrossOrigin.binary Get.postFromNode(@).file.URL, (data) =>
|
||||
if data?
|
||||
Metadata.parse.call @, data
|
||||
$.on @, 'click', Metadata.toggle
|
||||
else
|
||||
@textContent = 'error'
|
||||
$.on @, 'click', Metadata.load
|
||||
,
|
||||
Range: 'bytes=0-9999'
|
||||
|
||||
parse: (data) ->
|
||||
readInt = ->
|
||||
n = data[i++]
|
||||
len = 0
|
||||
len++ while n < (0x80 >> len)
|
||||
n ^= (0x80 >> len)
|
||||
while len-- and i < data.length
|
||||
n = (n << 8) ^ data[i++]
|
||||
n
|
||||
|
||||
i = 0
|
||||
while i < data.length
|
||||
element = readInt()
|
||||
size = readInt()
|
||||
if element is 0x3BA9 # Title
|
||||
title = ''
|
||||
while size-- and i < data.length
|
||||
title += String.fromCharCode data[i++]
|
||||
@textContent = @dataset.title = decodeURIComponent escape title # UTF-8 decoding
|
||||
return
|
||||
else unless element in [0x8538067, 0x549A966] # Segment, Info
|
||||
i += size
|
||||
@textContent = 'not found'
|
||||
|
||||
toggle: ->
|
||||
@textContent = if $.hasClass @, 'ready'
|
||||
@dataset.title or 'not found'
|
||||
else
|
||||
'title'
|
||||
$.toggleClass @, 'ready'
|
||||
@ -1,7 +1,7 @@
|
||||
Volume =
|
||||
init: ->
|
||||
return unless g.VIEW in ['index', 'thread'] and
|
||||
(Conf['Image Expansion'] or Conf['Image Hover'] or Conf['Gallery'])
|
||||
(Conf['Image Expansion'] or Conf['Image Hover'] or Conf['Image Hover in Catalog'] or Conf['Gallery'])
|
||||
|
||||
$.sync 'Allow Sound', (x) ->
|
||||
Conf['Allow Sound'] = x
|
||||
|
||||
@ -17,8 +17,8 @@ QuoteThreading =
|
||||
|
||||
@input = $('input', @controls)
|
||||
|
||||
$.on @input, 'change', @cb.thread
|
||||
$.on @threadNewLink.firstElementChild, 'click', @cb.click
|
||||
$.on @input, 'change', @rethread
|
||||
$.on @threadNewLink.firstElementChild, 'click', @rethread
|
||||
|
||||
Header.menu.addEntry @entry =
|
||||
el: @controls
|
||||
@ -99,11 +99,13 @@ QuoteThreading =
|
||||
|
||||
return true
|
||||
|
||||
rethread: (enabled) ->
|
||||
rethread: ->
|
||||
{thread} = QuoteThreading
|
||||
{posts} = thread
|
||||
|
||||
if QuoteThreading.enabled = enabled
|
||||
QuoteThreading.threadNewLink.hidden = true
|
||||
|
||||
if QuoteThreading.enabled = QuoteThreading.input.checked
|
||||
posts.forEach QuoteThreading.insert
|
||||
else
|
||||
nodes = []
|
||||
@ -125,9 +127,3 @@ QuoteThreading =
|
||||
Unread.setLine true
|
||||
Unread.read()
|
||||
Unread.update()
|
||||
|
||||
cb:
|
||||
thread: -> QuoteThreading.rethread QuoteThreading.input.checked
|
||||
click: ->
|
||||
QuoteThreading.threadNewLink.hidden = true
|
||||
QuoteThreading.rethread true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user