Merge branch 'ccd0' into v3

Conflicts:
	CHANGELOG.md
	LICENSE
	builds/4chan-X.user.js
	builds/crx.crx
	builds/crx/script.js
	src/General/Config.coffee
	src/General/css/style.css
	src/Images/Gallery.coffee
	src/Images/ImageExpand.coffee
This commit is contained in:
Zixaphir 2014-04-10 23:08:43 -07:00
commit 28eebe0183
30 changed files with 338 additions and 24121 deletions

1
.gitignore vendored
View File

@ -3,5 +3,6 @@ node_modules/
*.db
tmp-crx/
tmp-userscript/
testbuilds/
builds/4chan-X.zip
Gruntfile.js

View File

@ -1,5 +1,31 @@
<<<<<<< HEAD
=======
### v1.7.7
*2014-04-10*
**fgts**
- Update archive list.
### v1.7.6
*2014-04-10*
**ccd0**
- `Loop in New Tab` (enabled by default) causes videos opened in a separate tab to loop, and applies your settings for inline expanded videos to them.
### v1.7.5
*2014-04-09*
**ccd0**
- Add WebM support to gallery (currently no controls).
- Add PDF support to gallery, disabled by default. Enable with `PDF in Gallery`.
### v1.7.4
*2014-04-08*
**Nebukazar**
- `Quote Threading` disabled by default
- Added missing titles to Header icons
**ccd0**
- Fix bug in gallery introduced in 1.7.3.
### v1.7.3
*2014-04-07*
@ -13,7 +39,6 @@
### v1.7.2
*2014-04-07*
>>>>>>> ccd0
**ccd0**
- Restore thread expansion with JSON navigation disabled.

View File

