Merge tag 'beta' into unreadcount

4chan X v1.8.7.

Conflicts:
	CHANGELOG.md
	LICENSE
	builds/4chan-X-beta.crx
	builds/4chan-X-beta.meta.js
	builds/4chan-X-beta.user.js
	builds/4chan-X-noupdate.crx
	builds/4chan-X-noupdate.user.js
	builds/4chan-X.crx
	builds/4chan-X.meta.js
	builds/4chan-X.user.js
	builds/4chan-X.zip
	builds/updates-beta.xml
	builds/updates.xml
	package.json
This commit is contained in:
ccd0 2014-07-23 07:27:41 -07:00
commit 8a86bb9835
36 changed files with 474 additions and 381 deletions

View File

@ -1,3 +1,21 @@
**ccd0**
- Fix unread count updating bug in Firefox as in v1.8.6.2.
### v1.8.7
*2014-07-20*
Based on v1.8.6.1.
**ccd0**
- Various bugfixes.
**MayhemYDG**
- Improvements to Chrom* storage API.
**Zixaphir**
- Add gallery option `Scroll to Post`: Scrolls to the post containing the currently active image.
- Gallery now loops.
### v1.8.6.2
*2014-07-23*
@ -67,7 +85,6 @@
- Begin making available a version of the script with the updater disabled.
- The removal of slugs from the URL when you open a thread is now optional, and can be disabled by unchecking `Normalize URL`.
- The boards and file extensions for which a Sauce link is displayed can now be controlled by adding `;boards:[list]` and `types:[list]` respectively.
- Restrict Sauce links to `http` and `https` to prevent malicious script installation.
- Although usually not needed, `%%` can be used in format specifiers to write a literal `%`.
- Various bugfixes.
@ -647,7 +664,7 @@ Remove /v/ from stable Foolz archive.
**Spittie**
- Check image dimension before uploading
![Check image dimension](src/General/img/changelog/1.4.1.png)
![Check image dimension](img/1.4.1.png)
- Bug fixes
- Update archives
@ -695,7 +712,7 @@ Remove /v/ from stable Foolz archive.
**Spittie**
- Upload images directly from urls
![Upload from url](src/General/img/changelog/1.3.6.gif)
![Upload from url](img/1.3.6.gif)
- Add gfycat.com embedding
- Replace some icons with fontawesome
- Add Metro favicons (lel)
@ -771,7 +788,7 @@ Remove /v/ from stable Foolz archive.
- The last index refresh timer will now indicate the last time the index changed from 4chan's side, instead of the last time you refreshed the index.
- You can now refresh the index page you are on with the refresh shortcut in the header bar or the same keybind for refreshing threads.
- You can now switch between paged and all-threads index modes via the "Index Navigation" header sub-menu (note that this replaces infinite scrolling):<br>
![index navigation](src/General/img/changelog/1.2.46.png)
![index navigation](img/1.2.46.png)
- Threads in the index can now be sorted by:
<ul>
<li> Bump order
@ -881,7 +898,7 @@ Remove /v/ from stable Foolz archive.
**Zixaphir**:
- Fix an issue with the file dialog randomly opening multiple times (with seaweedchan)
![Gallery](src/General/img/changelog/2.3.6.png)
![Gallery](img/2.3.6.png)
- Add new feature: `Gallery`.
* Opens images in a lightweight Gallery script.
* If enabled while Image Expansion is disabled, will takeover as the default action when images are clicked.
@ -932,7 +949,7 @@ Remove /v/ from stable Foolz archive.
**seaweedchan**:
![Board title editing in action](src/General/img/changelog/1.2.31.png)
![Board title editing in action](img/1.2.31.png)
- Ported `Custom Board Titles` feature from Appchan X (with Zixaphir)
- This allows you to edit the board title and subtitle in real-time by ctrl+clicking them
@ -963,7 +980,7 @@ Remove /v/ from stable Foolz archive.
**MayhemYDG**:
![New thread watcher](src/General/img/changelog/1.2.28.png)
![New thread watcher](img/1.2.28.png)
- Greatly improved thread watcher
- Added submenu with ability to prune 404'd threads, filter by current board, etc
@ -978,7 +995,7 @@ Remove /v/ from stable Foolz archive.
**Zixaphir**:
![Linkifier in action](src/General/img/changelog/1.2.28-2.png)
![Linkifier in action](img/1.2.28-2.png)
- Drastically improved the accuracy and quality of the linkifier (with seaweedchan)
- Removed `Allow False Positives` option due to the accuracy of the new linkifier regex
@ -1220,7 +1237,7 @@ Remove /v/ from stable Foolz archive.
**seaweedchan**:
- Small bug fixes
## v1.2.0 - "Youmu" ![Youmu](src/General/img/changelog/1.2.0.png)
## v1.2.0 - "Youmu" ![Youmu](img/1.2.0.png)
*2013-05-10*
**MayhemYDG**:
@ -1252,7 +1269,7 @@ Remove /v/ from stable Foolz archive.
- QR with 4chan Pass made a little wider
- Styling changes for spoiler label, also added `.has-spoiler` class for QR
![QR styling changes](src/General/img/changelog/1.1.18.png)
![QR styling changes](img/1.1.18.png)
### v1.1.17
*2013-05-08*

