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
|
||||
*2014-04-04*
|
||||
|
||||
@ -21,6 +24,9 @@
|
||||
### v2.9.10
|
||||
*2014-04-02*
|
||||
|
||||
**duckness**:
|
||||
- Merge changes from Mayhem fork
|
||||
|
||||
**MayhemYDG**:
|
||||
- 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>
|
||||
|
||||
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": {
|
||||
"font-awesome": "~4.0.3",
|
||||
"grunt": "~0.4.2",
|
||||
"grunt": "~0.4.4",
|
||||
"grunt-bump": "~0.0.13",
|
||||
"grunt-concurrent": "~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-concat": "~0.3.0",
|
||||
"grunt-contrib-concat": "~0.4.0",
|
||||
"grunt-contrib-copy": "~0.5.0",
|
||||
"grunt-contrib-watch": "~0.6.0",
|
||||
"grunt-contrib-watch": "~0.6.1",
|
||||
"grunt-shell": "~0.6.4",
|
||||
"load-grunt-tasks": "~0.4.0"
|
||||
},
|
||||
|
||||
@ -149,7 +149,8 @@ Filter =
|
||||
return post.file.name
|
||||
false
|
||||
dimensions: (post) ->
|
||||
if post.file and post.file.isImage
|
||||
{file} = post
|
||||
if file and (file.isImage or file.isVideo)
|
||||
return post.file.dimensions
|
||||
false
|
||||
filesize: (post) ->
|
||||
|
||||
@ -7,8 +7,9 @@ Build =
|
||||
# OPs have a +10 characters threshold.
|
||||
# The file extension is not taken into account.
|
||||
threshold = if isReply then 30 else 40
|
||||
if filename.length - 4 > threshold
|
||||
"#{filename[...threshold - 5]}(...).#{filename[-3..]}"
|
||||
ext = filename.match(/\.[^.]+$/)[0]
|
||||
if filename.length - ext.length > threshold
|
||||
"#{filename[...threshold - 5]}(...)#{ext}"
|
||||
else
|
||||
filename
|
||||
thumbRotate: do ->
|
||||
|
||||
@ -361,6 +361,7 @@ Settings =
|
||||
sizeInBytes: 276 * 1024
|
||||
dimensions: '1280x720'
|
||||
isImage: true
|
||||
isVideo: false
|
||||
isSpoiler: true
|
||||
funk = FileInfo.createFunc @value
|
||||
@nextElementSibling.innerHTML = funk FileInfo, data
|
||||
|
||||
@ -925,7 +925,7 @@ nav a,
|
||||
.move {
|
||||
cursor: pointer;
|
||||
}
|
||||
.ihover {
|
||||
#ihover {
|
||||
position: fixed;
|
||||
max-height: 94vh;
|
||||
max-width: 75vw;
|
||||
|
||||
@ -108,7 +108,7 @@ div.center:not(.ad-cnt) {
|
||||
/* fixed, z-index */
|
||||
#overlay,
|
||||
#fourchanx-settings,
|
||||
#qp, .ihover,
|
||||
#qp, #ihover,
|
||||
#navlinks, .fixed #header-bar,
|
||||
:root.float #updater,
|
||||
:root.float #thread-stats,
|
||||
@ -124,7 +124,7 @@ div.center:not(.ad-cnt) {
|
||||
#notifications {
|
||||
z-index: 70;
|
||||
}
|
||||
#qp, .ihover {
|
||||
#qp, #ihover {
|
||||
z-index: 60;
|
||||
}
|
||||
#menu {
|
||||
@ -840,7 +840,7 @@ span.hide-announcement {
|
||||
:root.gecko.fit-width .full-image {
|
||||
width: 100%;
|
||||
}
|
||||
.ihover {
|
||||
#ihover {
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
max-height: 100%;
|
||||
|
||||
@ -116,7 +116,7 @@ class Post
|
||||
|
||||
parseFile: (that) ->
|
||||
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.
|
||||
anchor = thumb.parentNode
|
||||
fileText = fileEl.firstElementChild
|
||||
|
||||
@ -32,4 +32,3 @@ AutoGIF =
|
||||
else
|
||||
thumb.src = URL
|
||||
gif.src = URL
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ ImageExpand =
|
||||
cb: @node
|
||||
|
||||
node: ->
|
||||
return unless @file?.isImage or @file?.isVideo
|
||||
return unless @file and (@file.isImage or @file.isVideo)
|
||||
{thumb} = @file
|
||||
$.on thumb.parentNode, 'click', ImageExpand.cb.toggle
|
||||
if @isClone and $.hasClass thumb, 'expanding'
|
||||
@ -49,7 +49,7 @@ ImageExpand =
|
||||
for post in [post].concat post.clones
|
||||
{file} = post
|
||||
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 from here'] and Header.getTopOf(file.thumb) < 0)
|
||||
return
|
||||
@ -90,10 +90,10 @@ ImageExpand =
|
||||
ImageExpand.contract post
|
||||
|
||||
contract: (post) ->
|
||||
post.file.fullImage?.pause() if post.file.isVideo
|
||||
$.rmClass post.nodes.root, 'expanded-image'
|
||||
$.rmClass post.file.thumb, 'expanding'
|
||||
post.file.isExpanded = false
|
||||
post.file.fullImage.pause() if post.file.isVideo
|
||||
post.file.videoControls?.map($.rm)
|
||||
delete post.file.videoControls
|
||||
|
||||
@ -102,44 +102,41 @@ ImageExpand =
|
||||
{thumb, isVideo} = post.file
|
||||
return if post.isHidden or post.file.isExpanded or $.hasClass thumb, 'expanding'
|
||||
$.addClass thumb, 'expanding'
|
||||
naturalHeight = if isVideo then 'videoHeight' else 'naturalHeight'
|
||||
if img = post.file.fullImage
|
||||
if post.file.fullImage
|
||||
# Expand already-loaded/ing picture.
|
||||
$.addClass img, 'full-image'
|
||||
img.controls = (img.parentNode isnt thumb.parentNode)
|
||||
$.asap (-> img[naturalHeight]), ->
|
||||
$.asap (-> post.file.isVideo or post.file.fullImage.naturalHeight), ->
|
||||
ImageExpand.completeExpand post
|
||||
return
|
||||
post.file.fullImage = img = $.el (if isVideo then 'video' else 'img'),
|
||||
className: 'full-image'
|
||||
src: src or post.file.URL
|
||||
file =
|
||||
$.el (if post.file.isImage then 'img' else 'video'),
|
||||
className: 'full-image'
|
||||
src: src or post.file.URL
|
||||
post.file.fullImage = file
|
||||
if isVideo
|
||||
img.loop = true
|
||||
img.controls = Conf['Show Controls']
|
||||
$.on img, 'error', ImageExpand.error
|
||||
$.asap (-> post.file.fullImage[naturalHeight]), ->
|
||||
file.loop = true
|
||||
file.controls = Conf['Show Controls']
|
||||
$.on file, 'error', ImageExpand.error
|
||||
$.asap (-> post.file.isVideo or post.file.fullImage.naturalHeight), ->
|
||||
if isVideo
|
||||
# XXX Firefox doesn't seem to size videos correctly?
|
||||
img.style.maxHeight = img[naturalHeight] + "px"
|
||||
img.style.maxWidth = img['videoWidth'] + "px"
|
||||
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) ->
|
||||
{thumb} = post.file
|
||||
return unless $.hasClass thumb, 'expanding' # contracted before the image loaded
|
||||
post.file.isExpanded = true
|
||||
ImageExpand.setupVideo post if post.file.isVideo
|
||||
$.addClass post.nodes.root, 'expanded-image'
|
||||
$.rmClass post.file.thumb, 'expanding'
|
||||
unless post.nodes.root.parentNode
|
||||
# Image might start/finish loading before the post is inserted.
|
||||
# Don't scroll when it's expanded in a QP for example.
|
||||
$.addClass post.nodes.root, 'expanded-image'
|
||||
$.rmClass post.file.thumb, 'expanding'
|
||||
return
|
||||
{bottom} = post.nodes.root.getBoundingClientRect()
|
||||
$.queueTask ->
|
||||
$.addClass post.nodes.root, 'expanded-image'
|
||||
$.rmClass post.file.thumb, 'expanding'
|
||||
return unless bottom <= 0
|
||||
window.scrollBy 0, post.nodes.root.getBoundingClientRect().bottom - bottom
|
||||
|
||||
@ -159,9 +156,9 @@ ImageExpand =
|
||||
# drag left to contract
|
||||
file.mousedown = false
|
||||
$.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, 'mouseout', (e) ->
|
||||
$.on video, 'mouseout', (e) ->
|
||||
if file.mousedown and e.clientX <= video.getBoundingClientRect().left
|
||||
ImageExpand.contract post
|
||||
if Conf['Autoplay']
|
||||
|
||||
@ -9,37 +9,36 @@ ImageHover =
|
||||
name: 'Image Hover'
|
||||
cb: @catalogNode
|
||||
node: ->
|
||||
return unless @file?.isImage or @file?.isVideo
|
||||
return unless @file and (@file.isImage or @file.isVideo)
|
||||
$.on @file.thumb, 'mouseover', ImageHover.mouseover
|
||||
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
|
||||
mouseover: (e) ->
|
||||
post = if $.hasClass @, 'thumb'
|
||||
g.posts[@parentNode.dataset.fullID]
|
||||
else
|
||||
Get.postFromNode @
|
||||
{isVideo} = post.file
|
||||
el = $.el (if isVideo then 'video' else 'img'),
|
||||
className: 'ihover'
|
||||
src: post.file.URL
|
||||
{thumb} = post.file
|
||||
el = if post.file.isImage
|
||||
$.el 'img',
|
||||
id: 'ihover'
|
||||
src: post.file.URL
|
||||
else
|
||||
$.el 'video',
|
||||
controls: false
|
||||
id: 'ihover'
|
||||
src: post.file.URL
|
||||
autoplay: Conf['Autoplay']
|
||||
muted: !Conf['Allow Sound']
|
||||
loop: true
|
||||
$.add Header.hover, el
|
||||
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
|
||||
root: @
|
||||
el: el
|
||||
latestEvent: e
|
||||
endEvents: 'mouseout click'
|
||||
asapTest: -> el[naturalHeight]
|
||||
cb: ->
|
||||
el.pause() if isVideo
|
||||
asapTest: -> post.file.isVideo or el.naturalHeight
|
||||
$.on el, 'error', ImageHover.error
|
||||
error: ->
|
||||
return unless doc.contains @
|
||||
|
||||
@ -47,4 +47,4 @@ FileInfo =
|
||||
B: -> FileInfo.convertUnit @file.sizeInBytes, 'B'
|
||||
K: -> FileInfo.convertUnit @file.sizeInBytes, 'KB'
|
||||
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 =
|
||||
# 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: ->
|
||||
@db = new DataBoard 'yourPosts'
|
||||
@posts = []
|
||||
@ -386,23 +383,15 @@ QR =
|
||||
if file.size > max
|
||||
QR.error "#{file.name}: File too large (file: #{$.bytesToString file.size}, max: #{$.bytesToString max})."
|
||||
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
|
||||
post = QR.selected
|
||||
else if (post = QR.posts[QR.posts.length - 1]).file
|
||||
post = new QR.post()
|
||||
post.setFile file
|
||||
|
||||
openFileInput: (e) ->
|
||||
if /^text/.test file.type
|
||||
post.pasteText file
|
||||
else
|
||||
post.setFile file
|
||||
openFileInput: ->
|
||||
e.stopPropagation()
|
||||
if e.shiftKey and e.type is 'click'
|
||||
return QR.selected.rmFile()
|
||||
@ -412,7 +401,6 @@ QR =
|
||||
return
|
||||
return if e.target.nodeName is 'INPUT' or (e.keyCode and e.keyCode not in [32, 13]) or e.ctrlKey
|
||||
e.preventDefault()
|
||||
QR.nodes.fileInput.click()
|
||||
|
||||
generatePostableThreadsList: ->
|
||||
return unless QR.nodes
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user