Merge branch 'v3'
Conflicts: CHANGELOG.md LICENSE builds/appchan-x.user.js builds/crx/manifest.json builds/crx/script.js package.json src/General/Navigate.coffee src/Miscellaneous/CatalogLinks.coffee src/Posting/QR.coffee
This commit is contained in:
commit
2efa358131
67
CHANGELOG.md
67
CHANGELOG.md
@ -1,5 +1,72 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
### v2.9.26
|
### v2.9.26
|
||||||
*2014-05-07*
|
*2014-05-07*
|
||||||
|
=======
|
||||||
|
**MayhemYDG**:
|
||||||
|
- [Security fix](https://github.com/MayhemYDG/4chan-x/issues/1634).
|
||||||
|
|
||||||
|
### v1.7.33
|
||||||
|
*2014-05-10*
|
||||||
|
|
||||||
|
**DamonGant**
|
||||||
|
- Add Innovandalism Archive.
|
||||||
|
|
||||||
|
**ccd0**
|
||||||
|
- Update archive list.
|
||||||
|
- Add "disabled" option when Foolz Beta is the only choice.
|
||||||
|
|
||||||
|
### v1.7.32
|
||||||
|
*2014-05-10*
|
||||||
|
|
||||||
|
**Zixaphir, ccd0**
|
||||||
|
- Bug fixes in linkification/embedding.
|
||||||
|
|
||||||
|
**ccd0**
|
||||||
|
- Begin refactoring code to reduce potential for introducing Javascript injection bugs.
|
||||||
|
|
||||||
|
### v1.7.31
|
||||||
|
*2014-05-08*
|
||||||
|
|
||||||
|
**Zixaphir**
|
||||||
|
- Refactoring, bug fixes.
|
||||||
|
|
||||||
|
**ccd0**
|
||||||
|
- Fix some potential Javascript injection issues.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
### v1.7.30
|
||||||
|
*2014-05-05*
|
||||||
|
|
||||||
|
**thebladeee**
|
||||||
|
- Update archives.
|
||||||
|
|
||||||
|
### v1.7.29
|
||||||
|
*2014-05-03*
|
||||||
|
|
||||||
|
**ccd0**:
|
||||||
|
- If the original post form not hidden, it is expanded (except on the catalog page).
|
||||||
|
- 4chan's horizontal rules are no longer hidden. If you want to hide them as before, add the old code to your custom CSS:
|
||||||
|
```
|
||||||
|
body > hr,
|
||||||
|
#blotter hr,
|
||||||
|
.desktop > hr,
|
||||||
|
#delform > hr,
|
||||||
|
#content > hr {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
:root.index .board > hr:last-of-type,
|
||||||
|
:root.thread .board > hr {
|
||||||
|
border: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### v1.7.28
|
||||||
|
*2014-05-03*
|
||||||
|
|
||||||
|
**ccd0**:
|
||||||
|
- Copy Mayhem's fix for 4chan post form changes.
|
||||||
|
>>>>>>> v3
|
||||||
|
|
||||||
**zixaphir**
|
**zixaphir**
|
||||||
- Fixed (maybe?) a vulnerability in the post parser that allowed playful users to inject scripts or elements into posts, which could be used maliciously.
|
- Fixed (maybe?) a vulnerability in the post parser that allowed playful users to inject scripts or elements into posts, which could be used maliciously.
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* appchan x - Version 2.9.26 - 2014-05-11
|
* appchan x - Version 2.9.26 - 2014-05-27
|
||||||
*
|
*
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 4chan X
|
// @name 4chan X
|
||||||
// @version 1.7.27
|
// @version 1.7.33
|
||||||
// @minGMVer 1.14
|
// @minGMVer 1.14
|
||||||
// @minFFVer 26
|
// @minFFVer 26
|
||||||
// @namespace 4chan-X
|
// @namespace 4chan-X
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.27' />
|
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.33' />
|
||||||
</app>
|
</app>
|
||||||
</gupdate>
|
</gupdate>
|
||||||
|
|
||||||
|
|||||||
@ -18,9 +18,9 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
transition: color .25s, border-color .25s, flex .25s;
|
transition: color .25s, border-color .25s, flex .25s;
|
||||||
}
|
}
|
||||||
.field::-moz-placeholder,
|
.field::-moz-placeholder {
|
||||||
.field:hover::-moz-placeholder {
|
color: #AAA;
|
||||||
color: #AAA !important;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.field:hover {
|
.field:hover {
|
||||||
border-color: #999;
|
border-color: #999;
|
||||||
|
|||||||
@ -7,9 +7,9 @@ Redirect =
|
|||||||
|
|
||||||
archives = {}
|
archives = {}
|
||||||
for data in Redirect.archives
|
for data in Redirect.archives
|
||||||
{name, boards, files, software} = data
|
{name, boards, files, software, withCredentials} = data
|
||||||
archives[name] = data
|
archives[name] = data
|
||||||
for boardID in boards
|
for boardID in boards when !withCredentials
|
||||||
o.thread[boardID] = data unless boardID of o.thread
|
o.thread[boardID] = data unless boardID of o.thread
|
||||||
o.post[boardID] = data unless boardID of o.post or software isnt 'foolfuuka'
|
o.post[boardID] = data unless boardID of o.post or software isnt 'foolfuuka'
|
||||||
o.file[boardID] = data unless boardID of o.file or boardID not in files
|
o.file[boardID] = data unless boardID of o.file or boardID not in files
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
"https": true,
|
"https": true,
|
||||||
"software": "foolfuuka",
|
"software": "foolfuuka",
|
||||||
"boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "vg", "vp", "vr", "wsg"],
|
"boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "vg", "vp", "vr", "wsg"],
|
||||||
"files": ["a", "biz", "gd", "diy", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"]
|
"files": ["a", "biz", "diy", "gd", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"]
|
||||||
}, {
|
}, {
|
||||||
"uid": 1,
|
"uid": 1,
|
||||||
"name": "NSFW Foolz",
|
"name": "NSFW Foolz",
|
||||||
@ -65,7 +65,7 @@
|
|||||||
"uid": 8,
|
"uid": 8,
|
||||||
"name": "Rebecca Black Tech",
|
"name": "Rebecca Black Tech",
|
||||||
"domain": "rbt.asia",
|
"domain": "rbt.asia",
|
||||||
"http": true,
|
"http": false,
|
||||||
"https": true,
|
"https": true,
|
||||||
"software": "fuuka",
|
"software": "fuuka",
|
||||||
"boards": ["cgl", "g", "mu", "w"],
|
"boards": ["cgl", "g", "mu", "w"],
|
||||||
@ -78,7 +78,7 @@
|
|||||||
"https": false,
|
"https": false,
|
||||||
"software": "fuuka",
|
"software": "fuuka",
|
||||||
"boards": ["an", "fit", "k", "mlp", "r9k", "toy"],
|
"boards": ["an", "fit", "k", "mlp", "r9k", "toy"],
|
||||||
"files": ["an", "fit", "k", "r9k", "toy"]
|
"files": ["an", "fit", "k", "mlp", "r9k", "toy"]
|
||||||
}, {
|
}, {
|
||||||
"uid": 10,
|
"uid": 10,
|
||||||
"name": "warosu",
|
"name": "warosu",
|
||||||
@ -115,6 +115,15 @@
|
|||||||
"software": "foolfuuka",
|
"software": "foolfuuka",
|
||||||
"boards": ["g", "t"],
|
"boards": ["g", "t"],
|
||||||
"files": ["g", "t"]
|
"files": ["g", "t"]
|
||||||
|
}, {
|
||||||
|
"uid": 19,
|
||||||
|
"name": "Innovandalism Archive",
|
||||||
|
"domain": "boards.innovandalism.eu",
|
||||||
|
"http": true,
|
||||||
|
"https": false,
|
||||||
|
"software": "foolfuuka",
|
||||||
|
"boards": ["v"],
|
||||||
|
"files": []
|
||||||
}, {
|
}, {
|
||||||
"uid": 13,
|
"uid": 13,
|
||||||
"name": "Foolz Beta",
|
"name": "Foolz Beta",
|
||||||
@ -125,4 +134,13 @@
|
|||||||
"software": "foolfuuka",
|
"software": "foolfuuka",
|
||||||
"boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "vg", "vp", "vr", "wsg"],
|
"boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "vg", "vp", "vr", "wsg"],
|
||||||
"files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"]
|
"files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"]
|
||||||
|
}, {
|
||||||
|
"uid": 19,
|
||||||
|
"name": "Innovandalism Archive",
|
||||||
|
"domain": "boards.innovandalism.eu",
|
||||||
|
"http": true,
|
||||||
|
"https": false,
|
||||||
|
"software": "foolfuuka",
|
||||||
|
"boards": ["v"],
|
||||||
|
"files": []
|
||||||
}]
|
}]
|
||||||
|
|||||||
@ -47,7 +47,7 @@ Build =
|
|||||||
name: data.filename + data.ext
|
name: data.filename + data.ext
|
||||||
timestamp: "#{data.tim}#{data.ext}"
|
timestamp: "#{data.tim}#{data.ext}"
|
||||||
url: if boardID is 'f'
|
url: if boardID is 'f'
|
||||||
"//i.4cdn.org/#{boardID}/#{data.filename}#{data.ext}"
|
"//i.4cdn.org/#{boardID}/#{encodeURIComponent data.filename}#{data.ext}"
|
||||||
else
|
else
|
||||||
"//i.4cdn.org/#{boardID}/#{data.tim}#{data.ext}"
|
"//i.4cdn.org/#{boardID}/#{data.tim}#{data.ext}"
|
||||||
height: data.h
|
height: data.h
|
||||||
@ -150,7 +150,7 @@ Build =
|
|||||||
imgSrc = if boardID is 'f'
|
imgSrc = if boardID is 'f'
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
"<a class='fileThumb#{if file.isSpoiler then ' imgspoiler' else ''}' href='#{file.url}' target=_blank>" +
|
"<a class='fileThumb#{if file.isSpoiler then ' imgspoiler' else ''}' href=\"#{file.url}\" target=_blank>" +
|
||||||
"<img src='#{fileThumb}' alt='#{fileSize}' data-md5=#{file.MD5} style='height: #{file.theight}px; width: #{file.twidth}px;'>" +
|
"<img src='#{fileThumb}' alt='#{fileSize}' data-md5=#{file.MD5} style='height: #{file.theight}px; width: #{file.twidth}px;'>" +
|
||||||
"</a>"
|
"</a>"
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ Build =
|
|||||||
|
|
||||||
fileDims = if file.name[-3..] is 'pdf' then 'PDF' else "#{file.width}x#{file.height}"
|
fileDims = if file.name[-3..] is 'pdf' then 'PDF' else "#{file.width}x#{file.height}"
|
||||||
fileInfo = "<div class=fileText #{if file.isSpoiler then "title='#{filename}'" else ''}>File: " +
|
fileInfo = "<div class=fileText #{if file.isSpoiler then "title='#{filename}'" else ''}>File: " +
|
||||||
"<a href='#{file.url}' #{if filename isnt shortFilename and !file.isSpoiler then " title='#{filename}'" else ''} target=_blank>#{if file.isSpoiler then 'Spoiler Image' else shortFilename}</a>" +
|
"<a href=\"#{file.url}\" #{if filename isnt shortFilename and !file.isSpoiler then " title='#{filename}'" else ''} target=_blank>#{if file.isSpoiler then 'Spoiler Image' else shortFilename}</a>" +
|
||||||
" (#{fileSize}, #{fileDims})</div>"
|
" (#{fileSize}, #{fileDims})</div>"
|
||||||
|
|
||||||
fileHTML = "<div class=file>#{fileInfo}#{imgSrc}</div>"
|
fileHTML = "<div class=file>#{fileInfo}#{imgSrc}</div>"
|
||||||
@ -284,7 +284,7 @@ Build =
|
|||||||
pageCount = Index.liveThreadData.keys.indexOf("#{thread.ID}") // Index.threadsNumPerPage + 1
|
pageCount = Index.liveThreadData.keys.indexOf("#{thread.ID}") // Index.threadsNumPerPage + 1
|
||||||
|
|
||||||
subject = if thread.OP.info.subject
|
subject = if thread.OP.info.subject
|
||||||
"<div class='subject'>#{thread.OP.info.subject}</div>"
|
"<div class='subject'>#{thread.OP.nodes.subject.innerHTML}</div>"
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
comment = thread.OP.nodes.comment.innerHTML.replace /(<br>\s*){2,}/g, '<br>'
|
comment = thread.OP.nodes.comment.innerHTML.replace /(<br>\s*){2,}/g, '<br>'
|
||||||
|
|||||||
@ -91,6 +91,7 @@ Index =
|
|||||||
@navLinks = $.el 'div',
|
@navLinks = $.el 'div',
|
||||||
className: 'navLinks'
|
className: 'navLinks'
|
||||||
innerHTML: <%= importHTML('Features/Index-navlinks') %>
|
innerHTML: <%= importHTML('Features/Index-navlinks') %>
|
||||||
|
@timeEl = $ 'time#index-last-refresh', @navLinks
|
||||||
|
|
||||||
@searchInput = $ '#index-search', @navLinks
|
@searchInput = $ '#index-search', @navLinks
|
||||||
|
|
||||||
@ -114,7 +115,8 @@ Index =
|
|||||||
|
|
||||||
@currentPage = @getCurrentPage()
|
@currentPage = @getCurrentPage()
|
||||||
|
|
||||||
$.on d, 'scroll', Index.scroll
|
$.on d, 'scroll', @scroll
|
||||||
|
$.on window, 'focus', @updateIfNeeded
|
||||||
$.on @pagelist, 'click', @cb.pageNav
|
$.on @pagelist, 'click', @cb.pageNav
|
||||||
|
|
||||||
returnLink = $.el 'a',
|
returnLink = $.el 'a',
|
||||||
@ -221,11 +223,12 @@ Index =
|
|||||||
thread = g.threads[@parentNode.dataset.fullID]
|
thread = g.threads[@parentNode.dataset.fullID]
|
||||||
if e.shiftKey
|
if e.shiftKey
|
||||||
PostHiding.toggle thread.OP
|
PostHiding.toggle thread.OP
|
||||||
|
e.preventDefault()
|
||||||
else if e.altKey
|
else if e.altKey
|
||||||
Index.togglePin thread
|
Index.togglePin thread
|
||||||
|
e.preventDefault()
|
||||||
else
|
else
|
||||||
Navigate.navigate.call @
|
Navigate.navigate.call @, e
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
onOver: (e) ->
|
onOver: (e) ->
|
||||||
# 4chan's less than stellar CSS forces us to include a .post and .postInfo
|
# 4chan's less than stellar CSS forces us to include a .post and .postInfo
|
||||||
@ -297,7 +300,7 @@ Index =
|
|||||||
|
|
||||||
setupNavLinks: ->
|
setupNavLinks: ->
|
||||||
for el in $$ '.navLinks.desktop > a'
|
for el in $$ '.navLinks.desktop > a'
|
||||||
if el.getAttribute('href') is '.././catalog'
|
if /\/catalog$/.test el.pathname
|
||||||
el.href = '.././'
|
el.href = '.././'
|
||||||
$.on el, 'click', ->
|
$.on el, 'click', ->
|
||||||
switch @textContent
|
switch @textContent
|
||||||
@ -508,6 +511,18 @@ Index =
|
|||||||
else
|
else
|
||||||
"#{hiddenCount} hidden threads"
|
"#{hiddenCount} hidden threads"
|
||||||
|
|
||||||
|
updateIfNeeded: ->
|
||||||
|
{timeEl} = Index
|
||||||
|
needed =
|
||||||
|
# we're on the index,
|
||||||
|
g.VIEW is 'index' and
|
||||||
|
# not currently refreshing
|
||||||
|
!Index.req and
|
||||||
|
timeEl.dataset.utc and
|
||||||
|
# more than 10 minutes have elapsed since the last refresh.
|
||||||
|
timeEl.dataset.utc < Date.now() - (10 * $.MINUTE)
|
||||||
|
Index.update() if needed
|
||||||
|
|
||||||
update: (pageNum) ->
|
update: (pageNum) ->
|
||||||
return unless navigator.onLine
|
return unless navigator.onLine
|
||||||
if g.VIEW is 'thread'
|
if g.VIEW is 'thread'
|
||||||
@ -585,7 +600,7 @@ Index =
|
|||||||
new Notice 'error', 'Index refresh failed.', 1
|
new Notice 'error', 'Index refresh failed.', 1
|
||||||
return
|
return
|
||||||
|
|
||||||
timeEl = $ 'time#index-last-refresh', Index.navLinks
|
{timeEl} = Index
|
||||||
timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified'
|
timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified'
|
||||||
RelativeDates.update timeEl
|
RelativeDates.update timeEl
|
||||||
Index.scrollToIndex()
|
Index.scrollToIndex()
|
||||||
|
|||||||
@ -87,11 +87,6 @@ Main =
|
|||||||
Report.init()
|
Report.init()
|
||||||
return
|
return
|
||||||
when 'i.4cdn.org'
|
when 'i.4cdn.org'
|
||||||
if Conf['Loop in New Tab'] and video = $ 'video'
|
|
||||||
Video.configure video
|
|
||||||
$.on video, 'click', ->
|
|
||||||
if !video.controls
|
|
||||||
if video.paused then video.play() else video.pause()
|
|
||||||
$.ready ->
|
$.ready ->
|
||||||
if Conf['404 Redirect'] and d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found']
|
if Conf['404 Redirect'] and d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found']
|
||||||
Redirect.init()
|
Redirect.init()
|
||||||
@ -100,6 +95,11 @@ Main =
|
|||||||
boardID: g.BOARD.ID
|
boardID: g.BOARD.ID
|
||||||
filename: pathname[pathname.length - 1]
|
filename: pathname[pathname.length - 1]
|
||||||
location.replace URL if URL
|
location.replace URL if URL
|
||||||
|
else if Conf['Loop in New Tab'] and video = $ 'video'
|
||||||
|
Video.configure video
|
||||||
|
if !video.controls
|
||||||
|
$.on video, 'click', ->
|
||||||
|
if video.paused then video.play() else video.pause()
|
||||||
return
|
return
|
||||||
|
|
||||||
# c.time 'All initializations'
|
# c.time 'All initializations'
|
||||||
|
|||||||
@ -196,7 +196,7 @@ Navigate =
|
|||||||
return if @hostname isnt 'boards.4chan.org' or window.location.hostname is 'rs.4chan.org'
|
return if @hostname isnt 'boards.4chan.org' or window.location.hostname is 'rs.4chan.org'
|
||||||
if e
|
if e
|
||||||
if e.shiftKey or e.ctrlKey or (e.type is 'click' and e.button isnt 0) # Not simply a left click
|
if e.shiftKey or e.ctrlKey or (e.type is 'click' and e.button isnt 0) # Not simply a left click
|
||||||
Navigate.setMode @ unless e?.button is 2 # Right Click
|
Navigate.setMode @ unless e.button is 2 # Right Click
|
||||||
return
|
return
|
||||||
|
|
||||||
if @pathname is Navigate.path
|
if @pathname is Navigate.path
|
||||||
|
|||||||
@ -266,15 +266,21 @@ Settings =
|
|||||||
$.on $.id('apply-css'), 'click', Settings.usercss
|
$.on $.id('apply-css'), 'click', Settings.usercss
|
||||||
|
|
||||||
archBoards = {}
|
archBoards = {}
|
||||||
for {name, boards, files, software} in Redirect.archives
|
for {name, boards, files, software, withCredentials} in Redirect.archives
|
||||||
for boardID in boards
|
for boardID in boards
|
||||||
o = archBoards[boardID] or=
|
o = archBoards[boardID] or=
|
||||||
thread: []
|
thread: [[], []]
|
||||||
post: []
|
post: [[], []]
|
||||||
file: []
|
file: [[], []]
|
||||||
o.thread.push name
|
i = +!!withCredentials
|
||||||
o.post.push name if software is 'foolfuuka'
|
o.thread[i].push name
|
||||||
o.file.push name if boardID in files
|
o.post[i].push name if software is 'foolfuuka'
|
||||||
|
o.file[i].push name if boardID in files
|
||||||
|
for boardID, o of archBoards
|
||||||
|
for item in ['thread', 'post', 'file']
|
||||||
|
if o[item][0].length is 0 and o[item][1].length isnt 0
|
||||||
|
o[item][0].push 'disabled'
|
||||||
|
o[item] = o[item][0].concat(o[item][1])
|
||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
boardOptions = []
|
boardOptions = []
|
||||||
|
|||||||
@ -69,24 +69,9 @@ a {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 0px 2px;
|
padding: 0px 2px;
|
||||||
}
|
}
|
||||||
body > hr,
|
|
||||||
#blotter hr,
|
|
||||||
.desktop > hr,
|
|
||||||
#delform > hr,
|
|
||||||
#content > hr {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
:root.index .board > hr:last-of-type,
|
|
||||||
:root.thread .board > hr {
|
|
||||||
border: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
.ad-plea {
|
.ad-plea {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.ad-cnt {
|
|
||||||
margin: 10px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 4chan style fixes */
|
/* 4chan style fixes */
|
||||||
.opContainer, .op {
|
.opContainer, .op {
|
||||||
@ -904,13 +889,16 @@ span.hide-announcement {
|
|||||||
|
|
||||||
/* QR */
|
/* QR */
|
||||||
:root.hide-original-post-form #postForm,
|
:root.hide-original-post-form #postForm,
|
||||||
:root.hide-original-post-form .postingMode,
|
:root.hide-original-post-form #togglePostFormLink,
|
||||||
:root.hide-original-post-form #togglePostForm,
|
:root:not(.catalog) #togglePostFormLink,
|
||||||
#qr.autohide:not(.focus):not(:hover):not(:active) > form,
|
#qr.autohide:not(.focus):not(:hover):not(:active) > form,
|
||||||
.thread #qr select[data-name=thread],
|
.thread #qr select[data-name=thread],
|
||||||
#file-n-submit:not(.has-file) #qr-filerm {
|
#file-n-submit:not(.has-file) #qr-filerm {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
:root:not(.hide-original-post-form):not(.catalog) #postForm {
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
#qr select,
|
#qr select,
|
||||||
#dump-button,
|
#dump-button,
|
||||||
#url-button,
|
#url-button,
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
"javascript:quote(#{postID})"
|
"javascript:quote(#{postID})"
|
||||||
else
|
else
|
||||||
"/#{boardID}/thread/#{threadID}#q#{postID}"
|
"/#{boardID}/thread/#{threadID}#q#{postID}"
|
||||||
}' title='Quote this post'>#{postID}</a>
|
}' title='Reply to this post'>#{postID}</a>
|
||||||
#{pageIcon + sticky + closed + replyLink}
|
#{pageIcon + sticky + closed + replyLink}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -10,14 +10,13 @@ Linkify =
|
|||||||
|
|
||||||
if Conf['Embedding'] or Conf['Link Title']
|
if Conf['Embedding'] or Conf['Link Title']
|
||||||
@embedProcess = Function 'link',
|
@embedProcess = Function 'link',
|
||||||
"var data = this.services(link);
|
"""
|
||||||
if (data) {
|
var data = this.services(link);
|
||||||
#{
|
if (data) {#{
|
||||||
(if Conf['Embedding'] then 'this.embed(data);\n' else '') +
|
(if Conf['Embedding'] then 'this.embed(data); ' else '') +
|
||||||
if Conf['Link Title'] then 'this.title(data);' else ''
|
if Conf['Link Title'] then 'data.push(post); this.title(data);' else ''
|
||||||
}
|
}}
|
||||||
}
|
"""
|
||||||
"
|
|
||||||
|
|
||||||
Post.callbacks.push
|
Post.callbacks.push
|
||||||
name: 'Linkify'
|
name: 'Linkify'
|
||||||
@ -156,7 +155,7 @@ Linkify =
|
|||||||
return
|
return
|
||||||
|
|
||||||
embed: (data) ->
|
embed: (data) ->
|
||||||
[key, uid, options, link] = data
|
[key, uid, options, link, post] = data
|
||||||
href = link.href
|
href = link.href
|
||||||
embed = $.el 'a',
|
embed = $.el 'a',
|
||||||
className: 'embedder'
|
className: 'embedder'
|
||||||
@ -164,7 +163,6 @@ Linkify =
|
|||||||
textContent: '(embed)'
|
textContent: '(embed)'
|
||||||
|
|
||||||
embed.dataset[name] = value for name, value of {key, href, uid, options}
|
embed.dataset[name] = value for name, value of {key, href, uid, options}
|
||||||
embed.dataset.nodedata = link.innerHTML
|
|
||||||
|
|
||||||
$.addClass link, "#{embed.dataset.key}"
|
$.addClass link, "#{embed.dataset.key}"
|
||||||
|
|
||||||
@ -173,33 +171,30 @@ Linkify =
|
|||||||
|
|
||||||
Linkify.cb.toggle.call embed if Conf['Auto-embed']
|
Linkify.cb.toggle.call embed if Conf['Auto-embed']
|
||||||
|
|
||||||
data.push embed
|
|
||||||
|
|
||||||
title: (data) ->
|
title: (data) ->
|
||||||
[key, uid, options, link, embed] = data
|
[key, uid, options, link, post] = data
|
||||||
return unless service = Linkify.types[key].title
|
return unless service = Linkify.types[key].title
|
||||||
titles = Conf['CachedTitles']
|
titles = Conf['CachedTitles']
|
||||||
if title = titles[uid]
|
if title = titles[uid]
|
||||||
# Auto-embed may destroy our links.
|
link.textContent = title[0]
|
||||||
if link
|
|
||||||
link.textContent = title[0]
|
|
||||||
if Conf['Embedding']
|
|
||||||
embed.dataset.title = title[0]
|
|
||||||
else
|
else
|
||||||
try
|
try
|
||||||
$.cache service.api(uid), (-> Linkify.cb.title @, data), responseType: 'json'
|
$.cache service.api(uid), (-> Linkify.cb.title @, data), responseType: 'json'
|
||||||
catch err
|
catch err
|
||||||
if link
|
link.innerHTML = '<span class="warning">Title Link Blocked</span> (are you using NoScript?)</a>'
|
||||||
link.innerHTML = "[#{key}] <span class=warning>Title Link Blocked</span> (are you using NoScript?)</a>"
|
$.prepend link, $.tn "[#{key}] "
|
||||||
return
|
return
|
||||||
|
|
||||||
cb:
|
cb:
|
||||||
toggle: ->
|
toggle: ->
|
||||||
[string, @textContent] = if $.hasClass @, "embedded"
|
if $.hasClass @, "embedded"
|
||||||
['unembed', '(embed)']
|
$.rm @previousElementSibling
|
||||||
|
@previousElementSibling.hidden = false
|
||||||
|
@textContent = '(embed)'
|
||||||
else
|
else
|
||||||
['embed', '(unembed)']
|
@previousElementSibling.hidden = true
|
||||||
$.replace @previousElementSibling, Linkify.cb[string] @
|
$.before @, Linkify.cb.embed @
|
||||||
|
@textContent = '(unembed)'
|
||||||
$.toggleClass @, 'embedded'
|
$.toggleClass @, 'embedded'
|
||||||
|
|
||||||
embed: (a) ->
|
embed: (a) ->
|
||||||
@ -214,21 +209,8 @@ Linkify =
|
|||||||
|
|
||||||
return el
|
return el
|
||||||
|
|
||||||
unembed: (a) ->
|
|
||||||
# Recreate the original link.
|
|
||||||
el = $.el 'a',
|
|
||||||
rel: 'nofollow noreferrer'
|
|
||||||
target: 'blank'
|
|
||||||
className: 'linkify'
|
|
||||||
href: a.dataset.href
|
|
||||||
innerHTML: a.dataset.title or a.dataset.nodedata
|
|
||||||
|
|
||||||
$.addClass el, a.dataset.key
|
|
||||||
|
|
||||||
return el
|
|
||||||
|
|
||||||
title: (req, data) ->
|
title: (req, data) ->
|
||||||
[key, uid, options, link, embed] = data
|
[key, uid, options, link, post] = data
|
||||||
{status} = req
|
{status} = req
|
||||||
service = Linkify.types[key].title
|
service = Linkify.types[key].title
|
||||||
|
|
||||||
@ -243,8 +225,11 @@ Linkify =
|
|||||||
"#{status}'d"
|
"#{status}'d"
|
||||||
}"
|
}"
|
||||||
|
|
||||||
embed.dataset.title = text if Conf['Embedding'] and status in [200, 304]
|
link.textContent = text
|
||||||
link.textContent = text if link
|
for post2 in post.clones
|
||||||
|
for link2 in $$ 'a', post2.nodes.comment when link2.href is link.href
|
||||||
|
link2.textContent = text
|
||||||
|
return
|
||||||
|
|
||||||
ordered_types: [
|
ordered_types: [
|
||||||
key: 'audio'
|
key: 'audio'
|
||||||
@ -271,8 +256,10 @@ Linkify =
|
|||||||
regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/
|
regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/
|
||||||
style: 'border: 0; width: auto; height: auto;'
|
style: 'border: 0; width: auto; height: auto;'
|
||||||
el: (a) ->
|
el: (a) ->
|
||||||
$.el 'div',
|
el = $.el 'div'
|
||||||
innerHTML: "<a target=_blank href='#{a.dataset.href}'><img src='#{a.dataset.href}'></a>"
|
el.innerHTML = '<a target="_blank"><img></a>'
|
||||||
|
el.firstChild.href = el.firstChild.firstChild.src = a.dataset.href
|
||||||
|
el
|
||||||
,
|
,
|
||||||
key: 'InstallGentoo'
|
key: 'InstallGentoo'
|
||||||
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/
|
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/
|
||||||
@ -298,35 +285,36 @@ Linkify =
|
|||||||
el
|
el
|
||||||
,
|
,
|
||||||
key: 'MediaCrush'
|
key: 'MediaCrush'
|
||||||
regExp: /.*(?:mediacru.sh\/)([0-9a-z_]+)/i
|
regExp: /.*(?:mediacru.sh\/)([0-9a-z_-]+)/i
|
||||||
style: 'border: 0;'
|
style: 'border: 0;'
|
||||||
el: (a) ->
|
el: (a) ->
|
||||||
el = $.el 'div'
|
el = $.el 'div'
|
||||||
$.cache "https://mediacru.sh/#{a.dataset.uid}.json", ->
|
$.cache "https://mediacru.sh/#{a.dataset.uid}.json", ->
|
||||||
{status} = @
|
{status} = @
|
||||||
return div.innerHTML = "ERROR #{status}" unless status in [200, 304]
|
return el.textContent = "ERROR #{status}" unless status in [200, 304]
|
||||||
{files} = @response
|
{files} = @response
|
||||||
for type in ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg']
|
for type in ['video/mp4', 'video/webm', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'audio/mpeg', 'audio/ogg']
|
||||||
for file in files
|
for file in files
|
||||||
if file.type is type
|
if file.type is type
|
||||||
embed = file
|
embed = file
|
||||||
break
|
break
|
||||||
break if embed
|
break if embed
|
||||||
return div.innerHTML = "ERROR: Not a valid filetype" unless embed
|
return div.textContent = "ERROR: Not a valid filetype" unless embed
|
||||||
el.innerHTML = switch embed.type
|
switch embed.type
|
||||||
when 'video/mp4', 'video/ogv' then """
|
when 'video/mp4', 'video/webm', 'video/ogv'
|
||||||
<video autoplay loop>
|
el.innerHTML = '<video autoplay loop><source type="video/mp4"><source type="video/webm"><source type="video/ogg"></video>'
|
||||||
<source src="https://mediacru.sh/#{a.dataset.uid}.mp4" type="video/mp4;">
|
for ext, i in ['mp4', 'webm', 'ogv']
|
||||||
<source src="https://mediacru.sh/#{a.dataset.uid}.ogv" type="video/ogg; codecs='theora, vorbis'">
|
el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}"
|
||||||
</video>"""
|
when 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg'
|
||||||
when 'image/png', 'image/gif', 'image/jpeg'
|
el.innerHTML = '<a target="_blank"><img></a>'
|
||||||
"<a target=_blank href='#{a.dataset.href}'><img src='https://mediacru.sh/#{file.file}'></a>"
|
el.firstChild.href = a.dataset.href
|
||||||
when 'image/svg', 'image/svg+xml'
|
el.firstChild.firstChild.src = "https://mediacru.sh/#{file.file}"
|
||||||
"<embed src='https://mediacru.sh/#{file.file}' type='image/svg+xml' />"
|
when 'audio/mpeg', 'audio/ogg'
|
||||||
when 'audio/mpeg'
|
el.innerHTML = '<audio controls><source type="audio/ogg"><source type="audio/mpeg"></audio>'
|
||||||
"<audio controls><source src='https://mediacru.sh/#{file.file}'></audio>"
|
for ext, i in ['ogg', 'mp3']
|
||||||
|
el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}"
|
||||||
else
|
else
|
||||||
"ERROR: No valid filetype."
|
el.textContent = "ERROR: No valid filetype."
|
||||||
el
|
el
|
||||||
,
|
,
|
||||||
key: 'pastebin'
|
key: 'pastebin'
|
||||||
@ -343,19 +331,12 @@ Linkify =
|
|||||||
,
|
,
|
||||||
key: 'SoundCloud'
|
key: 'SoundCloud'
|
||||||
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
|
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
|
||||||
style: 'height: auto; width: 500px; display: inline-block;'
|
style: 'border: 0; width: 500px; height: 400px;'
|
||||||
el: (a) ->
|
el: (a) ->
|
||||||
div = $.el 'div',
|
$.el 'iframe',
|
||||||
className: "soundcloud"
|
src: "//w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F#{encodeURIComponent a.dataset.uid}"
|
||||||
name: "soundcloud"
|
|
||||||
$.ajax(
|
|
||||||
"//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{a.dataset.uid}"
|
|
||||||
onloadend: ->
|
|
||||||
div.innerHTML = JSON.parse(@responseText).html
|
|
||||||
false)
|
|
||||||
div
|
|
||||||
title:
|
title:
|
||||||
api: (uid) -> "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{uid}"
|
api: (uid) -> "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F#{encodeURIComponent uid}"
|
||||||
text: (_) -> _.title
|
text: (_) -> _.title
|
||||||
,
|
,
|
||||||
key: 'StrawPoll'
|
key: 'StrawPoll'
|
||||||
@ -369,26 +350,21 @@ Linkify =
|
|||||||
regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/
|
regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/
|
||||||
style: "border: none; width: 640px; height: 360px;"
|
style: "border: none; width: 640px; height: 360px;"
|
||||||
el: (a) ->
|
el: (a) ->
|
||||||
if result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec a.dataset.uid
|
if result = /(\w+)\/([bc])\/(\d+)/i.exec a.dataset.uid
|
||||||
[_, channel, chapter] = result
|
[_, channel, type, id] = result
|
||||||
|
idparam = {'b': 'archive_id', 'c': 'chapter_id'}
|
||||||
$.el 'object',
|
obj = $.el 'object',
|
||||||
data: 'http://www.twitch.tv/widgets/archive_embed_player.swf'
|
data: 'http://www.twitch.tv/widgets/archive_embed_player.swf'
|
||||||
innerHTML: """
|
obj.innerHTML = '<param name="allowFullScreen" value="true"><param name="flashvars">'
|
||||||
<param name='allowFullScreen' value='true' />
|
obj.children[1].value = "channel=#{channel}&start_volume=25&auto_play=false&#{idparam[type]}=#{id}"
|
||||||
<param name='flashvars' value='channel=#{channel}&start_volume=25&auto_play=false#{if chapter then "&chapter_id=" + chapter else ""}' />
|
obj
|
||||||
"""
|
|
||||||
|
|
||||||
else
|
else
|
||||||
channel = (/(\w+)/.exec a.dataset.uid)[0]
|
channel = (/(\w+)/.exec a.dataset.uid)[0]
|
||||||
|
obj = $.el 'object',
|
||||||
$.el 'object',
|
|
||||||
data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=#{channel}"
|
data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=#{channel}"
|
||||||
innerHTML: """
|
obj.innerHTML = '<param name="allowFullScreen" value="true"><param name="flashvars">'
|
||||||
<param name="allowFullScreen" value="true" />
|
obj.children[1].value = "hostname=www.twitch.tv&channel=#{channel}&auto_play=true&start_volume=25"
|
||||||
<param name="movie" value="http://www.twitch.tv/widgets/live_embed_player.swf" />
|
obj
|
||||||
<param name="flashvars" value="hostname=www.twitch.tv&channel=#{channel}&auto_play=true&start_volume=25" />
|
|
||||||
"""
|
|
||||||
,
|
,
|
||||||
key: 'Vocaroo'
|
key: 'Vocaroo'
|
||||||
regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/
|
regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/
|
||||||
|
|||||||
@ -44,10 +44,7 @@ CatalogLinks =
|
|||||||
CatalogLinks.el.title = "Turn catalog links #{if useCatalog then 'off' else 'on'}."
|
CatalogLinks.el.title = "Turn catalog links #{if useCatalog then 'off' else 'on'}."
|
||||||
|
|
||||||
external: (board) ->
|
external: (board) ->
|
||||||
switch board
|
if board in ['a', 'c', 'g', 'co', 'k', 'm', 'o', 'p', 'v', 'vg', 'w', 'cm', '3', 'adv', 'an', 'cgl', 'ck', 'diy', 'fa', 'fit', 'int', 'jp', 'mlp', 'lit', 'mu', 'n', 'po', 'sci', 'toy', 'trv', 'tv', 'vp', 'x', 'q']
|
||||||
when 'a', 'c', 'g', 'co', 'k', 'm', 'o', 'p', 'v', 'vg', 'w', 'cm', '3', 'adv', 'an', 'cgl', 'ck', 'diy', 'fa', 'fit', 'int', 'jp', 'mlp', 'lit', 'mu', 'n', 'po', 'sci', 'toy', 'trv', 'tv', 'vp', 'x', 'q'
|
"http://catalog.neet.tv/#{board}"
|
||||||
"http://catalog.neet.tv/#{board}"
|
else
|
||||||
when 'd', 'e', 'gif', 'h', 'hr', 'hc', 'r9k', 's', 'pol', 'soc', 'u', 'i', 'ic', 'hm', 'r', 'w', 'wg', 'wsg', 't', 'y'
|
"/#{board}/catalog"
|
||||||
"http://4index.gropes.us/#{board}"
|
|
||||||
else
|
|
||||||
"/#{board}/catalog"
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ Keybinds =
|
|||||||
keydown: (e) ->
|
keydown: (e) ->
|
||||||
return unless key = Keybinds.keyCode e
|
return unless key = Keybinds.keyCode e
|
||||||
{target} = e
|
{target} = e
|
||||||
|
return if target.nodeName is 'EMBED' # Prevent keybinds from firing on /f/ embeds.
|
||||||
if target.nodeName in ['INPUT', 'TEXTAREA']
|
if target.nodeName in ['INPUT', 'TEXTAREA']
|
||||||
return unless /(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test key
|
return unless /(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test key
|
||||||
unless g.VIEW is 'catalog'
|
unless g.VIEW is 'catalog'
|
||||||
|
|||||||
@ -43,8 +43,7 @@ QR =
|
|||||||
initReady: ->
|
initReady: ->
|
||||||
$.off d, '4chanXInitFinished', @initReady
|
$.off d, '4chanXInitFinished', @initReady
|
||||||
QR.postingIsEnabled = !!$.id 'postForm'
|
QR.postingIsEnabled = !!$.id 'postForm'
|
||||||
unless QR.postingIsEnabled
|
return unless QR.postingIsEnabled
|
||||||
return
|
|
||||||
|
|
||||||
$.on d, 'QRGetSelectedPost', ({detail: cb}) ->
|
$.on d, 'QRGetSelectedPost', ({detail: cb}) ->
|
||||||
cb QR.selected
|
cb QR.selected
|
||||||
@ -359,26 +358,23 @@ QR =
|
|||||||
if /^text\//.test file.type
|
if /^text\//.test file.type
|
||||||
if isSingle
|
if isSingle
|
||||||
post = QR.selected
|
post = QR.selected
|
||||||
else if index isnt 0 or (post = QR.posts[QR.posts.length - 1]).com
|
else if (post = QR.posts[QR.posts.length - 1]).com
|
||||||
post = new QR.post()
|
post = new QR.post()
|
||||||
post.pasteText file
|
post.pasteText file
|
||||||
return
|
return
|
||||||
unless file.type in QR.mimeTypes
|
unless file.type in QR.mimeTypes
|
||||||
QR.error "#{file.name}: Unsupported file type."
|
QR.error "#{file.name}: Unsupported file type."
|
||||||
return unless isSingle
|
return
|
||||||
max = QR.nodes.fileInput.max
|
max = QR.nodes.fileInput.max
|
||||||
max = Math.min(max, QR.max_size_video) if /^video\//.test file.type
|
max = Math.min(max, QR.max_size_video) if /^video\//.test file.type
|
||||||
if file.size > max
|
if file.size > max
|
||||||
QR.error "#{file.name}: File too large (file: #{$.bytesToString file.size}, max: #{$.bytesToString max})."
|
QR.error "#{file.name}: File too large (file: #{$.bytesToString file.size}, max: #{$.bytesToString max})."
|
||||||
return unless isSingle
|
return
|
||||||
if isSingle
|
if isSingle
|
||||||
post = QR.selected
|
post = QR.selected
|
||||||
else if index isnt 0 or (post = QR.posts[QR.posts.length - 1]).file
|
else if (post = QR.posts[QR.posts.length - 1]).file
|
||||||
post = new QR.post()
|
post = new QR.post()
|
||||||
if /^text/.test file.type
|
post.setFile file
|
||||||
return post.pasteText file
|
|
||||||
else
|
|
||||||
post.setFile file
|
|
||||||
|
|
||||||
openFileInput: (e) ->
|
openFileInput: (e) ->
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@ -436,7 +432,6 @@ QR =
|
|||||||
setNode 'addPost', '#add-post'
|
setNode 'addPost', '#add-post'
|
||||||
setNode 'charCount', '#char-count'
|
setNode 'charCount', '#char-count'
|
||||||
setNode 'fileSubmit', '#file-n-submit'
|
setNode 'fileSubmit', '#file-n-submit'
|
||||||
setNode 'filesize', '#qr-filesize'
|
|
||||||
setNode 'filename', '#qr-filename'
|
setNode 'filename', '#qr-filename'
|
||||||
setNode 'fileContainer', '#qr-filename-container'
|
setNode 'fileContainer', '#qr-filename-container'
|
||||||
setNode 'fileRM', '#qr-filerm'
|
setNode 'fileRM', '#qr-filerm'
|
||||||
|
|||||||
@ -82,6 +82,7 @@ QR.post = class
|
|||||||
(QR.posts[index-1] or QR.posts[index+1]).select()
|
(QR.posts[index-1] or QR.posts[index+1]).select()
|
||||||
QR.posts.splice index, 1
|
QR.posts.splice index, 1
|
||||||
QR.status()
|
QR.status()
|
||||||
|
|
||||||
delete: ->
|
delete: ->
|
||||||
$.rm @nodes.el
|
$.rm @nodes.el
|
||||||
URL.revokeObjectURL @URL
|
URL.revokeObjectURL @URL
|
||||||
@ -185,7 +186,7 @@ QR.post = class
|
|||||||
if errors.length
|
if errors.length
|
||||||
QR.error error for error in errors
|
QR.error error for error in errors
|
||||||
@URL = fileURL # this.removeFile will revoke this proper.
|
@URL = fileURL # this.removeFile will revoke this proper.
|
||||||
return @rmFile()
|
return if (QR.posts.length is 1) or (@com and @com.length) then @rmFile() else @rm() # I wrote this while listening to MCR
|
||||||
|
|
||||||
# Generate thumbnails only if they're really big.
|
# Generate thumbnails only if they're really big.
|
||||||
# Resized pictures through canvases look like ass,
|
# Resized pictures through canvases look like ass,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user