Merge branch 'v3'
Conflicts: CHANGELOG.md builds/appchan-x.user.js builds/crx/script.js src/Images/ImageExpand.coffee src/Images/ImageHover.coffee
This commit is contained in:
commit
453ebe7e74
@ -1,3 +1,6 @@
|
|||||||
|
**MayhemYDG**:
|
||||||
|
- Some changes to webm code.
|
||||||
|
|
||||||
### v2.9.12
|
### v2.9.12
|
||||||
*2014-04-04*
|
*2014-04-04*
|
||||||
|
|
||||||
@ -21,6 +24,9 @@
|
|||||||
### v2.9.10
|
### v2.9.10
|
||||||
*2014-04-02*
|
*2014-04-02*
|
||||||
|
|
||||||
|
**duckness**:
|
||||||
|
- Merge changes from Mayhem fork
|
||||||
|
|
||||||
**MayhemYDG**:
|
**MayhemYDG**:
|
||||||
- Fix captcha submission:
|
- Fix captcha submission:
|
||||||
Captchas were reloaded the instant a post was submitted to 4chan. Unfortunately, a recent change to reCAPTCHA made it so reloading captchas invalidates the ones that loaded but not yet used. This is now fixed by only unloading the captcha, and only load new ones after the post is submitted.<br>
|
Captchas were reloaded the instant a post was submitted to 4chan. Unfortunately, a recent change to reCAPTCHA made it so reloading captchas invalidates the ones that loaded but not yet used. This is now fixed by only unloading the captcha, and only load new ones after the post is submitted.<br>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -28,15 +28,15 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"font-awesome": "~4.0.3",
|
"font-awesome": "~4.0.3",
|
||||||
"grunt": "~0.4.2",
|
"grunt": "~0.4.4",
|
||||||
"grunt-bump": "~0.0.13",
|
"grunt-bump": "~0.0.13",
|
||||||
"grunt-concurrent": "~0.5.0",
|
"grunt-concurrent": "~0.5.0",
|
||||||
"grunt-contrib-clean": "~0.5.0",
|
"grunt-contrib-clean": "~0.5.0",
|
||||||
"grunt-contrib-coffee": "~0.10.0",
|
"grunt-contrib-coffee": "~0.10.1",
|
||||||
"grunt-contrib-compress": "~0.7.0",
|
"grunt-contrib-compress": "~0.7.0",
|
||||||
"grunt-contrib-concat": "~0.3.0",
|
"grunt-contrib-concat": "~0.4.0",
|
||||||
"grunt-contrib-copy": "~0.5.0",
|
"grunt-contrib-copy": "~0.5.0",
|
||||||
"grunt-contrib-watch": "~0.6.0",
|
"grunt-contrib-watch": "~0.6.1",
|
||||||
"grunt-shell": "~0.6.4",
|
"grunt-shell": "~0.6.4",
|
||||||
"load-grunt-tasks": "~0.4.0"
|
"load-grunt-tasks": "~0.4.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -149,7 +149,8 @@ Filter =
|
|||||||
return post.file.name
|
return post.file.name
|
||||||
false
|
false
|
||||||
dimensions: (post) ->
|
dimensions: (post) ->
|
||||||
if post.file and post.file.isImage
|
{file} = post
|
||||||
|
if file and (file.isImage or file.isVideo)
|
||||||
return post.file.dimensions
|
return post.file.dimensions
|
||||||
false
|
false
|
||||||
filesize: (post) ->
|
filesize: (post) ->
|
||||||
|
|||||||
@ -7,8 +7,9 @@ Build =
|
|||||||
# OPs have a +10 characters threshold.
|
# OPs have a +10 characters threshold.
|
||||||
# The file extension is not taken into account.
|
# The file extension is not taken into account.
|
||||||
threshold = if isReply then 30 else 40
|
threshold = if isReply then 30 else 40
|
||||||
if filename.length - 4 > threshold
|
ext = filename.match(/\.[^.]+$/)[0]
|
||||||
"#{filename[...threshold - 5]}(...).#{filename[-3..]}"
|
if filename.length - ext.length > threshold
|
||||||
|
"#{filename[...threshold - 5]}(...)#{ext}"
|
||||||
else
|
else
|
||||||
filename
|
filename
|
||||||
thumbRotate: do ->
|
thumbRotate: do ->
|
||||||
|
|||||||
@ -361,6 +361,7 @@ Settings =
|
|||||||
sizeInBytes: 276 * 1024
|
sizeInBytes: 276 * 1024
|
||||||
dimensions: '1280x720'
|
dimensions: '1280x720'
|
||||||
isImage: true
|
isImage: true
|
||||||
|
isVideo: false
|
||||||
isSpoiler: true
|
isSpoiler: true
|
||||||
funk = FileInfo.createFunc @value
|
funk = FileInfo.createFunc @value
|
||||||
@nextElementSibling.innerHTML = funk FileInfo, data
|
@nextElementSibling.innerHTML = funk FileInfo, data
|
||||||
|
|||||||
@ -925,7 +925,7 @@ nav a,
|
|||||||
.move {
|
.move {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.ihover {
|
#ihover {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
max-height: 94vh;
|
max-height: 94vh;
|
||||||
max-width: 75vw;
|
max-width: 75vw;
|
||||||
|
|||||||
@ -108,7 +108,7 @@ div.center:not(.ad-cnt) {
|
|||||||
/* fixed, z-index */
|
/* fixed, z-index */
|
||||||
#overlay,
|
#overlay,
|
||||||
#fourchanx-settings,
|
#fourchanx-settings,
|
||||||
#qp, .ihover,
|
#qp, #ihover,
|
||||||
#navlinks, .fixed #header-bar,
|
#navlinks, .fixed #header-bar,
|
||||||
:root.float #updater,
|
:root.float #updater,
|
||||||
:root.float #thread-stats,
|
:root.float #thread-stats,
|
||||||
@ -124,7 +124,7 @@ div.center:not(.ad-cnt) {
|
|||||||
#notifications {
|
#notifications {
|
||||||
z-index: 70;
|
z-index: 70;
|
||||||
}
|
}
|
||||||
#qp, .ihover {
|
#qp, #ihover {
|
||||||
z-index: 60;
|
z-index: 60;
|
||||||
}
|
}
|
||||||
#menu {
|
#menu {
|
||||||
@ -840,7 +840,7 @@ span.hide-announcement {
|
|||||||
:root.gecko.fit-width .full-image {
|
:root.gecko.fit-width .full-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.ihover {
|
#ihover {
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
|||||||
@ -116,7 +116,7 @@ class Post
|
|||||||
|
|
||||||
parseFile: (that) ->
|
parseFile: (that) ->
|
||||||
return unless (fileEl = $ '.file', @nodes.post) and thumb = $ 'img[data-md5]', fileEl
|
return unless (fileEl = $ '.file', @nodes.post) and thumb = $ 'img[data-md5]', fileEl
|
||||||
# Supports JPG/PNG/GIF/PDF.
|
# Supports JPG/PNG/GIF/WEBM/PDF.
|
||||||
# Flash files are not supported.
|
# Flash files are not supported.
|
||||||
anchor = thumb.parentNode
|
anchor = thumb.parentNode
|
||||||
fileText = fileEl.firstElementChild
|
fileText = fileEl.firstElementChild
|
||||||
|
|||||||
@ -32,4 +32,3 @@ AutoGIF =
|
|||||||
else
|
else
|
||||||
thumb.src = URL
|
thumb.src = URL
|
||||||
gif.src = URL
|
gif.src = URL
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ ImageExpand =
|
|||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return unless @file?.isImage or @file?.isVideo
|
return unless @file and (@file.isImage or @file.isVideo)
|
||||||
{thumb} = @file
|
{thumb} = @file
|
||||||
$.on thumb.parentNode, 'click', ImageExpand.cb.toggle
|
$.on thumb.parentNode, 'click', ImageExpand.cb.toggle
|
||||||
if @isClone and $.hasClass thumb, 'expanding'
|
if @isClone and $.hasClass thumb, 'expanding'
|
||||||
@ -49,7 +49,7 @@ ImageExpand =
|
|||||||
for post in [post].concat post.clones
|
for post in [post].concat post.clones
|
||||||
{file} = post
|
{file} = post
|
||||||
return unless file and (file.isImage or file.isVideo) and doc.contains post.nodes.root
|
return unless file and (file.isImage or file.isVideo) and doc.contains post.nodes.root
|
||||||
if ImageExpand.on and
|
if ImageExpand.on and !post.isHidden and
|
||||||
(!Conf['Expand spoilers'] and file.isSpoiler or
|
(!Conf['Expand spoilers'] and file.isSpoiler or
|
||||||
Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0)
|
Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0)
|
||||||
return
|
return
|
||||||
@ -90,10 +90,10 @@ ImageExpand =
|
|||||||
ImageExpand.contract post
|
ImageExpand.contract post
|
||||||
|
|
||||||
contract: (post) ->
|
contract: (post) ->
|
||||||
post.file.fullImage?.pause() if post.file.isVideo
|
|
||||||
$.rmClass post.nodes.root, 'expanded-image'
|
$.rmClass post.nodes.root, 'expanded-image'
|
||||||
$.rmClass post.file.thumb, 'expanding'
|
$.rmClass post.file.thumb, 'expanding'
|
||||||
post.file.isExpanded = false
|
post.file.isExpanded = false
|
||||||
|
post.file.fullImage.pause() if post.file.isVideo
|
||||||
post.file.videoControls?.map($.rm)
|
post.file.videoControls?.map($.rm)
|
||||||
delete post.file.videoControls
|
delete post.file.videoControls
|
||||||
|
|
||||||
@ -102,44 +102,41 @@ ImageExpand =
|
|||||||
{thumb, isVideo} = post.file
|
{thumb, isVideo} = post.file
|
||||||
return if post.isHidden or post.file.isExpanded or $.hasClass thumb, 'expanding'
|
return if post.isHidden or post.file.isExpanded or $.hasClass thumb, 'expanding'
|
||||||
$.addClass thumb, 'expanding'
|
$.addClass thumb, 'expanding'
|
||||||
naturalHeight = if isVideo then 'videoHeight' else 'naturalHeight'
|
if post.file.fullImage
|
||||||
if img = post.file.fullImage
|
|
||||||
# Expand already-loaded/ing picture.
|
# Expand already-loaded/ing picture.
|
||||||
$.addClass img, 'full-image'
|
$.asap (-> post.file.isVideo or post.file.fullImage.naturalHeight), ->
|
||||||
img.controls = (img.parentNode isnt thumb.parentNode)
|
|
||||||
$.asap (-> img[naturalHeight]), ->
|
|
||||||
ImageExpand.completeExpand post
|
ImageExpand.completeExpand post
|
||||||
return
|
return
|
||||||
post.file.fullImage = img = $.el (if isVideo then 'video' else 'img'),
|
file =
|
||||||
className: 'full-image'
|
$.el (if post.file.isImage then 'img' else 'video'),
|
||||||
src: src or post.file.URL
|
className: 'full-image'
|
||||||
|
src: src or post.file.URL
|
||||||
|
post.file.fullImage = file
|
||||||
if isVideo
|
if isVideo
|
||||||
img.loop = true
|
file.loop = true
|
||||||
img.controls = Conf['Show Controls']
|
file.controls = Conf['Show Controls']
|
||||||
$.on img, 'error', ImageExpand.error
|
$.on file, 'error', ImageExpand.error
|
||||||
$.asap (-> post.file.fullImage[naturalHeight]), ->
|
$.asap (-> post.file.isVideo or post.file.fullImage.naturalHeight), ->
|
||||||
if isVideo
|
if isVideo
|
||||||
# XXX Firefox doesn't seem to size videos correctly?
|
# XXX Firefox doesn't seem to size videos correctly?
|
||||||
img.style.maxHeight = img[naturalHeight] + "px"
|
img.style.maxHeight = img[naturalHeight] + "px"
|
||||||
img.style.maxWidth = img['videoWidth'] + "px"
|
img.style.maxWidth = img['videoWidth'] + "px"
|
||||||
ImageExpand.completeExpand post
|
ImageExpand.completeExpand post
|
||||||
$.after (if img.controls then thumb.parentNode else thumb), img
|
$.after (if file.controls then thumb.parentNode else thumb), file
|
||||||
|
|
||||||
completeExpand: (post) ->
|
completeExpand: (post) ->
|
||||||
{thumb} = post.file
|
{thumb} = post.file
|
||||||
return unless $.hasClass thumb, 'expanding' # contracted before the image loaded
|
return unless $.hasClass thumb, 'expanding' # contracted before the image loaded
|
||||||
post.file.isExpanded = true
|
post.file.isExpanded = true
|
||||||
ImageExpand.setupVideo post if post.file.isVideo
|
ImageExpand.setupVideo post if post.file.isVideo
|
||||||
|
$.addClass post.nodes.root, 'expanded-image'
|
||||||
|
$.rmClass post.file.thumb, 'expanding'
|
||||||
unless post.nodes.root.parentNode
|
unless post.nodes.root.parentNode
|
||||||
# Image might start/finish loading before the post is inserted.
|
# Image might start/finish loading before the post is inserted.
|
||||||
# Don't scroll when it's expanded in a QP for example.
|
# Don't scroll when it's expanded in a QP for example.
|
||||||
$.addClass post.nodes.root, 'expanded-image'
|
|
||||||
$.rmClass post.file.thumb, 'expanding'
|
|
||||||
return
|
return
|
||||||
{bottom} = post.nodes.root.getBoundingClientRect()
|
{bottom} = post.nodes.root.getBoundingClientRect()
|
||||||
$.queueTask ->
|
$.queueTask ->
|
||||||
$.addClass post.nodes.root, 'expanded-image'
|
|
||||||
$.rmClass post.file.thumb, 'expanding'
|
|
||||||
return unless bottom <= 0
|
return unless bottom <= 0
|
||||||
window.scrollBy 0, post.nodes.root.getBoundingClientRect().bottom - bottom
|
window.scrollBy 0, post.nodes.root.getBoundingClientRect().bottom - bottom
|
||||||
|
|
||||||
@ -159,9 +156,9 @@ ImageExpand =
|
|||||||
# drag left to contract
|
# drag left to contract
|
||||||
file.mousedown = false
|
file.mousedown = false
|
||||||
$.on video, 'mousedown', (e) -> file.mousedown = true if e.button is 0
|
$.on video, 'mousedown', (e) -> file.mousedown = true if e.button is 0
|
||||||
$.on video, 'mouseup', (e) -> file.mousedown = false if e.button is 0
|
$.on video, 'mouseup', (e) -> file.mousedown = false if e.button is 0
|
||||||
$.on video, 'mouseover', (e) -> file.mousedown = false
|
$.on video, 'mouseover', (e) -> file.mousedown = false
|
||||||
$.on video, 'mouseout', (e) ->
|
$.on video, 'mouseout', (e) ->
|
||||||
if file.mousedown and e.clientX <= video.getBoundingClientRect().left
|
if file.mousedown and e.clientX <= video.getBoundingClientRect().left
|
||||||
ImageExpand.contract post
|
ImageExpand.contract post
|
||||||
if Conf['Autoplay']
|
if Conf['Autoplay']
|
||||||
|
|||||||
@ -9,37 +9,36 @@ ImageHover =
|
|||||||
name: 'Image Hover'
|
name: 'Image Hover'
|
||||||
cb: @catalogNode
|
cb: @catalogNode
|
||||||
node: ->
|
node: ->
|
||||||
return unless @file?.isImage or @file?.isVideo
|
return unless @file and (@file.isImage or @file.isVideo)
|
||||||
$.on @file.thumb, 'mouseover', ImageHover.mouseover
|
$.on @file.thumb, 'mouseover', ImageHover.mouseover
|
||||||
catalogNode: ->
|
catalogNode: ->
|
||||||
return unless @thread.OP.file?.isImage
|
return unless @thread.OP.file and (@thread.OP.file.isImage or @thread.OP.file.isVideo)
|
||||||
$.on @nodes.thumb, 'mouseover', ImageHover.mouseover
|
$.on @nodes.thumb, 'mouseover', ImageHover.mouseover
|
||||||
mouseover: (e) ->
|
mouseover: (e) ->
|
||||||
post = if $.hasClass @, 'thumb'
|
post = if $.hasClass @, 'thumb'
|
||||||
g.posts[@parentNode.dataset.fullID]
|
g.posts[@parentNode.dataset.fullID]
|
||||||
else
|
else
|
||||||
Get.postFromNode @
|
Get.postFromNode @
|
||||||
{isVideo} = post.file
|
el = if post.file.isImage
|
||||||
el = $.el (if isVideo then 'video' else 'img'),
|
$.el 'img',
|
||||||
className: 'ihover'
|
id: 'ihover'
|
||||||
src: post.file.URL
|
src: post.file.URL
|
||||||
{thumb} = post.file
|
else
|
||||||
|
$.el 'video',
|
||||||
|
controls: false
|
||||||
|
id: 'ihover'
|
||||||
|
src: post.file.URL
|
||||||
|
autoplay: Conf['Autoplay']
|
||||||
|
muted: !Conf['Allow Sound']
|
||||||
|
loop: true
|
||||||
$.add Header.hover, el
|
$.add Header.hover, el
|
||||||
el.dataset.fullID = post.fullID
|
el.dataset.fullID = post.fullID
|
||||||
if isVideo
|
|
||||||
el.loop = true
|
|
||||||
el.controls = false
|
|
||||||
el.muted = not Conf['Allow Sound']
|
|
||||||
el.play() if Conf['Autoplay']
|
|
||||||
naturalHeight = if post.file.isVideo then 'videoHeight' else 'naturalHeight'
|
|
||||||
UI.hover
|
UI.hover
|
||||||
root: @
|
root: @
|
||||||
el: el
|
el: el
|
||||||
latestEvent: e
|
latestEvent: e
|
||||||
endEvents: 'mouseout click'
|
endEvents: 'mouseout click'
|
||||||
asapTest: -> el[naturalHeight]
|
asapTest: -> post.file.isVideo or el.naturalHeight
|
||||||
cb: ->
|
|
||||||
el.pause() if isVideo
|
|
||||||
$.on el, 'error', ImageHover.error
|
$.on el, 'error', ImageHover.error
|
||||||
error: ->
|
error: ->
|
||||||
return unless doc.contains @
|
return unless doc.contains @
|
||||||
|
|||||||
@ -47,4 +47,4 @@ FileInfo =
|
|||||||
B: -> FileInfo.convertUnit @file.sizeInBytes, 'B'
|
B: -> FileInfo.convertUnit @file.sizeInBytes, 'B'
|
||||||
K: -> FileInfo.convertUnit @file.sizeInBytes, 'KB'
|
K: -> FileInfo.convertUnit @file.sizeInBytes, 'KB'
|
||||||
M: -> FileInfo.convertUnit @file.sizeInBytes, 'MB'
|
M: -> FileInfo.convertUnit @file.sizeInBytes, 'MB'
|
||||||
r: -> if @file.isImage or @file.isVideo then @file.dimensions else 'PDF'
|
r: -> @file.dimensions or 'PDF'
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
QR =
|
QR =
|
||||||
# Add empty mimeType to avoid errors with URLs selected in Window's file dialog.
|
|
||||||
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', 'video/webm', '']
|
|
||||||
|
|
||||||
init: ->
|
init: ->
|
||||||
@db = new DataBoard 'yourPosts'
|
@db = new DataBoard 'yourPosts'
|
||||||
@posts = []
|
@posts = []
|
||||||
@ -386,23 +383,15 @@ QR =
|
|||||||
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
|
return
|
||||||
else unless file.type in QR.mimeTypes
|
|
||||||
unless /^text/.test file.type
|
|
||||||
QR.error "#{file.name}: Unsupported file type."
|
|
||||||
return
|
|
||||||
if isSingle
|
|
||||||
post = QR.selected
|
|
||||||
else if (post = QR.posts[QR.posts.length - 1]).com
|
|
||||||
post = new QR.post()
|
|
||||||
post.pasteText file
|
|
||||||
return
|
|
||||||
if isSingle
|
if isSingle
|
||||||
post = QR.selected
|
post = QR.selected
|
||||||
else if (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()
|
||||||
post.setFile file
|
if /^text/.test file.type
|
||||||
|
post.pasteText file
|
||||||
openFileInput: (e) ->
|
else
|
||||||
|
post.setFile file
|
||||||
|
openFileInput: ->
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
if e.shiftKey and e.type is 'click'
|
if e.shiftKey and e.type is 'click'
|
||||||
return QR.selected.rmFile()
|
return QR.selected.rmFile()
|
||||||
@ -412,7 +401,6 @@ QR =
|
|||||||
return
|
return
|
||||||
return if e.target.nodeName is 'INPUT' or (e.keyCode and e.keyCode not in [32, 13]) or e.ctrlKey
|
return if e.target.nodeName is 'INPUT' or (e.keyCode and e.keyCode not in [32, 13]) or e.ctrlKey
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
QR.nodes.fileInput.click()
|
|
||||||
|
|
||||||
generatePostableThreadsList: ->
|
generatePostableThreadsList: ->
|
||||||
return unless QR.nodes
|
return unless QR.nodes
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user