diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fbc53a17..432fc941e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ - Clicking on the border of the Header will not toggle `Header auto-hide` anymore. You can still change the setting in the Header menu → Header. - Bugfixes +- WebM support fixes. **Vampiricwulf** - Flash embedding and other Flash features. @@ -62,6 +63,7 @@ - Improved Linkifier link detection. - Fixed an issue with Thread Updater intervals not saving correctly. - Many spiffy performance, state awareness, and sanity improvements to JSON Navigation. +- Reload captcha if there are posts in the queue. ### v1.5.2 *2014-04-04* diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index a8d90ee80..9758a1b0b 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -3610,10 +3610,11 @@ gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif', spoilerRange: {}, shortFilename: function(filename, isReply) { - var threshold; + var ext, threshold; threshold = isReply ? 30 : 40; - if (filename.length - 4 > threshold) { - return "" + filename.slice(0, threshold - 5) + "(...)." + filename.slice(-3); + ext = filename.match(/\.[^.]+$/)[0]; + if (filename.length - ext.length > threshold) { + return "" + filename.slice(0, threshold - 5) + "(...)" + ext; } else { return filename; } @@ -4780,7 +4781,9 @@ return false; }, dimensions: function(post) { - if (post.file && post.file.isImage) { + var file; + file = post.file; + if (file && (file.isImage || file.isVideo)) { return post.file.dimensions; } return false; @@ -5933,7 +5936,6 @@ }; QR = { - mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', 'video/webm', ''], init: function() { var sc; if (!Conf['Quick Reply']) { @@ -6121,6 +6123,7 @@ } if (QR.captcha.isEnabled && /captcha|verification/i.test(el.textContent)) { QR.captcha.nodes.input.focus(); + QR.captcha.setup(); if (Conf['Captcha Warning Notifications'] && !d.hidden) { QR.notify(el); } else { @@ -6394,29 +6397,21 @@ } }, handleFile: function(file, isSingle, max) { - var post, _ref; + var post; if (file.size > max) { QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ")."); return; - } else if (_ref = file.type, __indexOf.call(QR.mimeTypes, _ref) < 0) { - if (!/^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(); } - return post.setFile(file); + if (/^text/.test(file.type)) { + return post.pasteText(file); + } else { + return post.setFile(file); + } }, openFileInput: function(e) { var _ref; @@ -7252,6 +7247,9 @@ $.rmClass(QR.nodes.el, 'dump'); } else if (this === QR.selected) { (QR.posts[index - 1] || QR.posts[index + 1]).select(); + if (QR.captcha.isEnabled) { + QR.captcha.setup(); + } } QR.posts.splice(index, 1); return QR.status(); @@ -7992,7 +7990,7 @@ if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) { return; } - if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { + if (ImageExpand.on && !post.isHidden && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { return; } $.queueTask(func, post); @@ -11618,11 +11616,7 @@ return FileInfo.convertUnit(this.file.sizeInBytes, 'MB'); }, r: function() { - if (this.file.isImage || this.file.isVideo) { - return this.file.dimensions; - } else { - return 'PDF'; - } + return this.file.dimensions || 'PDF'; } } }; @@ -13353,6 +13347,7 @@ sizeInBytes: 276 * 1024, dimensions: '1280x720', isImage: true, + isVideo: false, isSpoiler: true } }; diff --git a/builds/crx/script.js b/builds/crx/script.js index 3045f0570..79d3f4669 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -3671,10 +3671,11 @@ gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif', spoilerRange: {}, shortFilename: function(filename, isReply) { - var threshold; + var ext, threshold; threshold = isReply ? 30 : 40; - if (filename.length - 4 > threshold) { - return "" + filename.slice(0, threshold - 5) + "(...)." + filename.slice(-3); + ext = filename.match(/\.[^.]+$/)[0]; + if (filename.length - ext.length > threshold) { + return "" + filename.slice(0, threshold - 5) + "(...)" + ext; } else { return filename; } @@ -4834,7 +4835,9 @@ return false; }, dimensions: function(post) { - if (post.file && post.file.isImage) { + var file; + file = post.file; + if (file && (file.isImage || file.isVideo)) { return post.file.dimensions; } return false; @@ -5987,7 +5990,6 @@ }; QR = { - mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', 'video/webm', ''], init: function() { var sc; if (!Conf['Quick Reply']) { @@ -6176,6 +6178,7 @@ } if (QR.captcha.isEnabled && /captcha|verification/i.test(el.textContent)) { QR.captcha.nodes.input.focus(); + QR.captcha.setup(); if (Conf['Captcha Warning Notifications'] && !d.hidden) { QR.notify(el); } else { @@ -6450,29 +6453,21 @@ } }, handleFile: function(file, isSingle, max) { - var post, _ref; + var post; if (file.size > max) { QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ")."); return; - } else if (_ref = file.type, __indexOf.call(QR.mimeTypes, _ref) < 0) { - if (!/^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(); } - return post.setFile(file); + if (/^text/.test(file.type)) { + return post.pasteText(file); + } else { + return post.setFile(file); + } }, openFileInput: function(e) { var _ref; @@ -7291,6 +7286,9 @@ $.rmClass(QR.nodes.el, 'dump'); } else if (this === QR.selected) { (QR.posts[index - 1] || QR.posts[index + 1]).select(); + if (QR.captcha.isEnabled) { + QR.captcha.setup(); + } } QR.posts.splice(index, 1); return QR.status(); @@ -8031,7 +8029,7 @@ if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) { return; } - if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { + if (ImageExpand.on && !post.isHidden && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { return; } $.queueTask(func, post); @@ -11634,11 +11632,7 @@ return FileInfo.convertUnit(this.file.sizeInBytes, 'MB'); }, r: function() { - if (this.file.isImage || this.file.isVideo) { - return this.file.dimensions; - } else { - return 'PDF'; - } + return this.file.dimensions || 'PDF'; } } }; @@ -13372,6 +13366,7 @@ sizeInBytes: 276 * 1024, dimensions: '1280x720', isImage: true, + isVideo: false, isSpoiler: true } }; diff --git a/package.json b/package.json index 9e265ef0f..587b7a9bd 100755 --- a/package.json +++ b/package.json @@ -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" }, diff --git a/src/Filtering/Filter.coffee b/src/Filtering/Filter.coffee index 044b6763d..1805f4a34 100755 --- a/src/Filtering/Filter.coffee +++ b/src/Filtering/Filter.coffee @@ -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) -> diff --git a/src/General/Build.coffee b/src/General/Build.coffee index be0a55576..af75f9dfb 100755 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -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 -> diff --git a/src/General/Settings.coffee b/src/General/Settings.coffee index 951618384..291cfc1c3 100755 --- a/src/General/Settings.coffee +++ b/src/General/Settings.coffee @@ -388,6 +388,7 @@ Settings = sizeInBytes: 276 * 1024 dimensions: '1280x720' isImage: true + isVideo: false isSpoiler: true funk = FileInfo.createFunc @value @nextElementSibling.innerHTML = funk FileInfo, data diff --git a/src/General/lib/post.class b/src/General/lib/post.class index fbfacca86..3fac4c96e 100755 --- a/src/General/lib/post.class +++ b/src/General/lib/post.class @@ -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 diff --git a/src/Images/AutoGIF.coffee b/src/Images/AutoGIF.coffee index c47a388bb..70acc351c 100644 --- a/src/Images/AutoGIF.coffee +++ b/src/Images/AutoGIF.coffee @@ -32,4 +32,3 @@ AutoGIF = else thumb.src = URL gif.src = URL - diff --git a/src/Images/ImageExpand.coffee b/src/Images/ImageExpand.coffee index 1668cbeac..b2d6141e8 100755 --- a/src/Images/ImageExpand.coffee +++ b/src/Images/ImageExpand.coffee @@ -46,7 +46,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 diff --git a/src/Miscellaneous/FileInfo.coffee b/src/Miscellaneous/FileInfo.coffee index ee324e59e..c94bb41bd 100755 --- a/src/Miscellaneous/FileInfo.coffee +++ b/src/Miscellaneous/FileInfo.coffee @@ -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' diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 1300df978..a4ea8ca58 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -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: -> return if !Conf['Quick Reply'] @@ -147,6 +144,7 @@ QR = if QR.captcha.isEnabled and /captcha|verification/i.test el.textContent # Focus the captcha input on captcha error. QR.captcha.nodes.input.focus() + QR.captcha.setup() if Conf['Captcha Warning Notifications'] and !d.hidden QR.notify el else @@ -390,22 +388,14 @@ 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 - + if /^text/.test file.type + post.pasteText file + else + post.setFile file openFileInput: (e) -> e.stopPropagation() if e.shiftKey and e.type is 'click' diff --git a/src/Posting/QR.post.coffee b/src/Posting/QR.post.coffee index 6e6daa84a..0e2d2d320 100644 --- a/src/Posting/QR.post.coffee +++ b/src/Posting/QR.post.coffee @@ -80,6 +80,8 @@ QR.post = class $.rmClass QR.nodes.el, 'dump' else if @ is QR.selected (QR.posts[index-1] or QR.posts[index+1]).select() + if QR.captcha.isEnabled + QR.captcha.setup() QR.posts.splice index, 1 QR.status() delete: ->