Merge branch 'master' into catalog

Conflicts:
	src/General/Index.coffee
	src/General/lib/thread.class
This commit is contained in:
ccd0 2014-09-14 13:57:32 -07:00
commit 5df20a84dc
25 changed files with 346 additions and 393 deletions

View File

@ -1,3 +1,25 @@
### v1.9.3.0
*2014-09-14*
Based on v1.9.2.9.
**MayhemYDG**, **ccd0**
- Various small bugfixes.
**MayhemYDG**
- Keep title in 404'd tabs.
**ccd0**
- Change name of Greasemonkey beta version to `4chan X beta` so the beta and stable versions can be installed side by side.
- Index sorting/searching/etc. features (`JSON Navigation` option) and including WebM when expanding all images (`Expand videos` option) are now on by default.
### v1.9.2.9
*2014-09-13*
**ccd0**
- Fix minimum Chrome version (32).
- Fix Linkify bug.
### v1.9.2.8 ### v1.9.2.8
*2014-09-11* *2014-09-11*

View File

@ -1,5 +1,5 @@
/* /*
* 4chan X - Version 1.9.2.8 * 4chan X - Version 1.9.3.0
* *
* 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

View File

@ -1,6 +1,7 @@
Fork of [Spittie's 4chan X](https://github.com/Spittie/4chan-x) (itself a fork of [Seaweed's](https://github.com/seaweedchan/4chan-x)). Adds various features to 4chan.
A continuation of the fork formerly maintained by [Seaweed](https://github.com/seaweedchan/4chan-x) and subsequently [Spittie](https://github.com/Spittie/4chan-x).
If you're looking for OneeChan, try If you're looking for a maintained fork of OneeChan, try
https://github.com/Nebukazar/OneeChan https://github.com/Nebukazar/OneeChan
## [Install](https://ccd0.github.io/4chan-x/builds/4chan-X.user.js) (Firefox) ## [Install](https://ccd0.github.io/4chan-x/builds/4chan-X.user.js) (Firefox)
@ -25,7 +26,7 @@ This should also work for non-Windows/dev/canary Chrome and Chromium-based versi
Some recent versions of Chromium/Chrome (38.0.2085 - 38.0.2103) (and versions of Opera based on them) suffer from a (now fixed) [bug](https://crbug.com/393686) that prevents extensions from making HTTP requests if more than one extension is enabled. This breaks, among other things, thread updating, quick reply, and, when `JSON Navigation` is enabled, the thread index. If you are experiencing this, try using another version of Chromium/Chrome/Opera, disabling your other extensions, or using a different browser. Some recent versions of Chromium/Chrome (38.0.2085 - 38.0.2103) (and versions of Opera based on them) suffer from a (now fixed) [bug](https://crbug.com/393686) that prevents extensions from making HTTP requests if more than one extension is enabled. This breaks, among other things, thread updating, quick reply, and, when `JSON Navigation` is enabled, the thread index. If you are experiencing this, try using another version of Chromium/Chrome/Opera, disabling your other extensions, or using a different browser.
## Other browsers ## 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. 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. You may have better luck with [loadletter's v2 fork](https://github.com/loadletter/4chan-x), which has fewer features but less dependence on browser-specific APIs.
### dwb ### dwb
1. Install dwb with your package manager 1. Install dwb with your package manager

Binary file not shown.

View File

@ -1,6 +1,6 @@
// ==UserScript== // ==UserScript==
// @name 4chan X // @name 4chan X beta
// @version 1.9.2.8 // @version 1.9.3.0
// @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.2.8 // @version 1.9.3.0
// @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.2.8' /> <updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.9.3.0' />
</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.2.8' /> <updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.9.3.0' />
</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.2.8", "version": "1.9.3.0",
"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/",
@ -38,7 +38,7 @@
"devDependencies": { "devDependencies": {
"font-awesome": "4.2.0", "font-awesome": "4.2.0",
"grunt": "0.4.5", "grunt": "0.4.5",
"grunt-concurrent": "0.5.0", "grunt-concurrent": "1.0.0",
"grunt-contrib-clean": "0.6.0", "grunt-contrib-clean": "0.6.0",
"grunt-contrib-coffee": "0.11.1", "grunt-contrib-coffee": "0.11.1",
"grunt-contrib-compress": "0.11.0", "grunt-contrib-compress": "0.11.0",
@ -46,7 +46,7 @@
"grunt-contrib-copy": "0.5.0", "grunt-contrib-copy": "0.5.0",
"grunt-contrib-watch": "0.6.1", "grunt-contrib-watch": "0.6.1",
"grunt-crx": "0.3.3", "grunt-crx": "0.3.3",
"grunt-shell": "1.0.1", "grunt-shell": "1.1.1",
"load-grunt-tasks": "0.6.0" "load-grunt-tasks": "0.6.0"
}, },
"repository": { "repository": {
@ -64,4 +64,4 @@
"engines": { "engines": {
"node": ">=0.10" "node": ">=0.10"
} }
} }

View File

@ -153,12 +153,6 @@ Build =
else else
"/#{boardID}/thread/#{threadID}\#q#{postID}" "/#{boardID}/thread/#{threadID}\#q#{postID}"
pageIcon = if isOP and g.VIEW is 'index' and Conf['JSON Navigation']
pageNum = Math.floor(Index.liveThreadIDs.indexOf(postID) / Index.threadsNumPerPage) + 1
<%= html(' <span class="page-num" title="This thread is on page ${pageNum} in the original index.">[${pageNum}]</span>') %>
else
<%= html('') %>
sticky = if isSticky sticky = if isSticky
<%= html(' <img src="//s.4cdn.org/image/sticky${retina}.gif" alt="Sticky" title="Sticky" class="stickyIcon retina">') %> <%= html(' <img src="//s.4cdn.org/image/sticky${retina}.gif" alt="Sticky" title="Sticky" class="stickyIcon retina">') %>
else else
@ -183,7 +177,7 @@ Build =
'<span class="postNum${desktop2}">' + '<span class="postNum${desktop2}">' +
'<a href="${postLink}" title="Link to this post">No.</a>' + '<a href="${postLink}" title="Link to this post">No.</a>' +
'<a href="${quoteLink}" title="Reply to this post">${postID}</a>' + '<a href="${quoteLink}" title="Reply to this post">${postID}</a>' +
'&{pageIcon}&{sticky}&{closed}&{replyLink}' + '&{sticky}&{closed}&{replyLink}' +
'</span>' + '</span>' +
'</div>' '</div>'
) %> ) %>

View File

@ -2,8 +2,8 @@ Config =
main: main:
'Miscellaneous': 'Miscellaneous':
'JSON Navigation' : [ 'JSON Navigation' : [
false true
'Use JSON for loading the Board Index. Also allows searching and sorting the board index and infinite scolling.' 'Replace the board index with a dynamically generated one supporting searching, sorting, and infinite scrolling.'
] ]
'Catalog Links': [ 'Catalog Links': [
true true
@ -432,8 +432,8 @@ Config =
'Expand all images along with spoilers.' 'Expand all images along with spoilers.'
] ]
'Expand videos': [ 'Expand videos': [
false true
'Expand all images also expands videos (no autoplay).' 'Expand all images also expands videos.'
] ]
'Expand from here': [ 'Expand from here': [
false false

View File

@ -432,7 +432,6 @@ Index =
try try
threadRoot = Build.thread g.BOARD, threadData threadRoot = Build.thread g.BOARD, threadData
if thread = g.BOARD.threads[threadData.no] if thread = g.BOARD.threads[threadData.no]
thread.setPage Math.floor i / Index.threadsNumPerPage
thread.setCount 'post', threadData.replies + 1, threadData.bumplimit thread.setCount 'post', threadData.replies + 1, threadData.bumplimit
thread.setCount 'file', threadData.images + !!threadData.ext, threadData.imagelimit thread.setCount 'file', threadData.images + !!threadData.ext, threadData.imagelimit
thread.setStatus 'Sticky', !!threadData.sticky thread.setStatus 'Sticky', !!threadData.sticky
@ -441,8 +440,9 @@ Index =
thread = new Thread threadData.no, g.BOARD thread = new Thread threadData.no, g.BOARD
threads.push thread threads.push thread
Index.nodes.push threadRoot Index.nodes.push threadRoot
continue if thread.ID of thread.posts unless thread.ID of thread.posts
posts.push new Post $('.opContainer', threadRoot), thread, g.BOARD posts.push new Post $('.opContainer', threadRoot), thread, g.BOARD
thread.setPage i // Index.threadsNumPerPage + 1
catch err catch err
# Skip posts that we failed to parse. # Skip posts that we failed to parse.
errors = [] unless errors errors = [] unless errors

View File

@ -345,7 +345,7 @@ UI = do ->
else else
top top
[left, right] = if clientX <= @clientWidth - 400 [left, right] = if clientX <= @clientWidth / 2
[clientX + 45 + 'px', null] [clientX + 45 + 'px', null]
else else
[null, @clientWidth - clientX + 45 + 'px'] [null, @clientWidth - clientX + 45 + 'px']

View File

@ -56,7 +56,7 @@
<fieldset> <fieldset>
<legend>File Info Formatting <span class=warning data-feature='File Info Formatting'>is disabled.</span></legend> <legend>File Info Formatting <span class=warning data-feature='File Info Formatting'>is disabled.</span></legend>
<div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div> <div><input name=fileInfo class=field spellcheck=false>: <span class='file-info file-info-preview'></span></div>
<div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div> <div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>
<div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div> <div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>
<div>Spoiler indicator: <code>%p</code></div> <div>Spoiler indicator: <code>%p</code></div>

View File

@ -17,9 +17,11 @@ class DataBoard
delete: ({boardID, threadID, postID}) -> delete: ({boardID, threadID, postID}) ->
if postID if postID
return unless @data.boards[boardID]?[threadID]
delete @data.boards[boardID][threadID][postID] delete @data.boards[boardID][threadID][postID]
@deleteIfEmpty {boardID, threadID} @deleteIfEmpty {boardID, threadID}
else if threadID else if threadID
return unless @data.boards[boardID]
delete @data.boards[boardID][threadID] delete @data.boards[boardID][threadID]
@deleteIfEmpty {boardID} @deleteIfEmpty {boardID}
else else

View File

@ -16,9 +16,12 @@ class Thread
g.threads.push @fullID, board.threads.push @, @ g.threads.push @fullID, board.threads.push @, @
setPage: (pageNum) -> setPage: (pageNum) ->
icon = $ '.page-num', @OP.nodes.post {info} = @OP.nodes
for key in ['title', 'textContent'] unless icon = $ '.page-num', info
icon[key] = icon[key].replace /\d+/, pageNum icon = $.el 'span', className: 'page-num'
$.after $('a[title="Reply to this post"]', info), [$.tn(' '), icon]
icon.title = "This thread is on page #{pageNum} in the original index."
icon.textContent = "[#{pageNum}]"
@catalogView.nodes.pageCount.textContent = pageNum if @catalogView @catalogView.nodes.pageCount.textContent = pageNum if @catalogView
setCount: (type, count, reachedLimit) -> setCount: (type, count, reachedLimit) ->
return unless @catalogView return unless @catalogView
@ -41,13 +44,11 @@ class Thread
src: "#{Build.staticPath}#{typeLC}#{Build.gifIcon}" src: "#{Build.staticPath}#{typeLC}#{Build.gifIcon}"
alt: type alt: type
title: type title: type
className: "#{typeLC}Icon" className: "#{typeLC}Icon retina"
root = if type is 'Closed' and @isSticky root = if type is 'Closed' and @isSticky
$ '.stickyIcon', @OP.nodes.info $ '.stickyIcon', @OP.nodes.info
else if g.VIEW is 'index'
$ '.page-num', @OP.nodes.info
else else
$ '[title="Reply to this post"]', @OP.nodes.info $('.page-num', @OP.nodes.info) or $('[title="Reply to this post"]', @OP.nodes.info)
$.after root, [$.tn(' '), icon] $.after root, [$.tn(' '), icon]
return unless @catalogView return unless @catalogView

View File

@ -9,6 +9,7 @@ ImageHover =
return unless @file?.isImage or @file?.isVideo return unless @file?.isImage or @file?.isVideo
$.on @file.thumb, 'mouseover', ImageHover.mouseover $.on @file.thumb, 'mouseover', ImageHover.mouseover
mouseover: (e) -> mouseover: (e) ->
return unless doc.contains @
post = Get.postFromNode @ post = Get.postFromNode @
{file} = post {file} = post
{isVideo} = file {isVideo} = file

View File

@ -153,6 +153,7 @@ Linkify =
[key, uid, options, link, post] = data [key, uid, options, link, post] = data
embed = $.el 'a', embed = $.el 'a',
className: 'embedder' className: 'embedder'
rel: 'nofollow noreferrer'
href: link.href href: link.href
textContent: '(embed)' textContent: '(embed)'
@ -225,7 +226,7 @@ Linkify =
ordered_types: [ ordered_types: [
key: 'audio' key: 'audio'
regExp: /\.(?:mp3|ogg|wav)$/ regExp: /\.(?:mp3|ogg|wav)$/i
style: '' style: ''
el: (a) -> el: (a) ->
$.el 'audio', $.el 'audio',
@ -247,7 +248,7 @@ Linkify =
return file for file of files when files.hasOwnProperty file return file for file of files when files.hasOwnProperty file
, ,
key: 'image' key: 'image'
regExp: /\.(?:gif|png|jpg|jpeg|bmp)$/ regExp: /\.(?:gif|png|jpg|jpeg|bmp)$/i
style: 'border: 0; width: auto; height: auto;' style: 'border: 0; width: auto; height: auto;'
el: (a) -> el: (a) ->
$.el 'div', <%= html('<a target="_blank" href="${a.href}"><img src="${a.href}"></a>') %> $.el 'div', <%= html('<a target="_blank" href="${a.href}"><img src="${a.href}"></a>') %>
@ -277,7 +278,7 @@ Linkify =
el el
, ,
key: 'MediaCrush' key: 'MediaCrush'
regExp: /^\w+:\/\/(?:www\.)?mediacru\.sh\/([\w\-]+)/i regExp: /^\w+:\/\/(?:www\.)?mediacru\.sh\/([\w\-]+)/
style: 'border: 0;' style: 'border: 0;'
el: (a) -> el: (a) ->
el = $.el 'div' el = $.el 'div'
@ -445,7 +446,7 @@ Linkify =
dummy: true dummy: true
, ,
key: 'video' key: 'video'
regExp: /\.(?:ogv|webm|mp4)$/ regExp: /\.(?:ogv|webm|mp4)$/i
style: 'border: 0; width: auto; height: auto;' style: 'border: 0; width: auto; height: auto;'
el: (a) -> el: (a) ->
$.el 'video', $.el 'video',

View File

@ -180,7 +180,7 @@ Unread =
countQuotingYou = Object.keys(Unread.postsQuotingYou).length countQuotingYou = Object.keys(Unread.postsQuotingYou).length
if Conf['Unread Count'] if Conf['Unread Count']
d.title = "#{if Conf['Quoted Title'] and countQuotingYou then '(!) ' else ''}#{if count or !Conf['Hide Unread Count at (0)'] then "(#{count}) " else ''}#{if g.DEAD then "/#{g.BOARD}/ - 404" else "#{Unread.title}"}" d.title = "#{if Conf['Quoted Title'] and countQuotingYou then '(!) ' else ''}#{if count or !Conf['Hide Unread Count at (0)'] then "(#{count}) " else ''}#{if g.DEAD then Unread.title.replace '-', '- 404 -' else Unread.title}"
return unless Conf['Unread Favicon'] return unless Conf['Unread Favicon']