View File

@ -180,16 +180,6 @@ module.exports = (grunt) ->
pkg = grunt.config 'pkg'
pkg.type = type
grunt.config 'pkg', pkg
if type is 'crx'
pkg.align = '-webkit-align'
pkg.justify = '-webkit-justify-content'
pkg.transform = '-webkit-transform'
else
pkg.align = 'align'
pkg.justify = 'justify-content'
pkg.transform = 'transform'
grunt.log.ok 'pkg.type = %s', type
grunt.registerTask 'set-channel', 'Set the update channel', (channel) ->

View File

@ -1,5 +1,5 @@
/*
* 4chan X - Version 1.8.6.2 - 2014-07-23
* 4chan X - Version 1.8.7 - 2014-07-20
*
* Licensed under the MIT license.
* https://github.com/ccd0/4chan-x/blob/master/LICENSE

View File

@ -6,7 +6,10 @@ https://github.com/Nebukazar/OneeChan
## [Install](https://ccd0.github.io/4chan-x/builds/4chan-X.user.js) (Firefox)
Install [Greasemonkey](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/), then click the link above to install.
**Note**: The combination of Firefox 29 and Greasemonkey 2.0 may cause 4chan X not to work.
You may want to try the [Greasemonkey 2.1 beta](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/versions/2.1beta1), which fixes bugs in 2.0 that can prevent 4chan X from updating[[1]](https://github.com/greasemonkey/greasemonkey/issues/1938) or, in some versions of Firefox, break posting images from URLs and downloading with the original filename[[2]](https://github.com/greasemonkey/greasemonkey/issues/1937).
### Known issues
The combination of Firefox 29 and Greasemonkey 2.0 may cause 4chan X not to work.
Try [upgrading Firefox](http://www.mozilla.org/en-US/firefox/new/) to version 30 or higher.
Alternatively, you can downgrade to [Greasemonkey 1.15](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/versions/#version-1.15) and turn off automatic updates for Greasemonkey ([see pic](https://raw.githubusercontent.com/ccd0/4chan-x/master/img/2014-07-12_16-19-32.png)).
@ -16,6 +19,9 @@ This should also work for non-Windows/dev/canary Chrome and Chromium-based versi
**Note**: The stable and beta releases of Chrome on Windows will disable extensions not installed from the Chrome store, so users will need to install 4chan X from [here](https://chrome.google.com/webstore/detail/4chan-x/ohnjgmpcibpbafdlkimncjhflgedgpam).
### Known issues
Some recent versions of Chromium/Chrome (starting at 38.0.2085.0) suffer from a [bug](https://crbug.com/393686) that prevents extensions from making HTTP requests in the usual way. This breaks, among other things, thread updating, quick reply, and, when `JSON Navigation` is enabled, the thread index. Until this is fixed, try another version or a different browser.
## Other browsers
This fork of 4chan X is not guaranteed to work correctly in other browsers, but you are welcome to try your luck. Pull requests to fix the bugs you will likely find are always welcome.
@ -32,7 +38,7 @@ New features and non-urgent bugfixes are released on the beta channel for furthe
- [Firefox version](https://ccd0.github.io/4chan-x/builds/4chan-X-beta.user.js)
- [Chromium version](https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx)
## [Frequently Asked Questions](https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions)
## [Reporting Bugs and Contributing](https://github.com/ccd0/4chan-x/blob/master/CONTRIBUTING.md)
## More information
### [Frequently Asked Questions](https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions)
### [Reporting Bugs and Contributing](https://github.com/ccd0/4chan-x/blob/master/CONTRIBUTING.md)

Binary file not shown.

View File

@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan X
// @version 1.8.6.2
// @version 1.8.7
// @minGMVer 1.14
// @minFFVer 26
// @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==
// @name 4chan X
// @version 1.8.6.2
// @version 1.8.7
// @minGMVer 1.14
// @minFFVer 26
// @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'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.8.6.2' />
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.8.7' />
</app>
</gupdate>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.8.6.2' />
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.8.7' />
</app>
</gupdate>

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 355 KiB

After

Width:  |  Height:  |  Size: 355 KiB

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -1,6 +1,6 @@
{
"name": "4chan-X",
"version": "1.8.6.2",
"version": "1.8.7",
"description": "Cross-browser userscript for maximum lurking on 4chan.",
"meta": {
"name": "4chan X",

View File

@ -448,13 +448,15 @@ Config =
'Hide Thumbnails': [
false
]
# Fit Width =/= Fit width
'Fit Width': [
'Fit Width': [ # 'Fit width' (lowercase W) belongs to Image Expansion. Engine limitations, heh.
true
]
'Fit Height': [
true
]
'Scroll to Post': [
true
]
'Slide Delay': [
5.0
]

View File

@ -360,7 +360,7 @@ Header =
editCustomNav: ->
Settings.open 'Advanced'
settings = $.id 'fourchanx-settings'
$('input[name=boardnav]', settings).focus()
$('textarea[name=boardnav]', settings).focus()
hashScroll: ->
hash = @location.hash[1..]

View File

@ -147,6 +147,7 @@ Index =
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
switch e.target.nodeName
when 'BUTTON'
e.target.blur()
a = e.target.parentNode
when 'A'
a = e.target

View File

@ -35,7 +35,7 @@ Main =
Conf['CachedTitles'] = []
$.get Conf, (items) ->
$.extend Conf, items
$.asap (-> doc = d.documentElement), Main.initFeatures
Main.initFeatures()
$.on d, '4chanMainInit', Main.initStyle
@ -85,7 +85,7 @@ Main =
return if !Main.isThisPageLegit() or $.hasClass doc, 'fourchan-x'
# disable the mobile layout
$('link[href*=mobile]', d.head)?.disabled = true
$.addClass doc, 'fourchan-x', 'seaweedchan', g.VIEW, '<% if (type === 'crx') { %>blink<% } else { %>gecko<% } %>'
$.addClass doc, 'fourchan-x', 'seaweedchan', g.VIEW, if chrome? then 'blink' else 'gecko'
$.addStyle Main.css
Main.setClass()
@ -335,4 +335,4 @@ Main =
<% } %>
]
Main.init()
$.asap (-> (doc = d.documentElement) and d.head), Main.init

View File

@ -313,9 +313,9 @@ Settings =
interval.value = Conf['Interval']
customCSS.checked = Conf['Custom CSS']
inputs['usercss'].disabled = !Conf['Custom CSS']
$.on interval, 'change', ThreadUpdater.cb.interval
$.on customCSS, 'change', Settings.togglecss
$.on $.id('apply-css'), 'click', Settings.usercss
$.on interval, 'change', ThreadUpdater.cb.interval
$.on customCSS, 'change', Settings.togglecss
$.on $('#apply-css', section), 'click', Settings.usercss
archBoards = {}
for {name, boards, files, software, withCredentials} in Redirect.archives
@ -357,7 +357,7 @@ Settings =
boardSelect = $('#archive-board-select', section)
$.add boardSelect, boardOptions
table = $.id 'archive-table'
table = $('#archive-table', section)
$.on boardSelect, 'change', ->
$('tbody > :not([hidden])', table).hidden = true
$("tbody > .#{@value}", table).hidden = false

View File

@ -849,7 +849,9 @@ span.hide-announcement {
}
.persona {
width: 100%;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
#dump-button {
@ -869,6 +871,7 @@ span.hide-announcement {
opacity: 0.6;
}
.persona .field {
-webkit-flex: 1;
flex: 1;
width: 0;
}
@ -1279,22 +1282,32 @@ div.boardTitle {
left: 0;
right: 0;
z-index: 30;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
background: rgba(0,0,0,0.7);
}
.gal-viewport {
display: -webkit-flex;
display: flex;
<%= align %>-items: stretch;
-webkit-align-items: stretch;
align-items: stretch;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
}
.gal-thumbnails {
-webkit-flex: 0 0 150px;
flex: 0 0 150px;
overflow-y: auto;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
<%= align %>-items: stretch;
-webkit-align-items: stretch;
align-items: stretch;
text-align: center;
background: rgba(0,0,0,.5);
border-left: 1px solid #222;
@ -1309,6 +1322,7 @@ div.boardTitle {
width: auto;
}
.gal-thumb {
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
padding: 3px;
line-height: 0;
@ -1327,6 +1341,7 @@ div.boardTitle {
}
.gal-prev,
.gal-next {
-webkit-flex: 0 0 20px;
flex: 0 0 20px;
position: relative;
cursor: pointer;
@ -1341,7 +1356,8 @@ div.boardTitle {
.gal-next::after {
position: absolute;
top: 48.6%;
<%= transform %>: translateY(-50%)
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
display: inline-block;
border-top: 11px solid transparent;
border-bottom: 11px solid transparent;
@ -1357,10 +1373,14 @@ div.boardTitle {
}
.gal-image {
order: 1;
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
display: -webkit-flex;
display: flex;
<%= align %>-items: flex-start;
<%= justify %>: space-around;
-webkit-align-items: flex-start;
align-items: flex-start;
-webkit-justify-content: space-around;
justify-content: space-around;
overflow: hidden;
/* Flex > Non-Flex child max-width and overflow fix (Firefox only?) */
width: 1%;

