Merge branch 'master' of https://github.com/Spittie/4chan-x into v3

Conflicts:
	CHANGELOG.md
	LICENSE
	builds/4chan-X.meta.js
	builds/4chan-X.user.js
	builds/crx/script.js
	src/Archive/Redirect.coffee
	src/General/Header.coffee
	src/Monitoring/Favicon.coffee
This commit is contained in:
Zixaphir 2014-02-16 01:00:41 -07:00
commit 6dd0cac797
72 changed files with 13562 additions and 250 deletions

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
**MayhemYDG**:
- Added a `Reset Settings` button in the settings.
- More stability update.
@ -5,6 +6,54 @@
**ParrotParrot**:
- Added `Original filename` variable to Sauce panel.
=======
### v1.3.7
*2014-02-15*
**Spittie**
- Add Twitter embedding
- Add .xpi for Firefox Mobile
- Add /biz/
### v1.3.6
*2014-02-13*
**Spittie**
- Upload images directly from urls
![Upload from url](src/General/img/changelog/1.3.6.gif)
- Add gfycat.com embedding
- Replace some icons with fontawesome
- Add Metro favicons (lel)
### v1.3.5
*2014-02-10*
**Spittie**
- Fix Chrome (aka copy from Appchan)
- Add option to load the captcha when you open a thread
- Add OpenSUSE emoji
### v1.3.4
*2014-02-10*
**Spittie**
- Fix Chrome (Maybe? Hopefully I haven't fucked everything)
- Add fgst.eu
- Add mawa.re
### v1.3.3
*2014-02-09*
**MayhemYDG**
- Fix new captcha
**Spittie**
- Add archive.installgentoo.com
### v1.3.2
*2014-01-12*
>>>>>>> 7a7d0ec6860866e71e728aa9b41b1994fe1b5950
**seaweedchan**:
- Fix Menu errors on older Firefox versions, such as the ESR

View File

@ -1,8 +1,8 @@
/*
* 4chan X - Version 1.3.2 - 2014-01-28
* 4chan X - Version 1.3.7 - 2014-02-16
*
* Licensed under the MIT license.
* https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
* https://github.com/Spittie/4chan-x/blob/master/LICENSE
*
* Appchan X Copyright © 2013-2013 Zixaphir <zixaphirmoxphar@gmail.com>
* http://zixaphir.github.io/appchan-x/

View File

@ -1,27 +1,20 @@
# Get 4chan X [HERE](http://seaweedchan.github.io/4chan-x/).
Personal fork of Seaweed's 4chan X.
## Reporting bugs and suggestions
##[Install](https://github.com/Spittie/4chan-x/raw/master/builds/4chan-X.user.js) (Firefox)
##[Install](https://github.com/Spittie/4chan-x/raw/master/builds/crx.crx) (Chrom*)
##[Install](http://a.pomf.se/pmnhcu.xpi) (Firefox Mobile)
1. Make sure both your **browser** and **4chan X** are up to date.
2. Disable your other extensions & scripts to identify conflicts.
3. If your issue persists, open a [new issue](https://github.com/seaweedchan/4chan-x/issues) with the following information:
1. Precise steps to reproduce the problem, with the expected and actual results.
2. Console errors, if any.
3. Browser version.
4. Your exported settings. If your settings contains sensitive information (e.g. personas), edit the text file manually.
## If you have any problems, try resetting your 4chan X settings before calling me a faggot (but feel free to do so)
Open your console with:
- `Ctrl + Shift + J` on Chrome.
- `Ctrl + Shift + K` on Firefox.
- `Ctrl + Shift + O` on Opera.
## Development & Contribution
## Forking
### Get started
- Get started by reading through the [Help link](https://help.github.com/) on how to fork a Github project.
- Click the "Fork" button on this page.
- Install [node.js](http://nodejs.org/).
- Install [Grunt's CLI](http://gruntjs.com/) with `npm install -g grunt-cli`.
- Clone 4chan X.
- Clone your fork of 4chan X.
- `cd` into it.
- Install/Update 4chan X dependencies with `npm install`.
@ -35,10 +28,5 @@ Open your console with:
- Update the version with `grunt patch`, `grunt minor` or `grunt major`.
- Release with `grunt release`.
Note: this is only used to release new 4chan X versions, and is **not** needed or wanted in pull requests.
Note: this is only used to release new 4chan X versions, ignore as you see fit.
### Contribute
- Edit the CoffeeScript sources.
- If the edits affect regular users, edit the changelog.
- Open a pull request.

View File

@ -1,11 +1,11 @@
// ==UserScript==
// @name 4chan X
// @version 1.3.2
// @version 1.3.7
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
// @description Cross-browser userscript for maximum lurking on 4chan.
// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
// @license MIT; https://github.com/Spittie/4chan-x/blob/master/LICENSE
// @match *://boards.4chan.org/*
// @match *://sys.4chan.org/*
// @match *://a.4cdn.org/*
@ -15,8 +15,9 @@
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_openInTab
// @grant GM_xmlhttpRequest
// @run-at document-start
// @updateURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.meta.js
// @downloadURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.user.js
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC
// @updateURL https://github.com/Spittie/4chan-x/raw/stable/builds/4chan-X.meta.js
// @downloadURL https://github.com/Spittie/4chan-x/raw/stable/builds/4chan-X.user.js
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAF5JREFUeNrtkTESABAQxPD/R6tsE2dUGYUtFJvLDKf93KevHJAjpBorAQWSBIKqFASC4G0pCAkm4GfaEvgYXl0T6HBaE97f0vmnfYHbZOMLZCx9ISdKWwjOWZSC8GYm4SUGwfYgqI4AAAAASUVORK5CYII=
// ==/UserScript==

File diff suppressed because one or more lines are too long

BIN
builds/crx.crx Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

After

Width:  |  Height:  |  Size: 185 B

View File

@ -1,6 +1,6 @@
{
"name": "4chan X",
"version": "1.3.2",
"version": "1.3.7",
"manifest_version": 2,
"description": "Cross-browser userscript for maximum lurking on 4chan.",
"icons": {
@ -17,6 +17,8 @@
"homepage_url": "http://seaweedchan.github.io/4chan-x/",
"minimum_chrome_version": "31",
"permissions": [
"storage"
"storage",
"http://*/",
"https://*/"
]
}