@ -1,5 +1,5 @@
/*
* 4chan X - Version 1.7.3 - 2014-04-10
* 4chan X - Version 1.7.7 - 2014-04-10
*
* Licensed under the MIT license.
* https://github.com/ccd0/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.7.3
// @version 1.7.7
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "4chan X",
"version": "1.7.3",
"version": "1.7.7",
"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,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/crx.crx' version='1.7.3' />
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.7' />
</app>
</gupdate>

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -1,62 +0,0 @@
function GM_openInTab(_url) {
self.port.emit("GM_openInTab", _url);
return; // Should return the Window object
};
function GM_setValue(_name, _value) {
localStorage[_name] = _value;
return;
};
function GM_getValue(_name, _default) {
if (localStorage[_name] === null && _default === null) return null;
return (localStorage[_name] || _default);
};
function GM_deleteValue(_name) {
localStorage.removeItem(_name);
return;
};
function GM_listValues() {
return Object.keys(localStorage);
};
function GM_setClipboard(_text) {
self.port.emit("GM_setClipboard", _text);
};
//Deprecated
function GM_log(_message) {
console.log(_message);
return;
};
function GM_xmlhttpRequest(_details) {
//Ugly hack? Race condition? Memory leak?
_onload = _details.onload;
_context = _details.context;
self.port.emit("GM_xmlhttpRequest", _details);
};
self.port.on("callback_GM_xmlhttpRequest", function(_response) {
_response.context = _context;
_onload(_response);
});
function GM_addStyle(_css) {
self.port.emit("GM_addStyle", _css);
}
var GM_info = new Object();
GM_info.version = '1.15';
GM_info.scriptWillUpdate = true;
//To do
function GM_registerMenuCommand(_caption, _commandFunc, _accessKey) {
return;
}
self.port.on("load-userscript", function(_script) {
eval(_script);
});

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 B

View File

@ -1,82 +0,0 @@
var data = require("sdk/self").data;
var Request = require("sdk/request").Request;
var tabs = require("sdk/tabs");
var system = require("sdk/system");
if (system.platform !== 'android') {
// Clipboard is not supported on Android
var clipboard = require("sdk/clipboard");
}
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: ["*.4chan.org", "*.4cdn.org"],
contentScriptFile: data.url("greaseshim.js"),
contentScriptWhen: "start",
onAttach: function(worker) {
worker.port.emit("load-userscript", data.load("4chan-X.user.js"));
//GM_openInTab
worker.port.on("GM_openInTab", function(url) {
tabs.open(url);
});
//GM_setClipboard
worker.port.on("GM_setClipboard", function(text) {
if (system.platform !== 'android') {
// Clipboard is not supported on Android
clipboard.set(text);
}
});
//GM_xmlhttpRequest
worker.port.on("GM_xmlhttpRequest", function(details) {
request = new Object();
request.url = details.url;
if (details.headers) {
request.headers = details.headers;
if (details.headers["Content-Type"]) {request.contentType = details.headers["Content-Type"]};
};
if (details.data) {request.content = encodeURIComponent(details.data)};
if (details.overrideMimeType) {request.overrideMimeType = details.overrideMimeType};
request.onComplete = function(response) {
response.finalUrl = details.url;
response.responseText = response.text;
for (var headerName in response.headers) {
_string = headerName + ": " + response.headers[headerName] + " \n";
response.responseHeaders += _string;
}
response.readyState = 4;
worker.port.emit("callback_GM_xmlhttpRequest", response);
}
xhr = Request(request);
switch(details.method){
case "GET":
xhr.get();
break;
case "POST":
xhr.post();
break;
case "HEAD":
xhr.head();
break;
case "PUT":
xhr.put();
break;
default: xhr.get();
}
});
//GM_addStyle
worker.port.on("GM_addStyle", function(css) {
tabs.activeTab.attach({
contentScript: "var style = document.createElement('style');" +
"style.type = 'text/css';" +
"style.innerHTML = '" + css + "';" +
"document.head.appendChild(style);"
});
});
}
});

View File

@ -1,9 +0,0 @@
{
"name": "4chanx",
"title": "4chan X",
"id": "72DAF86E-9689-11E3-8BA3-F4B66188709B",
"description": "Adds various features to 4chan.",
"author": "Spittie",
"license": "MIT",
"version": "1.4.1"
}

View File

@ -1,12 +0,0 @@
var main = require("./main");
exports["test main"] = function(assert) {
assert.pass("Unit test running!");
};
exports["test main async"] = function(assert, done) {
assert.pass("async Unit test running!");
done();
};
require("sdk/test").run(exports);

View File

@ -1 +0,0 @@
postMessage({version:'1.7.3'},'*')

View File

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

View File

@ -95,8 +95,8 @@
"http": true,
"https": true,
"software": "foolfuuka",
"boards": ["cm", "hm", "r", "soc", "y"],
"files": ["cm", "hm", "r", "soc", "y"]
"boards": ["cm", "h", "hc", "hm", "r", "s", "soc", "y"],
"files": ["cm", "h", "hc", "hm", "r", "s", "soc", "y"]
}, {
"uid": 16,
"name": "maware",

View File

@ -155,6 +155,10 @@ Config =
true
'Adds a simple and cute image gallery.'
]
'PDF in Gallery': [
false
'Show PDF files in gallery.'
]
'Sauce': [
true
'Add sauce links to images.'
@ -193,15 +197,19 @@ Config =
]
'Autoplay': [
true
'Videos begin playing immediately when opened inline.'
'Videos begin playing immediately when opened.'
]
'Show Controls': [
true
'Show native seek and volume controls on videos. Contract videos when dragged to the left.'
'Show controls on videos expanded inline. Turn this off if you want to contract videos by clicking on them.'
]
'Allow Sound': [
true
'Allow sound in inline videos.'
'Allow sound in videos.'
]
'Loop in New Tab': [
true
'Loop videos opened in their own tabs, and apply settings for inline expanded videos to them.'
]
'Menu':
@ -380,7 +388,7 @@ Config =
'Highlights own posts if Quote Markers are enabled.'
]
'Quote Threading': [
true
false
'Thread conversations'
]
'Mark Quotes of You': [
@ -396,6 +404,7 @@ Config =
'Add \'(Cross-thread)\' to cross-threads quotes.'
'Highlights own posts if Quote Markers are enabled.'
]
imageExpansion:
'Fit width': [
false

View File

@ -49,6 +49,11 @@ Main =
Report.init()
return
when 'i.4cdn.org'
if Conf['Loop in New Tab'] and video = $ 'video'
Video.configure video
$.on video, 'click', ->
if !video.controls
if video.paused then video.play() else video.pause()
$.ready ->
if Conf['404 Redirect'] and d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found']
Redirect.init()

View File

@ -4,6 +4,7 @@ Settings =
link = $.el 'a',
className: 'settings-link fa fa-wrench'
textContent: 'Settings'
title: '4chan X Settings'
href: 'javascript:;'
$.on link, 'click', Settings.open

View File

@ -1465,16 +1465,20 @@ div.boardTitle {
/* Flex > Non-Flex child max-width and overflow fix (Firefox only?) */
width: 1%;
}
:root:not(.gal-fit-height) .gal-image {
:root:not(.gal-fit-height):not(.gal-pdf) .gal-image {
overflow-y: scroll !important;
}
:root:not(.gal-fit-width) .gal-image {
:root:not(.gal-fit-width):not(.gal-pdf) .gal-image {
overflow-x: scroll !important;
}
.gal-image a {
margin: auto;
line-height: 0;
}
:root.gal-pdf .gal-image a {
width: 100%;
height: 100%;
}
.gal-fit-width .gal-image video,
.gal-fit-width .gal-image img {
max-width: 100%;
@ -1483,11 +1487,22 @@ div.boardTitle {
.gal-fit-height .gal-image img {
max-height: 95vh;
}
.gal-image iframe {
width: 100%;
height: 100%;
}
.gal-buttons {
font-size: 2em;
margin-right: 10px;
margin-right: 3px;
padding-left: 7px;
padding-right: 7px;
top: 5px;
}
:root.gal-pdf .gal-buttons {
top: 40px;
background: rgba(0,0,0,0.6) !important;
border-radius: 3px;
}
.gal-buttons i {
vertical-align: baseline;
border-top-width: .4em;
@ -1507,12 +1522,12 @@ div.boardTitle {
.gal-name,
.gal-count {
position: fixed;
right: 178px;
right: 195px;
}
.gal-hide-thumbnails .gal-buttons,
.gal-hide-thumbnails .gal-count,
.gal-hide-thumbnails .gal-name {
right: 28px;
right: 44px;
}
.gal-name {
bottom: 6px;
@ -1527,6 +1542,10 @@ div.boardTitle {
.gal-buttons .menu-button:hover {
color: rgb(95, 95, 101) !important;
}
:root.gal-pdf .gal-close:hover,
:root.gal-pdf .gal-buttons .menu-button:hover {
color: rgb(204, 204, 204) !important;
}
.gal-count {
bottom: 27px;
background: rgba(0,0,0,0.6) !important;
@ -1534,21 +1553,21 @@ div.boardTitle {
padding: 1px 5px 2px 5px;
color: #ffffff !important;
}
:root:not(.gal-fit-width) .gal-name {
:root:not(.gal-fit-width):not(.gal-pdf) .gal-name {
bottom: 23px !important;
}
:root:not(.gal-fit-width) .gal-count {
:root:not(.gal-fit-width):not(.gal-pdf) .gal-count {
bottom: 44px !important;
}
:root:not(.gal-fit-height):not(.gal-hide-thumbnails) .gal-buttons,
:root:not(.gal-fit-height):not(.gal-hide-thumbnails) .gal-name,
:root:not(.gal-fit-height):not(.gal-hide-thumbnails) .gal-count {
right: 195px !important;
:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-buttons,
:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-name,
:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-count {
right: 178px !important;
}
:root.gal-hide-thumbnails:not(.gal-fit-height) .gal-buttons,
:root.gal-hide-thumbnails:not(.gal-fit-height) .gal-name,
:root.gal-hide-thumbnails:not(.gal-fit-height) .gal-count {
right: 44px !important;
:root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-buttons,
:root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-name,
:root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-count {
right: 28px !important;
}
@media screen and (resolution: 1dppx) {
.fa-bars {

View File

@ -1 +0,0 @@
postMessage({version:'<%= version %>'},'*')

View File

@ -18,7 +18,7 @@ Gallery =
cb: @node
node: ->
return unless @file?.isImage
return unless @file
if Gallery.nodes
Gallery.generateThumb $ '.file', @nodes.root
Gallery.nodes.total.textContent = Gallery.images.length
@ -64,8 +64,7 @@ Gallery =
{cb} = Gallery
$.on nodes.frame, 'click', cb.blank
$.on nodes.current, 'click', cb.download
$.on nodes.next, 'click', cb.next
$.on nodes.next, 'click', cb.advance
$.on ($ '.gal-prev', dialog), 'click', cb.prev
$.on ($ '.gal-next', dialog), 'click', cb.next
$.on ($ '.gal-close', dialog), 'click', cb.close
@ -105,13 +104,14 @@ Gallery =
generateThumb: (file) ->
post = Get.postFromNode file
return unless post.file and (post.file.isImage or post.file.isVideo or Conf['PDF in Gallery'])
title = ($ '.fileText a', file).textContent
thumb = $.el 'a',
className: 'gal-thumb'
href: post.file.URL
target: '_blank'
title = title
href: post.file.URL
target: '_blank'
title: title
thumb.dataset.id = Gallery.images.length
thumb.dataset.post = $('a[title="Highlight this post"]', post.nodes.info).href
@ -133,8 +133,10 @@ Gallery =
cb = switch key
when 'Esc', Conf['Open Gallery']
Gallery.cb.close
when 'Right', 'Enter'
when 'Right'
Gallery.cb.next
when 'Enter'
Gallery.cb.advance
when 'Left', ''
Gallery.cb.prev
@ -153,9 +155,15 @@ Gallery =
$.rmClass el, 'gal-highlight' if el = $ '.gal-highlight', Gallery.thumbs
$.addClass @, 'gal-highlight'
file = $.el (if @dataset.isVideo then 'video' else 'img'),
elType = if @dataset.isVideo then 'video' else if /\.pdf$/.test(@href) then 'iframe' else 'img'
(if elType is 'iframe' then $.addClass else $.rmClass) doc, 'gal-pdf'
file = $.el elType,
src: name.href = @href
title: name.download = name.textContent = @title
if elType is 'video'
img.loop = true
img.autoplay = Conf['Autoplay']
img.muted = !Conf['Allow Sound']
if @dataset.isVideo
file.muted = !Conf['Allow Sound']
@ -164,6 +172,7 @@ Gallery =
file.loop = true
$.extend file.dataset, @dataset
nodes.current.pause?()
$.replace nodes.current, file
nodes.count.textContent = +@dataset.id + 1
nodes.current = file
@ -192,18 +201,14 @@ Gallery =
delete post.file.fullImage
src = @src.split '/'
if src[2] is 'images.4chan.org'
if src[2] is 'i.4cdn.org'
URL = Redirect.to 'file',
boardID: src[3]
filename: src[5]
if URL
thumb.href = URL
return unless Gallery.nodes.current is img
revived = $.el 'img',
src: URL
title: img.title
$.extend revived.dataset, img.dataset
$.replace img, revived
img.src = URL
return
if g.DEAD or post.isDead or post.file.isDead
return
@ -222,10 +227,14 @@ Gallery =
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]
advance:-> if Gallery.nodes.current.paused then Gallery.nodes.current.play() else Gallery.cb.next()
pause: -> if Gallery.nodes.current.nodeType is 'VIDEO'
if Gallery.nodes.current.paused then Gallery.nodes.current.play() else Gallery.nodes.current.pause()
toggle: -> (if Gallery.nodes then Gallery.cb.close else Gallery.build)()
blank: (e) -> Gallery.cb.close() if e.target is @
close: ->
Gallery.nodes.current.pause?()
$.rm Gallery.nodes.el
delete Gallery.nodes
d.body.style.overflow = ''

View File

@ -28,9 +28,10 @@ ImageExpand =
clone = @
ImageExpand.setupVideoControls clone
unless clone.origin.file.fullImage.paused
$.queueTask -> ImageExpand.startVideo clone
$.queueTask -> Video.start clone.file.fullImage
return
else if ImageExpand.on and !@isHidden and
(Conf['Expand spoilers'] or !@file.isSpoiler) and
(Conf['Expand videos'] or !@file.isVideo)
@ -152,10 +153,8 @@ ImageExpand =
$.rmClass post.file.thumb, 'expanding'
post.file.isExpanded = true
if post.file.isVideo
post.file.fullImage.muted = !Conf['Allow Sound']
post.file.fullImage.controls = Conf['Show Controls']
ImageExpand.setupVideoControls post
ImageExpand.startVideo post if Conf['Autoplay'] and not disableAutoplay
Video.configure post.file.fullImage, disableAutoplay
videoCB: do ->
# dragging to the left contracts the video
@ -193,17 +192,6 @@ ImageExpand =
$.add file.videoControls, [$.tn('\u00A0'), contract]
$.add file.text, file.videoControls
startVideo: (post) ->
video = (file = post.file).fullImage
{controls} = video
video.controls = false
video.play()
# Hacky workaround for Firefox forever-loading bug for very short videos
if controls
$.asap (-> (video.readyState >= 3 and video.currentTime <= Math.max 0.1, (video.duration - 0.5)) or !file.isExpanded), ->
video.controls = true if file.isExpanded
, 500
error: ->
post = Get.postFromNode @
$.rm @

21
src/Images/Video.coffee Normal file
View File

@ -0,0 +1,21 @@
Video =
configure: (video, disableAutoplay) ->
video.loop = true
video.muted = !Conf['Allow Sound']
video.controls = Conf['Show Controls']
video.autoplay = false
if Conf['Autoplay'] and not disableAutoplay
Video.start video
else
video.pause()
start: (video) ->
{controls} = video
video.controls = false
video.play()
# Hacky workaround for Firefox forever-loading bug for very short videos
if controls
$.asap (-> (video.readyState >= 3 and video.currentTime <= Math.max 0.1, (video.duration - 0.5)) or !d.contains video), ->
video.controls = true
, 500

View File

@ -5,6 +5,7 @@ ThreadWatcher =
@shortcut = sc = $.el 'a',
id: 'watcher-link'
textContent: 'Watcher'
title: 'Thread Watcher'
href: 'javascript:;'
className: 'disabled fa fa-eye'