Conflicts:
	LICENSE
	builds/4chan-X.js
	builds/4chan-X.user.js
	builds/crx/script.js
This commit is contained in:
Zixaphir 2013-04-30 17:24:37 -07:00
commit ef3c862543
28 changed files with 497 additions and 248 deletions

View File

@ -1,8 +1,24 @@
seaweedchan:
- Fix various embedding issues
- Fix Link Title depending on Embedding
- Added favicons to links that can be embedded
- Add gist embedding
### 1.1.4 - 2013-04-29
seaweedchan:
- Change ESC functionality in QR to autohide if Persistent QR is enabled
- Add /v/ and /vg/ archiving to archive.nihil-ad-rem.net, and make sure Archiver Selection settings actually switch to it
- Add option to toggle between updater and stats fixed in header or floating
MayhemYDG:
- Add nyafuu archiving for /w/
- Add /d/ archive
### 1.1.3 - 2013-04-28
seaweedchan:
- Chrome doesn't get .null, so don't style it
- Fix count when auto update is disabled and set updater text to "Update"
- Remove /v/ and /vg/ redirection. See https://archive.foolz.us/foolz/thread/509388/ for news and how you can donate to bring /v/ and /vg/ archiving back.
- Remove /v/ and /vg/ redirection from Foolz.
- Toggle keybind for header auto-hiding
MayhemYDG:

View File