File diff suppressed because one or more lines are too long

BIN
builds/xpi/4chanx.xpi Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,62 @@
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);
});

0
builds/xpi/doc/main.md Normal file
View File

BIN
builds/xpi/icon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
builds/xpi/icon64.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

82
builds/xpi/lib/main.js Normal file
View File

@ -0,0 +1,82 @@
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);"
});
});
}
});

9
builds/xpi/package.json Normal file
View File

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

View File

@ -0,0 +1,12 @@
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 +1 @@
postMessage({version:'1.3.2'},'*')
postMessage({version:'1.3.7'},'*')

View File

@ -1,10 +1,10 @@
{
"name": "4chan-X",
"version": "1.3.2",
"version": "1.3.7",
"description": "Cross-browser userscript for maximum lurking on 4chan.",
"meta": {
"name": "4chan X",
"repo": "https://github.com/seaweedchan/4chan-x/",
"repo": "https://github.com/Spittie/4chan-x/",
"page": "http://seaweedchan.github.io/4chan-x/",
"buildsPath": "builds/",
"mainBranch": "master",

View File

@ -24,8 +24,8 @@ Redirect =
archives: [
name: "Foolz"
boards: ["a", "co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"]
files: ["a", "gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"]
boards: ["a", "biz","co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"]
files: ["a", "biz","gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"]
data:
domain: "archive.foolz.us"
http: false
@ -49,6 +49,7 @@ Redirect =
http: true
https: true
software: "foolfuuka"
software: "foolfuuka"
,
name: "4plebs"
boards: ["adv", "hr", "o", "pol", "s4s", "tg", "tv", "x"]
@ -69,7 +70,7 @@ Redirect =
software: "foolfuuka"
,
name: "Love is Over"
boards: ["d", "i"],
boards: ["d", "i"]
files: ["d", "i"]
data:
domain: "loveisover.me"
@ -79,7 +80,6 @@ Redirect =
,
name: "Install Gentoo"
boards: ["diy", "g", "sci"]
files: []
data:
domain: "archive.installgentoo.net"
http: false
@ -112,15 +112,15 @@ Redirect =
software: "fuuka"
,
name: "fgts"
boards: ["soc"]
files: ["soc"]
boards: ["r", "soc"]
files: ["r", "soc"]
data:
domain: "fgts.eu"
domain: "fgst.eu"
http: true
https: true
software: "foolfuuka"
,
name: "maware"
name: "maware"
boards: ["t"]
files: ["t"]
data:
@ -137,8 +137,8 @@ Redirect =
software: "foolfuuka"
,
name: "Foolz Beta"
boards: ["a", "co", "d", "gd", "h", "jp", "m", "mlp", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
files: ["a", "d", "gd", "h", "jp", "m", "tg", "u", "vg", "vp", "vr", "wsg"]
boards: ["a", "co", "gd", "jp", "m", "s4s", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
files: ["a", "gd", "jp", "m", "s4s", "tg", "u", "vg", "vp", "vr", "wsg"]
data:
domain: "beta.foolz.us"
http: true

View File

@ -317,6 +317,10 @@ Config =
true
'When disabled, shows a red border on the CAPTCHA input until a key is pressed instead of a notification.'
]
'Auto-load captcha': [
false
'Automatically load the captcha when you open a thread'
]
'Quote Links':
'Quote Backlinks': [

View File

@ -803,6 +803,7 @@ span.hide-announcement {
}
#qr select,
#dump-button,
#url-button,
.remove,
.captcha-img {
cursor: pointer;
@ -857,6 +858,14 @@ span.hide-announcement {
padding: 1px 0px 2px;
opacity: 0.6;
}
#url-button {
width: 10%;
margin: 0;
margin-right: 4px;
font: 13px sans-serif;
padding: 1px 0px 2px;
opacity: 0.6;
}
.persona .field:not(#dump) {
width: 95px;
min-width: 33.3%;
@ -884,7 +893,7 @@ input.field.tripped:not(:hover):not(:focus) {
min-height: 59px;
min-width: 302px;
}
.captcha-input {
.captcha-input{
width: 100%;
margin: 1px 0 0;
}
@ -961,7 +970,7 @@ input#qr-filename:not(.edit) {
right: 0px;
}
#qr-filerm {
margin-right: 2px;
margin-right: 3px;
z-index: 2;
}
#file-n-submit {

View File

@ -27,8 +27,9 @@
<span id=qr-no-file>No selected file</span>
<input id="qr-filename" data-name="filename" spellcheck="false">
<span id=qr-extras-container>
<a id=qr-filerm href=javascript:; title='Remove file'>×</a>
<a id=dump-button title='Dump list'>+</a>
<a id=qr-filerm href=javascript:; title='Remove file'><i class="fa fa-times-circle"></i></a>
<a id=url-button title='Post from url'><i class="fa fa-link"></i></a>
<a id=dump-button title='Dump list'><i class="fa fa-plus-square"></i></a>
</span>
</span>
<label id=qr-spoiler-label>
@ -40,4 +41,4 @@
</form>
<datalist id="list-name"></datalist>
<datalist id="list-email"></datalist>
<datalist id="list-sub"></datalist>
<datalist id="list-sub"></datalist>

View File

@ -89,6 +89,7 @@
<option value=4chanJS>4chanJS</option>
<option value=Mayhem>Mayhem</option>
<option value=Original>Original</option>
<option value=Metro>Metro</option>
</select>
<span class=favicon-preview></span>
</fieldset>

BIN
src/General/img/changelog/1.1.18.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
src/General/img/changelog/1.2.0.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

BIN
src/General/img/emoji/SS-sage.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 576 B

After

Width:  |  Height:  |  Size: 565 B

BIN
src/General/img/emoji/arch.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 567 B

After

Width:  |  Height:  |  Size: 563 B

BIN
src/General/img/emoji/centos.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 858 B

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 556 B

BIN
src/General/img/emoji/fedora.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 631 B

After

Width:  |  Height:  |  Size: 627 B

BIN
src/General/img/emoji/freebsd.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 919 B

BIN
src/General/img/emoji/gentoo.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 B

After

Width:  |  Height:  |  Size: 879 B

BIN
src/General/img/emoji/gnu.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 607 B

BIN
src/General/img/emoji/madotsuki.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 230 B

BIN
src/General/img/emoji/mint.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 B

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 B

BIN
src/General/img/emoji/ponyo.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

After

Width:  |  Height:  |  Size: 883 B

BIN
src/General/img/emoji/rabite.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
src/General/img/emoji/sabayon.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

After

Width:  |  Height:  |  Size: 829 B

BIN
src/General/img/emoji/trisquel.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 820 B

After

Width:  |  Height:  |  Size: 814 B

BIN
src/General/img/emoji/ubuntu.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 625 B

After

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

BIN
src/General/img/icon16.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

After

Width:  |  Height:  |  Size: 154 B

BIN
src/General/img/icon48.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

BIN
src/General/img/links/gist.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 683 B

After

Width:  |  Height:  |  Size: 667 B

BIN
src/General/img/links/installgentoo.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 729 B

BIN
src/General/img/links/liveleak.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 952 B

After

Width:  |  Height:  |  Size: 740 B

BIN
src/General/img/links/pastebin.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 871 B

After

Width:  |  Height:  |  Size: 839 B

BIN
src/General/img/links/vimeo.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 307 B

View File

@ -17,6 +17,8 @@
"homepage_url": "<%= meta.page %>",
"minimum_chrome_version": "<%= meta.min.chrome %>",
"permissions": [
"storage"
"storage",
"http://*/",
"https://*/"
]
}

View File

@ -16,6 +16,7 @@
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_openInTab
// @grant GM_xmlhttpRequest
// @run-at document-start
// @updateURL <%= meta.repo %>raw/stable/builds/<%= meta.files.metajs %>
// @downloadURL <%= meta.repo %>raw/stable/builds/<%= meta.files.userjs %>

View File

@ -284,6 +284,12 @@ Linkify =
el: (a) ->
$.el 'iframe',
src: "http://paste.installgentoo.com/view/embed/#{a.dataset.uid}"
Twitter:
regExp: /.*twitter.com\/(.+\/status\/\d+)/
el: (a) ->
$.el 'iframe',
src: "https://twitframe.com/show?url=https://twitter.com/#{a.dataset.uid}"
LiveLeak:
regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/
@ -334,6 +340,12 @@ Linkify =
div = $.el 'iframe',
src: "http://pastebin.com/embed_iframe.php?i=#{a.dataset.uid}"
gfycat:
regExp: /.*gfycat.com\/(?:iframe\/)?(\S*)/
el: (a) ->
div = $.el 'iframe',
src: "http://gfycat.com/iframe/#{a.dataset.uid}"
SoundCloud:
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
style: 'height: auto; width: 500px; display: inline-block;'

View File

@ -46,6 +46,7 @@ a.useremail[href*='#{name.toUpperCase()}']:last-of-type::#{pos} {
'FreeBSD': '<%= grunt.file.read("src/General/img/emoji/freebsd.png", {encoding: "base64"}) %>'
'Gentoo': '<%= grunt.file.read("src/General/img/emoji/gentoo.png", {encoding: "base64"}) %>'
'Mint': '<%= grunt.file.read("src/General/img/emoji/mint.png", {encoding: "base64"}) %>'
'OpenSUSE': '<%= grunt.file.read("src/General/img/emoji/opensuse.png", {encoding: "base64"}) %>'
'Osx': '<%= grunt.file.read("src/General/img/emoji/osx.png", {encoding: "base64"}) %>'
'Rhel': '<%= grunt.file.read("src/General/img/emoji/rhel.png", {encoding: "base64"}) %>'
'Sabayon': '<%= grunt.file.read("src/General/img/emoji/sabayon.png", {encoding: "base64"}) %>'

View File

@ -51,6 +51,14 @@ Favicon =
'<%= grunt.file.read("src/General/img/favicons/Original/unreadNSFW.png", {encoding: "base64"}) %>'
'<%= grunt.file.read("src/General/img/favicons/Original/unreadNSFWY.png", {encoding: "base64"}) %>'
]
'Metro': [
'<%= grunt.file.read("src/General/img/favicons/Metro/unreadDead.png", {encoding: "base64"}) %>'
'<%= grunt.file.read("src/General/img/favicons/Metro/unreadDeadY.png", {encoding: "base64"}) %>'
'<%= grunt.file.read("src/General/img/favicons/Metro/unreadSFW.png", {encoding: "base64"}) %>'
'<%= grunt.file.read("src/General/img/favicons/Metro/unreadSFWY.png", {encoding: "base64"}) %>'
'<%= grunt.file.read("src/General/img/favicons/Metro/unreadNSFW.png", {encoding: "base64"}) %>'
'<%= grunt.file.read("src/General/img/favicons/Metro/unreadNSFWY.png", {encoding: "base64"}) %>'
]
}[Conf['favicon']]
f = Favicon
@ -58,9 +66,10 @@ Favicon =
i = 0
while items[i]
items[i] = t + items[i++]
[f.unreadDead, funreadDeadY, f.unreadSFW, f.unreadSFWY, f.unreadNSFW, f.unreadNSFWY] = items
f.update()
update: ->
if @SFW
@unread = @unreadSFW

View File

@ -1,52 +1,64 @@
QR.captcha =
init: ->
return if d.cookie.indexOf('pass_enabled=1') >= 0
return unless @isEnabled = !!$.id 'captchaFormPart'
$.asap (-> $.id 'recaptcha_challenge_field_holder'), @ready.bind @
container = $.id 'captchaContainer'
return unless @isEnabled = !!container
ready: ->
setLifetime = (e) => @lifetime = e.detail
$.on window, 'captcha:timeout', setLifetime
$.globalEval 'window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))'
$.off window, 'captcha:timeout', setLifetime
$.globalEval 'loadRecaptcha()' if Conf['Auto-load captcha']
imgContainer = $.el 'div',
className: 'captcha-img'
title: 'Reload reCAPTCHA'
innerHTML: '<img>'
hidden: true
input = $.el 'input',
className: 'captcha-input field'
title: 'Verification'
placeholder: 'Focus to load reCAPTCHA'
autocomplete: 'off'
spellcheck: false
tabIndex: 55
tabIndex: 45
@nodes =
challenge: $.id 'recaptcha_challenge_field_holder'
img: imgContainer.firstChild
input: input
new MutationObserver(@load.bind @).observe @nodes.challenge,
childList: true
$.on input, 'focus', @setup
$.on imgContainer, 'click', @reload.bind @
$.on input, 'keydown', @keydown.bind @
$.on input, 'focus', -> $.addClass QR.nodes.el, 'focus'
$.on input, 'blur', -> $.rmClass QR.nodes.el, 'focus'
$.get 'captchas', [], ({captchas}) =>
@sync captchas
$.sync 'captchas', @sync
# start with an uncached captcha
@reload()
<% if (type === 'userscript') { %>
# XXX Firefox lacks focusin/focusout support.
$.on input, 'blur', QR.focusout
$.on input, 'focus', QR.focusin
<% } %>
$.addClass QR.nodes.el, 'has-captcha'
$.after QR.nodes.com.parentNode, [imgContainer, input]
@setupObserver = new MutationObserver @afterSetup
@setupObserver.observe container, childList: true
@afterSetup() # reCAPTCHA might have loaded before the QR.
setup: ->
$.globalEval 'loadRecaptcha()'
afterSetup: ->
return unless challenge = $.id 'recaptcha_challenge_field_holder'
QR.captcha.setupObserver.disconnect()
delete QR.captcha.setupObserver
setLifetime = (e) -> QR.captcha.lifetime = e.detail
$.on window, 'captcha:timeout', setLifetime
$.globalEval 'window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))'
$.off window, 'captcha:timeout', setLifetime
{img, input} = QR.captcha.nodes
img.parentNode.hidden = false
$.off input, 'focus', QR.captcha.setup
$.on input, 'keydown', QR.captcha.keydown.bind QR.captcha
$.on img.parentNode, 'click', QR.captcha.reload.bind QR.captcha
$.get 'captchas', [], ({captchas}) ->
QR.captcha.sync captchas
$.sync 'captchas', QR.captcha.sync
QR.captcha.nodes.challenge = challenge
new MutationObserver(QR.captcha.load.bind QR.captcha).observe challenge,
childList: true
QR.captcha.load()
sync: (captchas) ->
QR.captcha.captchas = captchas
@ -79,6 +91,7 @@ QR.captcha =
$.set 'captchas', @captchas
clear: ->
return unless @captchas.length
now = Date.now()
for captcha, i in @captchas
break if captcha.timeout > now
@ -98,7 +111,7 @@ QR.captcha =
@clear()
count: ->
count = @captchas.length
count = if @captchas then @captchas.length else 0
@nodes.input.placeholder = switch count
when 0
'Verification (Shift + Enter to cache)'

View File

@ -119,15 +119,9 @@ QR =
QR.cooldown.auto = false
QR.status()
focusin: ->
$.addClass QR.nodes.el, 'has-focus'
$.addClass QR.nodes.el, 'focus'
focusout: ->
<% if (type === 'crx') { %>
$.rmClass QR.nodes.el, 'has-focus'
<% } else { %>
$.queueTask ->
return if $.x 'ancestor::div[@id="qr"]', d.activeElement
$.rmClass QR.nodes.el, 'has-focus'
<% } %>
$.rmClass QR.nodes.el, 'focus'
hide: ->
d.activeElement.blur()
$.addClass QR.nodes.el, 'autohide'
@ -278,6 +272,69 @@ QR =
QR.open()
QR.handleFiles files
$.addClass QR.nodes.el, 'dump'
handleBlob: (blob) ->
return if blob.type is null
QR.error "Unsupported file type."
return unless blob.type in QR.mimeTypes
QR.error "Unsupported file type."
QR.handleFiles([blob])
handleUrl: ->
url = prompt("Insert an url:")
return if url is null
<% if (type === 'crx') { %>
xhr = new XMLHttpRequest();
xhr.open('GET', url, true)
xhr.responseType = 'blob'
xhr.onload = (e) ->
if @readyState is @DONE && xhr.status is 200
urlBlob = new Blob([@response], {type : @getResponseHeader('content-type')})
urlBlob.name = url.substr(url.lastIndexOf('/')+1, url.length)
QR.handleBlob(urlBlob)
return
else
QR.error "Can't load image."
return
xhr.onerror = (e) ->
QR.error "Can't load image."
return
xhr.send()
return
<% } %>
<% if (type === 'userscript') { %>
GM_xmlhttpRequest {
method: "GET",
url: url,
overrideMimeType: "text/plain; charset=x-user-defined",
onload: (xhr) ->
r = xhr.responseText
data = new Uint8Array(r.length)
i = 0
while i < r.length
data[i] = r.charCodeAt(i)
i++
#QUALITY coding at work
header = xhr.responseHeaders
start = header.indexOf("Content-Type: ") + 14
end = header.substr(start, header.length).indexOf("\n") - 1
mime = header.substr(start, end)
return if mime is null
urlBlob = new Blob([data], {type: mime})
urlBlob.name = url.substr(url.lastIndexOf('/')+1, url.length)
QR.handleBlob(urlBlob)
return
onerror: (xhr) ->
QR.error "Can't load image."
}
return
<% } %>
handleFiles: (files) ->
if @ isnt QR # file input
@ -354,6 +411,7 @@ QR =
close: '.close'
form: 'form'
dumpButton: '#dump-button'
urlButton: '#url-button'
name: '[data-name=name]'
email: '[data-name=email]'
sub: '[data-name=sub]'
@ -411,20 +469,16 @@ QR =
$.on nodes.filename.parentNode, 'click keydown', QR.openFileInput
<% if (type === 'userscript') { %>
# XXX Firefox lacks focusin/focusout support.
items = $$ '*', QR.nodes.el
i = 0
while elm = items[i++]
$.on elm, 'blur', QR.focusout
$.on elm, 'focus', QR.focusin
<% } %>
$.on dialog, 'focusin', QR.focusin
$.on dialog, 'focusout', QR.focusout
$.on nodes.autohide, 'change', QR.toggleHide
$.on nodes.close, 'click', QR.close
$.on nodes.dumpButton, 'click', -> nodes.el.classList.toggle 'dump'
$.on nodes.urlButton, 'click', QR.handleUrl
$.on nodes.addPost, 'click', -> new QR.post true
$.on nodes.form, 'submit', QR.submit
$.on nodes.fileRM, 'click', -> QR.selected.rmFile()

View File

@ -262,4 +262,4 @@ QR.post = class
(if oldIndex < newIndex then $.after else $.before) @, el
post = QR.posts.splice(oldIndex, 1)[0]
QR.posts.splice newIndex, 0, post
QR.status()
QR.status()