Merge branch 'master' into catalog

This commit is contained in:
ccd0 2014-09-13 01:56:37 -07:00
commit 1285b3aeff
35 changed files with 769 additions and 528 deletions

View File

@ -1,3 +1,82 @@
### v1.9.2.8
*2014-09-11*
**ccd0**
- Simplify and improve thumbnail replacement / preloading. Remove the download queue (didn't work well). Drop support for non-autoplaying replaced WebM thumbnails.
### v1.9.2.7
*2014-09-10*
**ccd0**
- Quote fetching bugfix.
### v1.9.2.6
*2014-09-09*
**ccd0**
- Small bugfixes.
### v1.9.2.5
*2014-09-09*
**Worer**
- Remove mawa.re from archive list (as in v1.9.1.10).
### v1.9.2.4
*2014-09-08*
**ccd0**
- Fix thumbnail replacement / preloading loading images which are not actually on the page.
### v1.9.2.3
*2014-09-07*
**ccd0**
- Thumbnail replacement / preloading / WebM bugfixes.
- Embedded videos from mediacru.sh are no longer autoplayed and have controls.
### v1.9.2.2
*2014-09-07*
**ccd0**
- Fix bug causing missing pages from index search (as in v1.9.1.9).
- Also fix bug from v1.9.2.0 causing threads to be missing from infinite scroll.
### v1.9.2.1
*2014-09-07*
**ccd0**
- Improve reliability of thumbnail replacement / preloading by queueing downloads.
### v1.9.2.0
*2014-09-06*
Based on v1.9.1.8.
**Zixaphir**
- Implement WebM thumbnail replacement / preloading.
**ccd0**
- Pause offscreen WebM thumbnails, fix some bugs.
### v1.9.1.10
*2014-09-09*
**Worer**
- Remove mawa.re from archive list.
### v1.9.1.9
*2014-09-07*
**ccd0**
- Fix bug causing missing pages from index search.
### v1.9.1.8
*2014-09-06*
**ccd0**
- Fix bug in WebM hover/expand.
### v1.9.1.7 ### v1.9.1.7
*2014-09-05* *2014-09-05*

View File

@ -1,5 +1,5 @@
/* /*
* 4chan X - Version 1.9.1.7 * 4chan X - Version 1.9.2.8
* *
* Licensed under the MIT license. * Licensed under the MIT license.
* https://github.com/ccd0/4chan-x/blob/master/LICENSE * https://github.com/ccd0/4chan-x/blob/master/LICENSE

Binary file not shown.

View File

@ -1,6 +1,6 @@
// ==UserScript== // ==UserScript==
// @name 4chan X // @name 4chan X
// @version 1.9.1.7 // @version 1.9.2.8
// @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

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -1,6 +1,6 @@
// ==UserScript== // ==UserScript==
// @name 4chan X // @name 4chan X
// @version 1.9.1.7 // @version 1.9.2.8
// @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

Binary file not shown.

View File

@ -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/4chan-X-beta.crx' version='1.9.1.7' /> <updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.9.2.8' />
</app> </app>
</gupdate> </gupdate>

View File

@ -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/4chan-X.crx' version='1.9.1.7' /> <updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.9.2.8' />
</app> </app>
</gupdate> </gupdate>

View File

@ -3,7 +3,7 @@
"description": "Cross-browser userscript for maximum lurking on 4chan.", "description": "Cross-browser userscript for maximum lurking on 4chan.",
"meta": { "meta": {
"name": "4chan X", "name": "4chan X",
"version": "1.9.1.7", "version": "1.9.2.8",
"repo": "https://github.com/ccd0/4chan-x/", "repo": "https://github.com/ccd0/4chan-x/",
"page": "https://github.com/ccd0/4chan-x", "page": "https://github.com/ccd0/4chan-x",
"downloads": "https://ccd0.github.io/4chan-x/builds/", "downloads": "https://ccd0.github.io/4chan-x/builds/",

View File

@ -70,14 +70,4 @@
"software": "foolfuuka", "software": "foolfuuka",
"boards": ["asp", "cm", "h", "hc", "hm", "n", "p", "r", "s", "soc", "y"], "boards": ["asp", "cm", "h", "hc", "hm", "n", "p", "r", "s", "soc", "y"],
"files": ["asp", "cm", "h", "hc", "hm", "n", "p", "r", "s", "soc", "y"] "files": ["asp", "cm", "h", "hc", "hm", "n", "p", "r", "s", "soc", "y"]
}, {
"uid": 16,
"name": "maware",
"domain": "archive.mawa.re",
"http": true,
"https": false,
"software": "foolfuuka",
"boards": ["t"],
"files": ["t"],
"imagehosts": ["http://archive.mawa.re/"]
}] }]

View File

@ -151,8 +151,9 @@ Filter =
return post.file.name return post.file.name
false false
dimensions: (post) -> dimensions: (post) ->
if post.file and post.file.isImage {file} = post
return post.file.dimensions if file and (file.isImage or file.isVideo)
return file.dimensions
false false
filesize: (post) -> filesize: (post) ->
if post.file if post.file

View File

@ -173,15 +173,19 @@ Config =
] ]
'Replace GIF': [ 'Replace GIF': [
false false
'Replace thumbnail of gifs with its actual image.' 'Replace gif thumbnails with the actual image.'
]
'Replace PNG': [
false
'Replace pngs.'
] ]
'Replace JPG': [ 'Replace JPG': [
false false
'Replace jpgs.' 'Replace jpg thumbnails with the actual image.'
]
'Replace PNG': [
false
'Replace png thumbnails with the actual image.'
]
'Replace WEBM': [
false
'Replace webm thumbnails with the actual webm video. Probably will degrade browser performance ;)'
] ]
'Image Prefetching': [ 'Image Prefetching': [
false false
@ -644,7 +648,7 @@ vp-replace
] ]
'Toggle sage': [ 'Toggle sage': [
'Alt+s' 'Alt+s'
'Toggle sage in email field' 'Toggle sage in options field.'
] ]
'Submit QR': [ 'Submit QR': [
'Ctrl+Enter' 'Ctrl+Enter'

View File

@ -91,6 +91,7 @@ Get =
$.rmAll root $.rmAll root
$.add root, nodes.root $.add root, nodes.root
$.event 'PostsInserted'
fetchedPost: (req, boardID, threadID, postID, root, context) -> fetchedPost: (req, boardID, threadID, postID, root, context) ->
# In case of multiple callbacks for the same request, # In case of multiple callbacks for the same request,
# don't parse the same original post more than once. # don't parse the same original post more than once.
@ -116,6 +117,13 @@ Get =
break if post.no is postID # we found it! break if post.no is postID # we found it!
if post.no isnt postID if post.no isnt postID
# Cached requests can be stale and must be rechecked.
if req.cached
api = "//a.4cdn.org/#{boardID}/thread/#{threadID}.json"
$.cleanCache (url) -> url is api
$.cache api, ->
Get.fetchedPost @, boardID, threadID, postID, root, context
return
# The post can be deleted by the time we check a quote. # The post can be deleted by the time we check a quote.
unless Get.archivedPost boardID, postID, root, context unless Get.archivedPost boardID, postID, root, context
$.addClass root, 'warning' $.addClass root, 'warning'

View File

@ -407,6 +407,7 @@ Header =
bottom -= clientHeight - headRect.bottom + headRect.height bottom -= clientHeight - headRect.bottom + headRect.height
bottom bottom
isNodeVisible: (node) -> isNodeVisible: (node) ->
return false if d.hidden or !doc.contains node
{height} = node.getBoundingClientRect() {height} = node.getBoundingClientRect()
Header.getTopOf(node) + height >= 0 and Header.getBottomOf(node) + height >= 0 Header.getTopOf(node) + height >= 0 and Header.getBottomOf(node) + height >= 0
isHidden: -> isHidden: ->

View File

@ -98,6 +98,7 @@ Index =
$.asap (-> $('.board', doc) or d.readyState isnt 'loading'), -> $.asap (-> $('.board', doc) or d.readyState isnt 'loading'), ->
board = $ '.board' board = $ '.board'
$.replace board, Index.root $.replace board, Index.root
$.event 'PostsInserted'
# Hacks: # Hacks:
# - When removing an element from the document during page load, # - When removing an element from the document during page load,
# its ancestors will still be correctly created inside of it. # its ancestors will still be correctly created inside of it.
@ -128,7 +129,6 @@ Index =
return Index.endNotice() if pageNum > Index.pagesNum return Index.endNotice() if pageNum > Index.pagesNum
nodes = Index.buildSinglePage pageNum nodes = Index.buildSinglePage pageNum
nodes.shift() # Remove thread common with previous page
Index.buildReplies nodes if Conf['Show Replies'] Index.buildReplies nodes if Conf['Show Replies']
Index.buildStructure nodes Index.buildStructure nodes
Index.setPage pageNum Index.setPage pageNum
@ -281,7 +281,7 @@ Index =
getPagesNum: -> getPagesNum: ->
if Index.isSearching if Index.isSearching
Math.ceil (Index.sortedNodes.length / 2) / Index.threadsNumPerPage Math.ceil Index.sortedNodes.length / Index.threadsNumPerPage
else else
Index.pagesNum Index.pagesNum
getMaxPageNum: -> getMaxPageNum: ->
@ -553,6 +553,7 @@ Index =
buildStructure: (nodes) -> buildStructure: (nodes) ->
for node in nodes for node in nodes
$.add Index.root, [node, $.el 'hr'] $.add Index.root, [node, $.el 'hr']
$.event 'PostsInserted' if doc.contains Index.root
ThreadHiding.onIndexBuild nodes ThreadHiding.onIndexBuild nodes
isSearching: false isSearching: false

View File

@ -170,28 +170,31 @@ Settings =
data.Conf[newKey] = data.Conf[prevKey] if newKey data.Conf[newKey] = data.Conf[prevKey] if newKey
delete data.Conf[prevKey] delete data.Conf[prevKey]
data data
data = Settings.convertSettings data, data = convertSettings data,
# General confs # General confs
'Disable 4chan\'s extension': '' 'Disable 4chan\'s extension': ''
'Catalog Links': '' 'Remove Slug': ''
'Reply Navigation': '' 'Check for Updates': ''
'Recursive Filtering': 'Recursive Hiding'
'Reply Hiding': 'Reply Hiding Buttons'
'Thread Hiding': 'Thread Hiding Buttons'
'Show Stubs': 'Stubs' 'Show Stubs': 'Stubs'
'Image Auto-Gif': 'Auto-GIF' 'Image Auto-Gif': 'Replace GIF'
'Expand From Current': '' 'Reveal Spoilers': 'Reveal Spoiler Thumbnails'
'Unread Tab Icon': 'Unread Favicon' 'Expand From Current': 'Expand from here'
'Post in Title': 'Thread Excerpt' 'Post in Title': 'Thread Excerpt'
'Auto Hide QR': '' 'Open Reply in New Tab': 'Open Post in New Tab'
'Open Reply in New Tab': '' 'Remember QR size': 'Remember QR Size'
'Remember QR size': '' 'Remember Subject': ''
'Quote Inline': 'Quote Inlining' 'Quote Inline': 'Quote Inlining'
'Quote Preview': 'Quote Previewing' 'Quote Preview': 'Quote Previewing'
'Indicate OP quote': 'Mark OP Quotes' 'Indicate OP quote': 'Mark OP Quotes'
'Indicate You quote': 'Mark Quotes of You'
'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes' 'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes'
'Reply Hiding': 'Reply Hiding Buttons'
'Thread Hiding': 'Thread Hiding Buttons'
# filter # filter
'uniqueid': 'uniqueID' 'uniqueid': 'uniqueID'
'mod': 'capcode' 'mod': 'capcode'
'email': ''
'country': 'flag' 'country': 'flag'
'md5': 'MD5' 'md5': 'MD5'
# keybinds # keybinds
@ -200,6 +203,7 @@ Settings =
'openOptions': 'Open settings' 'openOptions': 'Open settings'
'close': 'Close' 'close': 'Close'
'spoiler': 'Spoiler tags' 'spoiler': 'Spoiler tags'
'sageru': 'Toggle sage'
'code': 'Code tags' 'code': 'Code tags'
'submit': 'Submit QR' 'submit': 'Submit QR'
'watch': 'Watch' 'watch': 'Watch'

View File

@ -89,7 +89,7 @@ a {
[hidden] { [hidden] {
display: none !important; display: none !important;
} }
hr ~ div.center:not(.ad-cnt) { hr + div.center:not(.ad-cnt):not(.topad):not(.middlead):not(.bottomad) {
display: none !important; display: none !important;
} }
.page-num { .page-num {
@ -795,6 +795,7 @@ span.hide-announcement {
/* File */ /* File */
.fnswitch:hover > .fntrunc, .fnswitch:hover > .fntrunc,
.fnswitch:not(:hover) > .fnfull, .fnswitch:not(:hover) > .fnfull,
.expanded-image > .post > .file > .fileThumb > video[data-md5],
.expanded-image > .post > .file > .fileThumb > img[data-md5] { .expanded-image > .post > .file > .fileThumb > img[data-md5] {
display: none; display: none;
} }

View File

@ -89,6 +89,7 @@ do ->
$.on req, 'load', (e) -> $.on req, 'load', (e) ->
cb.call @, e for cb in @callbacks cb.call @, e for cb in @callbacks
@evt = e @evt = e
@cached = true
delete @callbacks delete @callbacks
$.on req, 'abort error', rm $.on req, 'abort error', rm
req.callbacks = [cb] req.callbacks = [cb]

View File

@ -56,7 +56,7 @@ class Clone extends Post
@file[key] = val @file[key] = val
file = $ '.file', post file = $ '.file', post
@file.text = file.firstElementChild @file.text = file.firstElementChild
@file.thumb = $ 'img[data-md5]', file @file.thumb = $ '.fileThumb > [data-md5]', file
@file.fullImage = $ '.full-image', file @file.fullImage = $ '.full-image', file
@file.videoControls = $ '.video-controls', @file.text @file.videoControls = $ '.video-controls', @file.text
@ -72,7 +72,7 @@ class Clone extends Post
root.dataset.clone = origin.clones.push(@) - 1 root.dataset.clone = origin.clones.push(@) - 1
cloneWithoutVideo: (node) -> cloneWithoutVideo: (node) ->
if node.tagName is 'VIDEO' if node.tagName is 'VIDEO' and !node.dataset.md5 # (exception for WebM thumbnails)
[] []
else if node.nodeType is Node.ELEMENT_NODE and $ 'video', node else if node.nodeType is Node.ELEMENT_NODE and $ 'video', node
clone = node.cloneNode false clone = node.cloneNode false

View File

@ -74,7 +74,7 @@ class DataBoard
ajaxClean: (boardID) -> ajaxClean: (boardID) ->
$.cache "//a.4cdn.org/#{boardID}/threads.json", (e) => $.cache "//a.4cdn.org/#{boardID}/threads.json", (e) =>
if e.target.status isnt 200 if e.target.status isnt 200
@delete boardID if e.target.status is 404 @delete {boardID} if e.target.status is 404
return return
board = @data.boards[boardID] board = @data.boards[boardID]
threads = {} threads = {}

View File

@ -1,20 +0,0 @@
AutoGIF =
init: ->
return if g.VIEW is 'catalog' or !Conf['Auto-GIF'] or g.BOARD.ID in ['gif', 'wsg']
Post.callbacks.push
name: 'Auto-GIF'
cb: @node
node: ->
return if @isClone or @isHidden or @thread.isHidden or !@file?.isImage
{thumb, URL} = @file
return unless /gif$/.test(URL) and !/spoiler/.test thumb.src
if @file.isSpoiler
# Revealed spoilers do not have height/width set, this fixes auto-gifs dimensions.
{style} = thumb
style.maxHeight = style.maxWidth = if @isReply then '125px' else '250px'
gif = $.el 'img'
$.on gif, 'load', ->
# Replace the thumbnail once the GIF has finished loading.
thumb.src = URL
gif.src = URL

View File

@ -29,7 +29,7 @@ ImageExpand =
else if @file.isExpanded and @file.isVideo else if @file.isExpanded and @file.isVideo
ImageExpand.setupVideoCB @ ImageExpand.setupVideoCB @
ImageExpand.setupVideo @, !@origin.file.fullImage?.paused or @origin.file.wasPlaying, @file.fullImage.controls ImageExpand.setupVideo @, !@origin.file.fullImage?.paused or @origin.file.wasPlaying, @file.fullImage.controls
else if ImageExpand.on and !@isHidden and else if ImageExpand.on and !@isHidden and !@isFetchedQuote and
(Conf['Expand spoilers'] or !@file.isSpoiler) and (Conf['Expand spoilers'] or !@file.isSpoiler) and
(Conf['Expand videos'] or !@file.isVideo) (Conf['Expand videos'] or !@file.isVideo)
ImageExpand.expand @ ImageExpand.expand @
@ -70,15 +70,15 @@ ImageExpand =
playVideos: (e) -> playVideos: (e) ->
g.posts.forEach (post) -> g.posts.forEach (post) ->
return unless post.file and post.file.isVideo and post.file.isExpanded for post in [post, post.clones...] when post.file and post.file.isVideo and post.file.isExpanded
video = post.file.fullImage video = post.file.fullImage
visible = !d.hidden and Header.isNodeVisible video visible = Header.isNodeVisible video
if visible and post.file.wasPlaying if visible and post.file.wasPlaying
delete post.file.wasPlaying delete post.file.wasPlaying
video.play() video.play()
else if !visible and !video.paused else if !visible and !video.paused
post.file.wasPlaying = true post.file.wasPlaying = true
video.pause() video.pause()
return return
setFitness: -> setFitness: ->
@ -158,7 +158,7 @@ ImageExpand =
TrashQueue.remove el TrashQueue.remove el
unless file.isHovered unless file.isHovered
$.queueTask(-> el.src = el.src) if /\.gif$/.test el.src $.queueTask(-> el.src = el.src) if /\.gif$/.test el.src
el.currentTime = 0 if isVideo el.currentTime = 0 if isVideo and el.readyState >= el.HAVE_METADATA
else else
el.src = src or file.URL el.src = src or file.URL
$.after thumb, el $.after thumb, el

View File

@ -18,7 +18,7 @@ ImageHover =
el.id = 'ihover' el.id = 'ihover'
TrashQueue.remove el TrashQueue.remove el
$.queueTask(-> el.src = el.src) if /\.gif$/.test el.src $.queueTask(-> el.src = el.src) if /\.gif$/.test el.src
el.currentTime = 0 if isVideo el.currentTime = 0 if isVideo and el.readyState >= el.HAVE_METADATA
else else
file.fullImage = el = $.el (if isVideo then 'video' else 'img'), file.fullImage = el = $.el (if isVideo then 'video' else 'img'),
className: 'full-image' className: 'full-image'

View File

@ -1,48 +1,81 @@
ImageLoader = ImageLoader =
init: -> init: ->
return if g.VIEW is 'catalog' return if g.VIEW is 'catalog'
return unless Conf["Image Prefetching"] or Conf["Replace JPG"] or Conf["Replace PNG"] or Conf["Replace GIF"] return unless Conf['Image Prefetching'] or Conf['Replace JPG'] or Conf['Replace PNG'] or Conf['Replace GIF'] or Conf['Replace WEBM']
Post.callbacks.push Post.callbacks.push
name: 'Image Replace' name: 'Image Replace'
cb: @node cb: @node
Thread.callbacks.push $.on d, 'PostsInserted', ->
name: 'Image Replace' g.posts.forEach ImageLoader.prefetch
cb: @thread
return unless Conf['Image Prefetching'] and g.VIEW is 'thread' if Conf['Replace WEBM']
$.on d, 'scroll visibilitychange 4chanXInitFinished PostsInserted', ->
# Special case: Quote previews are off screen when inserted into document, but quickly moved on screen.
qpClone = $.id('qp')?.firstElementChild
g.posts.forEach (post) ->
for post in [post, post.clones...] when post.file?.videoThumb
{thumb} = post.file
if Header.isNodeVisible(thumb) or post.nodes.root is qpClone then thumb.play() else thumb.pause()
return
return unless Conf['Image Prefetching']
prefetch = $.el 'label', prefetch = $.el 'label',
<%= html('<input type="checkbox" name="prefetch"> Prefetch Images') %> <%= html('<input type="checkbox" name="prefetch"> Prefetch Images') %>
@el = prefetch.firstElementChild @el = prefetch.firstElementChild
$.on @el, 'change', @toggle $.on @el, 'change', ->
if Conf['prefetch'] = @checked
g.posts.forEach ImageLoader.prefetch
Header.menu.addEntry Header.menu.addEntry
el: prefetch el: prefetch
order: 104 order: 104
thread: ->
ImageLoader.thread = @
node: -> node: ->
return if @isClone or @isHidden or @thread.isHidden or !@file?.isImage return if @isClone or !@file
{thumb, URL} = @file ImageLoader.replaceVideo @ if Conf['Replace WEBM'] and @file.isVideo
return unless (Conf[string = "Replace #{if (type = (URL.match /\w{3}$/)[0].toUpperCase()) is 'PEG' then 'JPG' else type}"] and !/spoiler/.test thumb.src) or Conf['prefetch'] ImageLoader.prefetch @
if @file.isSpoiler
# Revealed spoilers do not have height/width set, this fixes the image's dimensions.
{style} = thumb
style.maxHeight = style.maxWidth = if @isReply then '125px' else '250px'
img = $.el 'img'
if Conf[string]
$.on img, 'load', ->
# Replace the thumbnail once the GIF has finished loading.
thumb.src = URL
img.src = URL
toggle: -> replaceVideo: (post) ->
enabled = Conf['prefetch'] = @checked {file} = post
if enabled {thumb} = file
ImageLoader.thread.posts.forEach (post) -> ImageLoader.node.call post video = $.el 'video',
return preload: 'none'
loop: true
poster: thumb.src
textContent: thumb.alt
className: thumb.className
video.dataset.md5 = thumb.dataset.md5
video.style[attr] = thumb.style[attr] for attr in ['height', 'width', 'maxHeight', 'maxWidth']
video.src = file.URL
$.on video, 'mouseover', ImageHover.mouseover if Conf['Image Hover']
$.replace thumb, video
file.thumb = video
file.videoThumb = true
prefetch: (post) ->
{file} = post
return unless file
{isImage, isVideo, thumb, URL} = file
return if file.isPrefetched or !(isImage or isVideo) or post.isHidden or post.thread.isHidden
type = if (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) is 'JPEG' then 'JPG' else match
replace = Conf["Replace #{type}"] and !/spoiler/.test thumb.src
return unless replace or Conf['prefetch']
return unless [post, post.clones...].some (clone) -> doc.contains clone.nodes.root
file.isPrefetched = true
if file.videoThumb
clone.file.thumb.preload = 'auto' for clone in post.clones
thumb.preload = 'auto'
# XXX Cloned video elements with poster in Firefox cause momentary display of image loading icon.
if !chrome?
$.on thumb, 'loadeddata', -> @removeAttribute 'poster'
return
el = $.el if isImage then 'img' else 'video'
if replace and isImage
$.on el, 'load', ->
clone.file.thumb.src = URL for clone in post.clones
thumb.src = URL
el.src = URL

View File

@ -8,5 +8,8 @@ RevealSpoilers =
node: -> node: ->
return if @isClone or !@file?.isSpoiler return if @isClone or !@file?.isSpoiler
{thumb} = @file {thumb} = @file
# Remove old width and height.
thumb.removeAttribute 'style' thumb.removeAttribute 'style'
# Enforce thumbnail size if thumbnail is replaced.
thumb.style.maxHeight = thumb.style.maxWidth = if @isReply then '125px' else '250px'
thumb.src = @file.thumbURL thumb.src = @file.thumbURL

View File

@ -295,7 +295,7 @@ Linkify =
return div.textContent = "ERROR: Not a valid filetype" unless embed return div.textContent = "ERROR: Not a valid filetype" unless embed
switch embed.type switch embed.type
when 'video/mp4', 'video/webm', 'video/ogv' when 'video/mp4', 'video/webm', 'video/ogv'
$.extend el, <%= html('<video autoplay loop><source type="video/mp4"><source type="video/webm"></video>') %> $.extend el, <%= html('<video controls loop><source type="video/mp4"><source type="video/webm"></video>') %>
for ext, i in ['mp4', 'webm'] for ext, i in ['mp4', 'webm']
el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}" el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}"
when 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg' when 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg'