@ -85,6 +85,7 @@ module.exports = (grunt) ->
concurrent:
build: [
'concat:license'
'build-crx'
'build-userjs'
'build-userscript'
@ -152,7 +153,6 @@ module.exports = (grunt) ->
grunt.registerTask 'build', [
'concurrent:build'
'concat:license'
]
grunt.registerTask 'build-crx', [

View File

@ -1,5 +1,5 @@
/*
* 4chan X - Version 1.1.3 - 2013-04-30
* 4chan X - Version 1.1.4 - 2013-04-30
*
* Licensed under the MIT license.
* https://github.com/seaweedchan/4chan-x/blob/master/LICENSE

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan X
// @version 1.1.3
// @version 1.1.4
// @namespace 4chan-X
// @description Cross-browser userscript for maximum lurking on 4chan.
// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "4chan X",
"version": "1.1.3",
"version": "1.1.4",
"manifest_version": 2,
"description": "Cross-browser userscript for maximum lurking on 4chan.",
"icons": {

File diff suppressed because one or more lines are too long

View File

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

View File

@ -13,13 +13,19 @@ Redirect =
"//archive.foolz.us/#{boardID}/full_image/#{filename}"
when 'u'
"//nsfw.foolz.us/#{boardID}/full_image/#{filename}"
when 'v', 'vg'
"//archive.nihil-ad-rem.net/#{boardID}/full_image/#{filename}"
when 'po'
"//archive.thedarkcave.org/#{boardID}/full_image/#{filename}"
when 'hr', 'tv'
"http://archive.4plebs.org/#{boardID}/full_image/#{filename}"
when 'c', 'w', 'wg'
"//archive.nyafuu.org/#{boardID}/full_image/#{filename}"
when 'd'
"//loveisover.me/#{boardID}/full_image/#{filename}"
when 'ck', 'fa', 'lit', 's4s'
"//fuuka.warosu.org/#{boardID}/full_image/#{filename}"
when 'cgl', 'g', 'mu', 'w'
when 'cgl', 'g', 'mu'
"//rbt.asia/#{boardID}/full_image/#{filename}"
when 'an', 'k', 'toy', 'x'
"http://archive.heinessen.com/#{boardID}/full_image/#{filename}"
@ -58,11 +64,18 @@ Redirect =
else
null)
unless archive.boards.contains g.BOARD.ID
Conf['archivers'] = archive
archiver:
'Foolz':
base: 'https://archive.foolz.us'
boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg']
type: 'foolfuuka'
'NihilAdRem':
base: '//archive.nihil-ad-rem.net'
boards: ['v', 'vg']
type: 'foolfuuka'
'NSFWFoolz':
base: 'https://nsfw.foolz.us'
boards: ['u']
@ -75,6 +88,14 @@ Redirect =
base: 'http://archive.4plebs.org'
boards: ['hr', 'tg', 'tv', 'x']
base: 'foolfuuka'
'NyaFuu':
base: '//archive.nyafuu.org'
boards: ['c', 'w', 'wg']
type: 'foolfuuka'
'LoveIsOver':
base: '//loveisover.me'
boards: ['d']
type: 'foolfuuka'
'Warosu':
base: '//fuuka.warosu.org'
boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg']
@ -95,10 +116,6 @@ Redirect =
base: '//www.cliché.net/4chan/cgi-board.pl'
boards: ['e']
type: 'fuuka'
'NyaFuu':
base: '//archive.nyafuu.org'
boards: ['c', 'w']
type: 'fuuka'
path: (base, archiver, data) ->
if data.isSearch

View File

@ -217,6 +217,10 @@ Config =
true
'Display reply and image count.'
]
'Updater and Stats in Header': [
true,
'Places the thread updater and thread stats in the header instead of floating them.'
]
'Thread Watcher': [
true
'Bookmark threads.'

View File

@ -139,22 +139,22 @@ Header =
for a in as
if a.textContent is board
a = a.cloneNode true
if /-title/.test t
a.textContent = a.title
else if /-replace/.test t
if $.hasClass a, 'current'
a.textContent = a.title
a.textContent = if /-title/.test(t) or /-replace/.test(t) and $.hasClass a, 'current'
a.title
else if /-full/.test t
a.textContent = "/#{board}/ - #{a.title}"
else if /-(index|catalog|text)/.test t
if m = t.match /-(index|catalog)/
a.setAttribute 'data-only', m[1]
a.href = "//boards.4chan.org/#{board}/"
a.href += 'catalog' if m[1] is 'catalog'
if m = t.match /-text:"(.+)"/
a.textContent = m[1]
else if board is '@'
$.addClass a, 'navSmall'
"/#{board}/ - #{a.title}"
else if m = t.match /-text:"(.+)"/
m[1]
else
a.textContent
if m = t.match /-(index|catalog)/
a.setAttribute 'data-only', m[1]
a.href = "//boards.4chan.org/#{board}/"
a.href += 'catalog' if m[1] is 'catalog'
$.addClass a, 'navSmall' if board is '@'
return a
$.tn t
$.add list, nodes

View File

@ -66,6 +66,8 @@ a[href="javascript:;"] {
#qp, #ihover,
#navlinks, .fixed #header-bar,
#watcher,
:root.float #updater,
:root.float #thread-stats,
#qr {
position: fixed;
}
@ -374,9 +376,6 @@ a[href="javascript:;"] {
a.hide-announcement {
float: left;
}
#toggleMsgBtn {
display: none;
}
/* Unread */
#unread-line {
@ -385,13 +384,14 @@ a.hide-announcement {
}
/* Thread Updater */
#updater:not(:hover) {
#updater {
background: none;
border: none;
box-shadow: none;
}
#updater > .move {
padding: 0 3px;
padding: 5px 3px 0px;
margin-bottom: -3px;
}
#updater > div:last-child {
text-align: center;
@ -399,11 +399,8 @@ a.hide-announcement {
#updater input[type=number] {
width: 4em;
}
#updater:not(:hover) > div:not(.move) {
display: none;
}
#updater input[type="button"] {
width: 100%;
:root.float #updater {
padding: 0px 3px;
}
.new {
color: limegreen;
@ -444,6 +441,12 @@ a.hide-announcement {
border: none;
box-shadow: none;
}
:root.float #post-count, :root.float #file-count {
pointer-events: none;
}
:root.float #thread-stats {
padding: 0px 3px;
}
/* Quote */
.deadlink {
@ -892,3 +895,36 @@ a:only-of-type > .remove {
cursor: pointer;
text-decoration: none !important;
}
/* Link Title Favicons */
.linkify.YouTube {
background: transparent url('data:image/png;base64,<%= grunt.file.read("src/General/img/links/youtube.png", {encoding: "base64"}) %>') center left no-repeat!important;
padding-left: 18px;
}
.linkify.Vimeo {
background: transparent url('data:image/png;base64,<%= grunt.file.read("src/General/img/links/vimeo.png", {encoding: "base64"}) %>') center left no-repeat!important;
padding-left: 18px;
}
.linkify.SoundCloud {
background: transparent url('data:image/png;base64,<%= grunt.file.read("src/General/img/links/soundcloud.png", {encoding: "base64"}) %>') center left no-repeat!important;
padding-left: 18px;
}
.linkify.audio {
background: transparent url('data:image/png;base64,<%= grunt.file.read("src/General/img/links/audio.png", {encoding: "base64"}) %>') center left no-repeat!important;
padding-left: 18px;
}
.linkify.LiveLeak {
background: transparent url('data:image/png;base64,<%= grunt.file.read("src/General/img/links/liveleak.png", {encoding: "base64"}) %>') center left no-repeat!important;
padding-left: 18px;
}
.linkify.Vocaroo {
background: transparent url('data:image/png;base64,<%= grunt.file.read("src/General/img/links/vocaroo.png", {encoding: "base64"}) %>') center left no-repeat!important;
padding-left: 18px;
}
.linkify.pastebin {
background: transparent url('data:image/png;base64,<%= grunt.file.read("src/General/img/links/pastebin.png", {encoding: "base64"}) %>') center left no-repeat!important;
padding-left: 18px;
}
.linkify.gist {
background: transparent url('data:image/png;base64,<%= grunt.file.read("src/General/img/links/gist.png", {encoding: "base64"}) %>') center left no-repeat!important;
padding-left: 18px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

View File

@ -373,7 +373,7 @@ $.set = do ->
items = {}
localItems = {}
catch err
c.error err
c.error err.stack
(key, val) ->
if typeof key is 'string'

View File

@ -125,21 +125,17 @@ Linkify =
textContent: @getAttribute("data-title") or url
@textContent = '(embed)'
$.addClass el, "#{@getAttribute 'data-service'}"
# Embed
else
# We create an element to embed
el = (type = Linkify.types[@getAttribute("data-service")]).el.call @
# Set style values.
if style = type.style
el.style.cssText = style
el.style.cssText = if style = type.style
style
else
items =
'embedWidth': Config['embedWidth']
'embedHeight': Config['embedHeight']
$.get items, (items) ->
el.style.cssText = "border: 0; width: #{items['embedWidth']}px; height: #{items['embedHeight']}px"
"border: 0; width: 640px; height: 390px"
@textContent = '(unembed)'
@ -187,32 +183,44 @@ Linkify =
src: @name
SoundCloud:
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
style: 'height: auto; width: 500px; display: inline-block;'
el: ->
div = $.el 'div',
className: "soundcloud"
name: "soundcloud"
name: "soundcloud"
$.ajax(
"//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=#{@getAttribute 'data-originalURL'}&color=#{Style.colorToHex Themes[Conf['theme']]['Background Color']}"
"//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{@name}"
div: div
onloadend: ->
@div.innerHTML = JSON.parse(@responseText).html
false)
div
title:
api: -> "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{@name}"
text: -> JSON.parse(@responseText).title
pastebin:
regExp: /.*(?:pastebin.com\/)([^#\&\?]*).*/
regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/
el: ->
div = $.el 'iframe',
src: "http://pastebin.com/embed_iframe.php?i=#{@name}"
gist:
regExp: /.*(?:gist.github.com\/.*\/)([^#\&\?]*).*/
el: ->
div = $.el 'iframe',
# Github doesn't allow embedding straight from the site, so we use an external site to bypass that.
src: "http://www.purplegene.com/script?url=https://gist.github.com/#{@name}.js"
embedder: (a) ->
return [a] unless Conf['Embedding']
return [a] unless Conf['Link Title']
titles = {}
callbacks = ->
a.textContent = switch @status
when 200, 304
title = "[#{embed.getAttribute 'data-service'}] #{service.text.call @}"
title = "#{service.text.call @}"
embed.setAttribute 'data-title', title
titles[embed.name] = [title, Date.now()]
$.set 'CachedTitles', titles
@ -235,13 +243,16 @@ Linkify =
embed.setAttribute 'data-service', key
embed.setAttribute 'data-originalURL', a.href
$.addClass a, "#{embed.getAttribute 'data-service'}"
$.on embed, 'click', Linkify.toggle
unless Conf['Embedding']
embed.hidden = true
if Conf['Link Title'] and (service = type.title)
$.get 'CachedTitles', {}, (item) ->
titles = item['CachedTitles']
if title = titles[match[1]]
a.textContent = title[0]
embed.setAttribute 'data-title', title[0]

View File

@ -11,7 +11,7 @@ ExpandComment =
name: 'Comment Expansion'
cb: @node
node: ->
if a = $ '.abbr > a', @nodes.comment
if a = $ '.abbr > a:not([onclick])', @nodes.comment
$.on a, 'click', ExpandComment.cb
callbacks: []
cb: (e) ->
@ -63,4 +63,4 @@ ExpandComment =
for callback in ExpandComment.callbacks
callback.call post
return
return

View File

@ -41,7 +41,10 @@ Keybinds =
for notification in notifications
$('.close', notification).click()
else if QR.nodes
QR.close()
if Conf['Persistent QR']
QR.hide()
else
QR.close()
when Conf['Spoiler tags']
return if target.nodeName isnt 'TEXTAREA'
Keybinds.tags 'spoiler', target

View File

@ -1,14 +1,20 @@
ThreadStats =
init: ->
return if g.VIEW isnt 'thread' or !Conf['Thread Stats']
@dialog = sc = $.el 'span',
innerHTML: "<span id=post-count>0</span> / <span id=file-count>0</span></div>"
id: 'thread-stats'
if Conf['Updater and Stats in Header']
@dialog = sc = $.el 'span',
innerHTML: "<span id=post-count>0</span> / <span id=file-count>0</span>"
id: 'thread-stats'
Header.addShortcut sc
else
@dialog = sc = UI.dialog 'thread-stats', 'bottom: 0px; right: 0px;',
"<div class=move><span id=post-count>0</span> / <span id=file-count>0</span></div>"
$.ready =>
$.add d.body, sc
@postCountEl = $ '#post-count', sc
@fileCountEl = $ '#file-count', sc
Header.addShortcut sc
Thread::callbacks.push
name: 'Thread Stats'

View File

@ -3,20 +3,28 @@ ThreadUpdater =
return if g.VIEW isnt 'thread' or !Conf['Thread Updater']
checked = if Conf['Auto Update'] then 'checked' else ''
@dialog = sc = $.el 'span',
innerHTML: "<span id=update-status></span><span id=update-timer title='Update now'></span>"
id: 'updater'
@timer = $ '#update-timer', sc
if Conf['Updater and Stats in Header']
@dialog = sc = $.el 'span',
innerHTML: "<span id=update-status></span><span id=update-timer title='Update now'></span>"
id: 'updater'
Header.addShortcut sc
else
@dialog = sc = UI.dialog 'updater', 'bottom: 0px; left: 0px;',
"<div class=move></div><span id=update-status></span><span id=update-timer title='Update now'></span>"
$.addClass doc, 'float'
$.ready =>
$.addClass doc, 'float'
$.add d.body, sc
@checkPostCount = 0
@timer = $ '#update-timer', sc
@status = $ '#update-status', sc
$.on @timer, 'click', ThreadUpdater.update
$.on @status, 'click', ThreadUpdater.update
@checkPostCount = 0
Header.addShortcut sc
subEntries = []
for name, conf of Config.updater.checkbox
checked = if Conf[name] then 'checked' else ''

View File

@ -39,6 +39,7 @@ ThreadWatcher =
for id, props of watched[board]
x = $.el 'a',
textContent: '×'
className: 'close'
href: 'javascript:;'
$.on x, 'click', ThreadWatcher.cb.x
link = $.el 'a', props