View File

@ -42,11 +42,24 @@ $.ajax = do ->
# With the `If-Modified-Since` header we only receive the HTTP headers and no body for 304 responses.
# This saves a lot of bandwidth and CPU time for both the users and the servers.
lastModified = {}
blockedURLs = {}
blockedError = (url) ->
return if blockedURLs[url]
blockedURLs[url] = true
h_message = '<%= meta.name %> was blocked from loading the following URL:<br><span></span><br>'
h_message += '[<a href="<%= meta.faq %>#why-was-4chan-x-blocked-from-loading-a-url" target="_blank">More info</a>]'
message = $.el 'div', innerHTML: h_message
$('span', message).textContent = (if /^\/\//.test url then location.protocol else '') + url
new Notice 'error', message, 30, -> delete blockedURLs[url]
(url, options, extra={}) ->
{type, whenModified, upCallbacks, form} = extra
r = new XMLHttpRequest()
type or= form and 'post' or 'get'
r.open type, url, true
try
r.open type, url, true
catch err
blockedError url
return options.onerror?()
if whenModified
r.setRequestHeader 'If-Modified-Since', lastModified[url] if url of lastModified
$.on r, 'load', -> lastModified[url] = r.getResponseHeader 'Last-Modified'
@ -275,9 +288,6 @@ $.sync = do ->
cb changes[key].newValue, key
return
(key, cb) -> $.syncing[key] = cb
$.desync = (key) -> delete $.syncing[key]
$.localKeys = [
# filters
'name',
@ -295,85 +305,99 @@ $.localKeys = [
# custom css
'usercss'
]
# https://developer.chrome.com/extensions/storage.html
$.delete = (keys) ->
chrome.storage.sync.remove keys
$.get = (key, val, cb) ->
if typeof cb is 'function'
items = $.item key, val
else
items = key
cb = val
localItems = null
syncItems = null
for key, val of items
if key in $.localKeys
(localItems or= {})[key] = val
else
(syncItems or= {})[key] = val
count = 0
done = (item) ->
if chrome.runtime.lastError
c.error chrome.runtime.lastError.message
$.extend items, item
cb items unless --count
if localItems
count++
chrome.storage.local.get localItems, done
if syncItems
count++
chrome.storage.sync.get syncItems, done
$.set = do ->
do ->
items =
sync: {}
local: {}
timeout = {}
sync: {}
$.delete = (keys) ->
if typeof keys is 'string'
keys = [keys]
local = []
sync = []
for key in keys
if key in $.localKeys
local.push key
delete items.local[key]
else
sync.push key
delete items.sync[key]
chrome.storage.local.remove local
chrome.storage.sync.remove sync
$.get = (key, val, cb) ->
if typeof cb is 'function'
data = $.item key, val
else
data = key
cb = val
localItems = null
syncItems = null
for key, val of data
if key in $.localKeys
(localItems or= {})[key] = val
else
(syncItems or= {})[key] = val
count = 0
done = (result) ->
if chrome.runtime.lastError
c.error chrome.runtime.lastError.message
$.extend data, result
cb data unless --count
if localItems
count++
chrome.storage.local.get localItems, done
if syncItems
count++
chrome.storage.sync.get syncItems, done
timeout = {}
setArea = (area) ->
data = items[area]
return if !Object.keys(data).length or timeout[area]
items[area] = {}
return if !Object.keys(data).length or timeout[area] > Date.now()
chrome.storage[area].set data, ->
if chrome.runtime.lastError
c.error chrome.runtime.lastError.message
for key, val of data when key not of items[area]
if area is 'sync' and chrome.storage.sync.QUOTA_BYTES_PER_ITEM < JSON.stringify(val).length + key.length
c.error chrome.runtime.lastError.message, key, val
continue
items[area][key] = val
timeout[area] = setTimeout setArea, $.MINUTE, area
setTimeout setArea, $.MINUTE, area
timeout[area] = Date.now() + $.MINUTE
return
delete timeout[area]
items[area] = {}
setAll = $.debounce $.SECOND, ->
for key in $.localKeys
if key of items.sync
items.local[key] = items.sync[key]
delete items.sync[key]
try
setArea 'local'
setArea 'sync'
catch err
c.error err.stack
setSync = $.debounce $.SECOND, ->
setArea 'sync'
(key, val) ->
$.set = (key, val) ->
if typeof key is 'string'
items.sync[key] = val
else
$.extend items.sync, key
setAll()
$.clear = (cb) ->
count = 2
done = ->
if chrome.runtime.lastError
c.error chrome.runtime.lastError.message
return
cb?() unless --count
chrome.storage.local.clear done
chrome.storage.sync.clear done
for key in $.localKeys when key of items.sync
items.local[key] = items.sync[key]
delete items.sync[key]
setArea 'local'
setSync()
$.clear = (cb) ->
items.local = {}
items.sync = {}
count = 2
done = ->
if chrome.runtime.lastError
c.error chrome.runtime.lastError.message
return
cb?() unless --count
chrome.storage.local.clear done
chrome.storage.sync.clear done
<% } else { %>
# http://wiki.greasespot.net/Main_Page
@ -383,8 +407,6 @@ $.sync = do ->
cb JSON.parse(newValue), key
(key, cb) -> $.syncing[g.NAMESPACE + key] = cb
$.desync = (key) -> delete $.syncing[g.NAMESPACE + key]
$.delete = (keys) ->
unless keys instanceof Array
keys = [keys]

View File

@ -1,5 +1,5 @@
class Notice
constructor: (type, content, @timeout) ->
constructor: (type, content, @timeout, @onclose) ->
@el = $.el 'div',
innerHTML: '<a href="javascript:;" class="close fa fa-times" title="Close"></a><div class="message"></div>'
@el.style.opacity = 0
@ -27,3 +27,4 @@ class Notice
close: =>
$.off d, 'visibilitychange', @add
$.rm @el
@onclose?()

View File

@ -77,7 +77,7 @@ Gallery =
nodes.current.parentElement.scrollTop = 0
Gallery.cb.open.call if image
$ "[href='#{image.href.replace /https?:/, ''}']", nodes.thumbs
$("[href='#{image.href}']", nodes.thumbs) or Gallery.images[0]
else
Gallery.images[0]
@ -86,6 +86,7 @@ Gallery =
generateThumb: (file) ->
post = Get.postFromNode file
return if post.isClone or post.isHidden
return unless post.file and (post.file.isImage or post.file.isVideo or Conf['PDF in Gallery'])
return if Gallery.fullIDs[post.fullID]
Gallery.fullIDs[post.fullID] = true
@ -137,7 +138,9 @@ Gallery =
{nodes} = Gallery
{name} = nodes
slideshow = Gallery.slideshow and +@dataset.id > +nodes.current.dataset.id
oldID = +nodes.current.dataset.id
newID = +@dataset.id
slideshow = Gallery.slideshow and (newID > oldID or (oldID is Gallery.images.length-1 and newID is 0))
$.rmClass el, 'gal-highlight' if el = $ '.gal-highlight', nodes.thumbs
$.addClass @, 'gal-highlight'
@ -162,6 +165,10 @@ Gallery =
nodes.next.focus()
Gallery.cb[if slideshow then 'setupTimer' else 'stop']()
# Scroll to post
if Conf['Scroll to Post'] and post = (post = g.posts[file.dataset.post])?.nodes.root
Header.scrollTo post
# Center selected thumbnail
nodes.thumbs.scrollTop = @offsetTop + @offsetHeight/2 - nodes.thumbs.clientHeight/2
@ -199,8 +206,14 @@ Gallery =
if postObj.filedeleted
post.kill true
prev: -> Gallery.cb.open.call Gallery.images[+Gallery.nodes.current.dataset.id - 1]
next: -> Gallery.cb.open.call Gallery.images[+Gallery.nodes.current.dataset.id + 1]
prev: ->
Gallery.cb.open.call(
Gallery.images[+Gallery.nodes.current.dataset.id - 1] or Gallery.images[Gallery.images.length - 1]
)
next: ->
Gallery.cb.open.call(
Gallery.images[+Gallery.nodes.current.dataset.id + 1] or Gallery.images[0]
)
enterKey: -> if Gallery.nodes.current.paused then Gallery.nodes.current.play() else Gallery.cb.next()
click: -> Gallery.cb[if Gallery.nodes.current.controls then 'stop' else 'enterKey']()
toggle: -> (if Gallery.nodes then Gallery.cb.close else Gallery.build)()
@ -223,7 +236,6 @@ Gallery =
{current} = Gallery.nodes
isVideo = current.nodeName is 'VIDEO'
Video.start current if isVideo
return Gallery.cb.stop() if !Gallery.images[+Gallery.nodes.current.dataset.id + 1]
if (if isVideo then current.readyState > 4 else current.complete) or current.nodeName is 'IFRAME'
Gallery.cb.startTimer()
else
@ -291,7 +303,7 @@ Gallery =
el: label
createSubEntries: ->
subEntries = ['Hide Thumbnails', 'Fit Width', 'Fit Height'].map Gallery.menu.createSubEntry
subEntries = ['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Scroll to Post'].map Gallery.menu.createSubEntry
delayLabel = $.el 'label', innerHTML: 'Slide Delay: <input type="number" name="Slide Delay" min="0" step="any" class="field">'
delayInput = delayLabel.firstElementChild

View File

@ -10,22 +10,19 @@ ImageHover =
$.on @file.thumb, 'mouseover', ImageHover.mouseover
mouseover: (e) ->
post = Get.postFromNode @
{isVideo} = post.file
if post.file.fullImage
el = post.file.fullImage
{file} = post
{isVideo} = file
if el = file.fullImage
el.id = 'ihover'
TrashQueue.remove el
else
el = $.el (if isVideo then 'video' else 'img'),
file.fullImage = el = $.el (if isVideo then 'video' else 'img'),
className: 'full-image'
src: post.file.URL
post.file.fullImage = el
{thumb} = post.file
if d.body.contains thumb
$.after thumb, el unless el is thumb.nextSibling
else
$.add Header.hover, el if el.parentNode isnt Header.hover
el.id = 'ihover'
el.dataset.fullID = post.fullID
id: 'ihover'
el.dataset.fullID = post.fullID
$.on el, 'error', ImageHover.error
el.src = file.URL
$.after file.thumb, el
if isVideo
el.loop = true
el.controls = false
@ -35,7 +32,7 @@ ImageHover =
el: el
latestEvent: e
endEvents: 'mouseout click'
asapTest: -> (if isVideo then el.videoHeight else el.naturalHeight)
asapTest: -> (if isVideo then el.readyState >= el.HAVE_CURRENT_DATA else el.naturalHeight)
noRemove: true
cb: ->
$.off el, 'error', ImageHover.error
@ -43,7 +40,6 @@ ImageHover =
el.pause()
TrashQueue.add el, post
el.removeAttribute 'id'
$.on el, 'error', ImageHover.error
error: ->
return unless doc.contains @
post = g.posts[@dataset.fullID]

View File

@ -44,7 +44,6 @@ Sauce =
a = Sauce.link.cloneNode true
a.href = parts['url']
a.textContent = parts['text']
return null unless /^https?:$/.test a.protocol
a
node: ->
return if @isClone or !@file

View File

@ -151,13 +151,12 @@ Linkify =
embed: (data) ->
[key, uid, options, link, post] = data
href = link.href
embed = $.el 'a',
className: 'embedder'
href: 'javascript:;'
href: link.href
textContent: '(embed)'
embed.dataset[name] = value for name, value of {key, href, uid, options}
embed.dataset[name] = value for name, value of {key, uid, options}
$.addClass link, "#{embed.dataset.key}"
@ -181,7 +180,8 @@ Linkify =
return
cb:
toggle: ->
toggle: (e) ->
e?.preventDefault()
if $.hasClass @, "embedded"
$.rm @previousElementSibling
@previousElementSibling.hidden = false
@ -253,14 +253,14 @@ Linkify =
el: (a) ->
el = $.el 'div'
el.innerHTML = '<a target="_blank"><img></a>'
el.firstChild.href = el.firstChild.firstChild.src = a.dataset.href
el.firstChild.href = el.firstChild.firstChild.src = a.href
el
,
key: 'InstallGentoo'
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/
el: (a) ->
$.el 'iframe',
src: "http://paste.installgentoo.com/view/embed/#{a.dataset.uid}"
src: "https://paste.installgentoo.com/view/embed/#{a.dataset.uid}"
,
key: 'Twitter'
regExp: /.*twitter.com\/(.+\/status\/\d+)/
@ -302,7 +302,7 @@ Linkify =
el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}"
when 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg'
el.innerHTML = '<a target="_blank"><img></a>'
el.firstChild.href = a.dataset.href
el.firstChild.href = a.href
el.firstChild.firstChild.src = "https://mediacru.sh/#{file.file}"
when 'audio/mpeg', 'audio/ogg'
el.innerHTML = '<audio controls><source type="audio/ogg"><source type="audio/mpeg"></audio>'
@ -322,20 +322,20 @@ Linkify =
regExp: /.*gfycat.com\/(?:iframe\/)?(\S*)/
el: (a) ->
div = $.el 'iframe',
src: "http://gfycat.com/iframe/#{a.dataset.uid}"
src: "//gfycat.com/iframe/#{a.dataset.uid}"
,
key: 'SoundCloud'
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
style: 'border: 0; width: 500px; height: 400px;'
el: (a) ->
$.el 'iframe',
src: "//w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F#{encodeURIComponent a.dataset.uid}"
src: "https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F#{encodeURIComponent a.dataset.uid}"
title:
api: (uid) -> "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F#{encodeURIComponent uid}"
text: (_) -> _.title
,
key: 'StrawPoll'
regExp: /strawpoll\.me\/(?:embed_\d+\/)?(\d+)/
regExp: /strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/
style: 'border: 0; width: 600px; height: 406px;'
el: (a) ->
$.el 'iframe',