View File

@ -101,6 +101,7 @@ ExpandThread =
postsRoot.push root postsRoot.push root
Main.callbackNodes Post, posts Main.callbackNodes Post, posts
$.after a, postsRoot $.after a, postsRoot
$.event 'PostsInserted'
postsCount = postsRoot.length postsCount = postsRoot.length
a.textContent = ExpandThread.text '-', postsCount, filesCount a.textContent = ExpandThread.text '-', postsCount, filesCount

View File

@ -326,6 +326,7 @@ ThreadUpdater =
$.add ThreadUpdater.root, root $.add ThreadUpdater.root, root
else else
$.add ThreadUpdater.root, root $.add ThreadUpdater.root, root
$.event 'PostsInserted'
if scroll if scroll
if Conf['Bottom Scroll'] if Conf['Bottom Scroll']

View File

@ -29,12 +29,6 @@ QR =
$.on d, '4chanXInitFinished', @initReady $.on d, '4chanXInitFinished', @initReady
if Conf['Persistent QR']
unless g.BOARD.ID is 'f' and g.VIEW is 'index'
$.on d, '4chanXInitFinished', @persist
else
$.ready @persist
Post.callbacks.push Post.callbacks.push
name: 'Quick Reply' name: 'Quick Reply'
cb: @node cb: @node
@ -94,11 +88,6 @@ QR =
node: -> node: ->
$.on $('a[title="Reply to this post"]', @nodes.info), 'click', QR.quote $.on $('a[title="Reply to this post"]', @nodes.info), 'click', QR.quote
persist: ->
return unless QR.postingIsEnabled
QR.open()
QR.hide() if Conf['Auto Hide QR'] or g.VIEW is 'catalog'
open: -> open: ->
if QR.nodes if QR.nodes
QR.nodes.el.hidden = false QR.nodes.el.hidden = false

View File

@ -160,7 +160,10 @@ QR.post = class
@filesize = $.bytesToString file.size @filesize = $.bytesToString file.size
@nodes.label.hidden = false if QR.spoiler @nodes.label.hidden = false if QR.spoiler
URL.revokeObjectURL @URL URL.revokeObjectURL @URL
@showFileData() if @ is QR.selected if @ is QR.selected
@showFileData()
else
@updateFilename()
if el if el
@setThumbnail el @setThumbnail el
else else