Release 4chan X v1.7.52.
This commit is contained in:
parent
c8d29b6741
commit
f67675ec11
@ -1,3 +1,9 @@
|
||||
### v1.7.52
|
||||
*2014-06-02*
|
||||
|
||||
**ccd0**
|
||||
- Add workaround for downloading with the original filename in Firefox.
|
||||
|
||||
### v1.7.51
|
||||
*2014-06-02*
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ module.exports = (grunt) ->
|
||||
'src/General/Get.coffee'
|
||||
'src/General/UI.coffee'
|
||||
'src/General/Notice.coffee'
|
||||
'src/General/CrossOrigin.coffee'
|
||||
'src/Filtering/**/*.coffee'
|
||||
'src/Quotelinks/**/*.coffee'
|
||||
'src/Posting/QR.coffee'
|
||||
|
||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 4chan X - Version 1.7.51 - 2014-06-02
|
||||
* 4chan X - Version 1.7.52 - 2014-06-02
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.7.51
|
||||
// @version 1.7.52
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.7.51
|
||||
// @version 1.7.52
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -24,7 +24,7 @@
|
||||
// ==/UserScript==
|
||||
|
||||
/*
|
||||
* 4chan X - Version 1.7.51 - 2014-06-02
|
||||
* 4chan X - Version 1.7.52 - 2014-06-02
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
@ -106,7 +106,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, TrashQueue, UI, Unread, Video, c, d, doc, g,
|
||||
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, TrashQueue, UI, Unread, Video, c, d, doc, g,
|
||||
__slice = [].slice,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
@ -194,6 +194,7 @@
|
||||
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
||||
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
||||
'Delete Link': [true, 'Add post and image deletion links to the menu.'],
|
||||
'Download Link': [true, 'Add a download with original filename link to the menu.'],
|
||||
'Archive Link': [true, 'Add an archive link to the menu.']
|
||||
},
|
||||
'Monitoring': {
|
||||
@ -372,7 +373,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.7.51',
|
||||
VERSION: '1.7.52',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -4016,6 +4017,50 @@
|
||||
};
|
||||
})();
|
||||
|
||||
CrossOrigin = (function() {
|
||||
var handleBlob, handleUrl;
|
||||
handleBlob = function(urlBlob, contentType, contentDisposition, url, cb) {
|
||||
var blob, match, mime, name, _ref, _ref1, _ref2;
|
||||
name = (_ref = url.match(/([^\/]+)\/*$/)) != null ? _ref[1] : void 0;
|
||||
mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream';
|
||||
match = (contentDisposition != null ? (_ref1 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref1[1] : void 0 : void 0) || (contentType != null ? (_ref2 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref2[1] : void 0 : void 0);
|
||||
if (match) {
|
||||
name = match.replace(/\\"/g, '"');
|
||||
}
|
||||
blob = new Blob([urlBlob], {
|
||||
type: mime
|
||||
});
|
||||
blob.name = name;
|
||||
return cb(blob);
|
||||
};
|
||||
handleUrl = function(url, cb) {
|
||||
return GM_xmlhttpRequest({
|
||||
method: "GET",
|
||||
url: url,
|
||||
overrideMimeType: "text/plain; charset=x-user-defined",
|
||||
onload: function(xhr) {
|
||||
var contentDisposition, contentType, data, i, r, _ref, _ref1;
|
||||
r = xhr.responseText;
|
||||
data = new Uint8Array(r.length);
|
||||
i = 0;
|
||||
while (i < r.length) {
|
||||
data[i] = r.charCodeAt(i);
|
||||
i++;
|
||||
}
|
||||
contentType = (_ref = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)) != null ? _ref[1] : void 0;
|
||||
contentDisposition = (_ref1 = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)) != null ? _ref1[1] : void 0;
|
||||
return handleBlob(data, contentType, contentDisposition, url, cb);
|
||||
},
|
||||
onerror: function(xhr) {
|
||||
return cb(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
return {
|
||||
request: handleUrl
|
||||
};
|
||||
})();
|
||||
|
||||
Anonymize = {
|
||||
init: function() {
|
||||
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
||||
@ -6052,44 +6097,16 @@
|
||||
QR.handleFiles(files);
|
||||
return $.addClass(QR.nodes.el, 'dump');
|
||||
},
|
||||
handleBlob: function(urlBlob, contentType, contentDisposition, url) {
|
||||
var blob, match, mime, name, _ref, _ref1, _ref2;
|
||||
name = (_ref = url.match(/([^\/]+)\/*$/)) != null ? _ref[1] : void 0;
|
||||
mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream';
|
||||
match = (contentDisposition != null ? (_ref1 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref1[1] : void 0 : void 0) || (contentType != null ? (_ref2 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref2[1] : void 0 : void 0);
|
||||
if (match) {
|
||||
name = match.replace(/\\"/g, '"');
|
||||
}
|
||||
blob = new Blob([urlBlob], {
|
||||
type: mime
|
||||
});
|
||||
blob.name = name;
|
||||
return QR.handleFiles([blob]);
|
||||
},
|
||||
handleUrl: function() {
|
||||
var url;
|
||||
url = prompt("Insert an url:");
|
||||
if (url === null) {
|
||||
return;
|
||||
}
|
||||
return GM_xmlhttpRequest({
|
||||
method: "GET",
|
||||
url: url,
|
||||
overrideMimeType: "text/plain; charset=x-user-defined",
|
||||
onload: function(xhr) {
|
||||
var contentDisposition, contentType, data, i, r, _ref, _ref1;
|
||||
r = xhr.responseText;
|
||||
data = new Uint8Array(r.length);
|
||||
i = 0;
|
||||
while (i < r.length) {
|
||||
data[i] = r.charCodeAt(i);
|
||||
i++;
|
||||
}
|
||||
contentType = (_ref = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)) != null ? _ref[1] : void 0;
|
||||
contentDisposition = (_ref1 = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)) != null ? _ref1[1] : void 0;
|
||||
return QR.handleBlob(data, contentType, contentDisposition, url);
|
||||
},
|
||||
onerror: function(xhr) {
|
||||
return CrossOrigin.request(url, function(blob) {
|
||||
if (blob) {
|
||||
return QR.handleFiles([blob]);
|
||||
} else {
|
||||
return QR.error("Can't load image.");
|
||||
}
|
||||
});
|
||||
@ -9320,6 +9337,24 @@
|
||||
className: 'download-link',
|
||||
textContent: 'Download file'
|
||||
});
|
||||
if (typeof chrome === "undefined" || chrome === null) {
|
||||
$.on(a, 'click', function(e) {
|
||||
if (this.protocol === 'blob:') {
|
||||
return true;
|
||||
}
|
||||
e.preventDefault();
|
||||
return CrossOrigin.request(this.href, (function(_this) {
|
||||
return function(blob) {
|
||||
if (blob) {
|
||||
_this.href = URL.createObjectURL(blob);
|
||||
return _this.click();
|
||||
} else {
|
||||
return new Notice('error', "Could not download " + file.URL, 30);
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
});
|
||||
}
|
||||
return $.event('AddMenuEntry', {
|
||||
type: 'post',
|
||||
el: a,
|
||||
@ -12444,7 +12479,7 @@
|
||||
Settings.dialog = dialog = $.el('div', {
|
||||
id: 'fourchanx-settings',
|
||||
className: 'dialog',
|
||||
innerHTML: '<nav><div class=sections-list></div><p class=\'imp-exp-result warning\'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href=\'https://github.com/ccd0/4chan-x\' target=_blank>4chan X</a> | <a href=\'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md\' target=_blank>1.7.51</a> | <a href=\'https://github.com/ccd0/4chan-x/issues\' target=_blank>Issues</a> | <a href=javascript:; class=\'close fa fa-times\' title=Close></a></div></nav><div class=section-container><section></section></div>'
|
||||
innerHTML: '<nav><div class=sections-list></div><p class=\'imp-exp-result warning\'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href=\'https://github.com/ccd0/4chan-x\' target=_blank>4chan X</a> | <a href=\'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md\' target=_blank>1.7.52</a> | <a href=\'https://github.com/ccd0/4chan-x/issues\' target=_blank>Issues</a> | <a href=javascript:; class=\'close fa fa-times\' title=Close></a></div></nav><div class=section-container><section></section></div>'
|
||||
});
|
||||
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||
@ -13289,7 +13324,7 @@
|
||||
}
|
||||
if (previousversion) {
|
||||
el = $.el('span', {
|
||||
innerHTML: '4chan X has been updated to <a href="https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md" target="_blank">version 1.7.51</a>.'
|
||||
innerHTML: '4chan X has been updated to <a href="https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md" target="_blank">version 1.7.52</a>.'
|
||||
});
|
||||
new Notice('info', el, 15);
|
||||
} else {
|
||||
|
||||
Binary file not shown.
BIN
builds/crx.crx
BIN
builds/crx.crx
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "4chan X",
|
||||
"version": "1.7.51",
|
||||
"version": "1.7.52",
|
||||
"manifest_version": 2,
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"icons": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Generated by CoffeeScript
|
||||
/*
|
||||
* 4chan X - Version 1.7.51 - 2014-06-02
|
||||
* 4chan X - Version 1.7.52 - 2014-06-02
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
@ -82,7 +82,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, TrashQueue, UI, Unread, Video, c, d, doc, g,
|
||||
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, TrashQueue, UI, Unread, Video, c, d, doc, g,
|
||||
__slice = [].slice,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
@ -170,7 +170,7 @@
|
||||
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
||||
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
||||
'Delete Link': [true, 'Add post and image deletion links to the menu.'],
|
||||
'Download Link': [true, 'Add a download with original filename link to the menu. Chrome-only currently.'],
|
||||
'Download Link': [true, 'Add a download with original filename link to the menu.'],
|
||||
'Archive Link': [true, 'Add an archive link to the menu.']
|
||||
},
|
||||
'Monitoring': {
|
||||
@ -348,7 +348,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.7.51',
|
||||
VERSION: '1.7.52',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -4045,6 +4045,47 @@
|
||||
};
|
||||
})();
|
||||
|
||||
CrossOrigin = (function() {
|
||||
var handleBlob, handleUrl;
|
||||
handleBlob = function(urlBlob, contentType, contentDisposition, url, cb) {
|
||||
var blob, match, mime, name, _ref, _ref1, _ref2;
|
||||
name = (_ref = url.match(/([^\/]+)\/*$/)) != null ? _ref[1] : void 0;
|
||||
mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream';
|
||||
match = (contentDisposition != null ? (_ref1 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref1[1] : void 0 : void 0) || (contentType != null ? (_ref2 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref2[1] : void 0 : void 0);
|
||||
if (match) {
|
||||
name = match.replace(/\\"/g, '"');
|
||||
}
|
||||
blob = new Blob([urlBlob], {
|
||||
type: mime
|
||||
});
|
||||
blob.name = name;
|
||||
return cb(blob);
|
||||
};
|
||||
handleUrl = function(url, cb) {
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function(e) {
|
||||
var contentDisposition, contentType;
|
||||
if (this.readyState === this.DONE && xhr.status === 200) {
|
||||
contentType = this.getResponseHeader('Content-Type');
|
||||
contentDisposition = this.getResponseHeader('Content-Disposition');
|
||||
return handleBlob(this.response, contentType, contentDisposition, url, cb);
|
||||
} else {
|
||||
return cb(null);
|
||||
}
|
||||
};
|
||||
xhr.onerror = function(e) {
|
||||
return cb(null);
|
||||
};
|
||||
return xhr.send();
|
||||
};
|
||||
return {
|
||||
request: handleUrl
|
||||
};
|
||||
})();
|
||||
|
||||
Anonymize = {
|
||||
init: function() {
|
||||
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
||||
@ -6090,43 +6131,19 @@
|
||||
QR.handleFiles(files);
|
||||
return $.addClass(QR.nodes.el, 'dump');
|
||||
},
|
||||
handleBlob: function(urlBlob, contentType, contentDisposition, url) {
|
||||
var blob, match, mime, name, _ref, _ref1, _ref2;
|
||||
name = (_ref = url.match(/([^\/]+)\/*$/)) != null ? _ref[1] : void 0;
|
||||
mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream';
|
||||
match = (contentDisposition != null ? (_ref1 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref1[1] : void 0 : void 0) || (contentType != null ? (_ref2 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref2[1] : void 0 : void 0);
|
||||
if (match) {
|
||||
name = match.replace(/\\"/g, '"');
|
||||
}
|
||||
blob = new Blob([urlBlob], {
|
||||
type: mime
|
||||
});
|
||||
blob.name = name;
|
||||
return QR.handleFiles([blob]);
|
||||
},
|
||||
handleUrl: function() {
|
||||
var url, xhr;
|
||||
var url;
|
||||
url = prompt("Insert an url:");
|
||||
if (url === null) {
|
||||
return;
|
||||
}
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function(e) {
|
||||
var contentDisposition, contentType;
|
||||
if (this.readyState === this.DONE && xhr.status === 200) {
|
||||
contentType = this.getResponseHeader('Content-Type');
|
||||
contentDisposition = this.getResponseHeader('Content-Disposition');
|
||||
return QR.handleBlob(this.response, contentType, contentDisposition, url);
|
||||
return CrossOrigin.request(url, function(blob) {
|
||||
if (blob) {
|
||||
return QR.handleFiles([blob]);
|
||||
} else {
|
||||
return QR.error("Can't load image.");
|
||||
}
|
||||
};
|
||||
xhr.onerror = function(e) {
|
||||
return QR.error("Can't load image.");
|
||||
};
|
||||
return xhr.send();
|
||||
});
|
||||
},
|
||||
handleFiles: function(files) {
|
||||
var file, i, _i, _len;
|
||||
@ -12438,7 +12455,7 @@
|
||||
Settings.dialog = dialog = $.el('div', {
|
||||
id: 'fourchanx-settings',
|
||||
className: 'dialog',
|
||||
innerHTML: '<nav><div class=sections-list></div><p class=\'imp-exp-result warning\'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href=\'https://github.com/ccd0/4chan-x\' target=_blank>4chan X</a> | <a href=\'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md\' target=_blank>1.7.51</a> | <a href=\'https://github.com/ccd0/4chan-x/issues\' target=_blank>Issues</a> | <a href=javascript:; class=\'close fa fa-times\' title=Close></a></div></nav><div class=section-container><section></section></div>'
|
||||
innerHTML: '<nav><div class=sections-list></div><p class=\'imp-exp-result warning\'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href=\'https://github.com/ccd0/4chan-x\' target=_blank>4chan X</a> | <a href=\'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md\' target=_blank>1.7.52</a> | <a href=\'https://github.com/ccd0/4chan-x/issues\' target=_blank>Issues</a> | <a href=javascript:; class=\'close fa fa-times\' title=Close></a></div></nav><div class=section-container><section></section></div>'
|
||||
});
|
||||
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||
@ -13270,7 +13287,7 @@
|
||||
}
|
||||
if (previousversion) {
|
||||
el = $.el('span', {
|
||||
innerHTML: '4chan X has been updated to <a href="https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md" target="_blank">version 1.7.51</a>.'
|
||||
innerHTML: '4chan X has been updated to <a href="https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md" target="_blank">version 1.7.52</a>.'
|
||||
});
|
||||
new Notice('info', el, 15);
|
||||
} else {
|
||||
|
||||
@ -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.51' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.52' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "4chan X",
|
||||
"version": "1.7.51",
|
||||
"version": "1.7.52",
|
||||
"manifest_version": 2,
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"icons": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Generated by CoffeeScript
|
||||
/*
|
||||
* 4chan X - Version 1.7.51 - 2014-06-02
|
||||
* 4chan X - Version 1.7.52 - 2014-06-02
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
@ -82,7 +82,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, TrashQueue, UI, Unread, Video, c, d, doc, g,
|
||||
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, TrashQueue, UI, Unread, Video, c, d, doc, g,
|
||||
__slice = [].slice,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
@ -170,7 +170,7 @@
|
||||
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
||||
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
||||
'Delete Link': [true, 'Add post and image deletion links to the menu.'],
|
||||
'Download Link': [true, 'Add a download with original filename link to the menu. Chrome-only currently.'],
|
||||
'Download Link': [true, 'Add a download with original filename link to the menu.'],
|
||||
'Archive Link': [true, 'Add an archive link to the menu.']
|
||||
},
|
||||
'Monitoring': {
|
||||
@ -348,7 +348,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.7.51',
|
||||
VERSION: '1.7.52',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -4045,6 +4045,47 @@
|
||||
};
|
||||
})();
|
||||
|
||||
CrossOrigin = (function() {
|
||||
var handleBlob, handleUrl;
|
||||
handleBlob = function(urlBlob, contentType, contentDisposition, url, cb) {
|
||||
var blob, match, mime, name, _ref, _ref1, _ref2;
|
||||
name = (_ref = url.match(/([^\/]+)\/*$/)) != null ? _ref[1] : void 0;
|
||||
mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream';
|
||||
match = (contentDisposition != null ? (_ref1 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref1[1] : void 0 : void 0) || (contentType != null ? (_ref2 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref2[1] : void 0 : void 0);
|
||||
if (match) {
|
||||
name = match.replace(/\\"/g, '"');
|
||||
}
|
||||
blob = new Blob([urlBlob], {
|
||||
type: mime
|
||||
});
|
||||
blob.name = name;
|
||||
return cb(blob);
|
||||
};
|
||||
handleUrl = function(url, cb) {
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function(e) {
|
||||
var contentDisposition, contentType;
|
||||
if (this.readyState === this.DONE && xhr.status === 200) {
|
||||
contentType = this.getResponseHeader('Content-Type');
|
||||
contentDisposition = this.getResponseHeader('Content-Disposition');
|
||||
return handleBlob(this.response, contentType, contentDisposition, url, cb);
|
||||
} else {
|
||||
return cb(null);
|
||||
}
|
||||
};
|
||||
xhr.onerror = function(e) {
|
||||
return cb(null);
|
||||
};
|
||||
return xhr.send();
|
||||
};
|
||||
return {
|
||||
request: handleUrl
|
||||
};
|
||||
})();
|
||||
|
||||
Anonymize = {
|
||||
init: function() {
|
||||
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
||||
@ -6090,43 +6131,19 @@
|
||||
QR.handleFiles(files);
|
||||
return $.addClass(QR.nodes.el, 'dump');
|
||||
},
|
||||
handleBlob: function(urlBlob, contentType, contentDisposition, url) {
|
||||
var blob, match, mime, name, _ref, _ref1, _ref2;
|
||||
name = (_ref = url.match(/([^\/]+)\/*$/)) != null ? _ref[1] : void 0;
|
||||
mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream';
|
||||
match = (contentDisposition != null ? (_ref1 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref1[1] : void 0 : void 0) || (contentType != null ? (_ref2 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? _ref2[1] : void 0 : void 0);
|
||||
if (match) {
|
||||
name = match.replace(/\\"/g, '"');
|
||||
}
|
||||
blob = new Blob([urlBlob], {
|
||||
type: mime
|
||||
});
|
||||
blob.name = name;
|
||||
return QR.handleFiles([blob]);
|
||||
},
|
||||
handleUrl: function() {
|
||||
var url, xhr;
|
||||
var url;
|
||||
url = prompt("Insert an url:");
|
||||
if (url === null) {
|
||||
return;
|
||||
}
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function(e) {
|
||||
var contentDisposition, contentType;
|
||||
if (this.readyState === this.DONE && xhr.status === 200) {
|
||||
contentType = this.getResponseHeader('Content-Type');
|
||||
contentDisposition = this.getResponseHeader('Content-Disposition');
|
||||
return QR.handleBlob(this.response, contentType, contentDisposition, url);
|
||||
return CrossOrigin.request(url, function(blob) {
|
||||
if (blob) {
|
||||
return QR.handleFiles([blob]);
|
||||
} else {
|
||||
return QR.error("Can't load image.");
|
||||
}
|
||||
};
|
||||
xhr.onerror = function(e) {
|
||||
return QR.error("Can't load image.");
|
||||
};
|
||||
return xhr.send();
|
||||
});
|
||||
},
|
||||
handleFiles: function(files) {
|
||||
var file, i, _i, _len;
|
||||
@ -12438,7 +12455,7 @@
|
||||
Settings.dialog = dialog = $.el('div', {
|
||||
id: 'fourchanx-settings',
|
||||
className: 'dialog',
|
||||
innerHTML: '<nav><div class=sections-list></div><p class=\'imp-exp-result warning\'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href=\'https://github.com/ccd0/4chan-x\' target=_blank>4chan X</a> | <a href=\'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md\' target=_blank>1.7.51</a> | <a href=\'https://github.com/ccd0/4chan-x/issues\' target=_blank>Issues</a> | <a href=javascript:; class=\'close fa fa-times\' title=Close></a></div></nav><div class=section-container><section></section></div>'
|
||||
innerHTML: '<nav><div class=sections-list></div><p class=\'imp-exp-result warning\'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href=\'https://github.com/ccd0/4chan-x\' target=_blank>4chan X</a> | <a href=\'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md\' target=_blank>1.7.52</a> | <a href=\'https://github.com/ccd0/4chan-x/issues\' target=_blank>Issues</a> | <a href=javascript:; class=\'close fa fa-times\' title=Close></a></div></nav><div class=section-container><section></section></div>'
|
||||
});
|
||||
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||
@ -13270,7 +13287,7 @@
|
||||
}
|
||||
if (previousversion) {
|
||||
el = $.el('span', {
|
||||
innerHTML: '4chan X has been updated to <a href="https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md" target="_blank">version 1.7.51</a>.'
|
||||
innerHTML: '4chan X has been updated to <a href="https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md" target="_blank">version 1.7.52</a>.'
|
||||
});
|
||||
new Notice('info', el, 15);
|
||||
} else {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "4chan-X",
|
||||
"version": "1.7.51",
|
||||
"version": "1.7.52",
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"meta": {
|
||||
"name": "4chan X",
|
||||
|
||||
@ -229,12 +229,10 @@ Config =
|
||||
true
|
||||
'Add post and image deletion links to the menu.'
|
||||
]
|
||||
<% if (type === 'crx') { %>
|
||||
'Download Link': [
|
||||
true
|
||||
'Add a download with original filename link to the menu. Chrome-only currently.'
|
||||
'Add a download with original filename link to the menu.'
|
||||
]
|
||||
<% } %>
|
||||
'Archive Link': [
|
||||
true
|
||||
'Add an archive link to the menu.'
|
||||
|
||||
52
src/General/CrossOrigin.coffee
Normal file
52
src/General/CrossOrigin.coffee
Normal file
@ -0,0 +1,52 @@
|
||||
CrossOrigin = do ->
|
||||
|
||||
handleBlob = (urlBlob, contentType, contentDisposition, url, cb) ->
|
||||
name = url.match(/([^\/]+)\/*$/)?[1]
|
||||
mime = contentType?.match(/[^;]*/)[0] or 'application/octet-stream'
|
||||
match =
|
||||
contentDisposition?.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)?[1] or
|
||||
contentType?.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)?[1]
|
||||
if match
|
||||
name = match.replace /\\"/g, '"'
|
||||
blob = new Blob([urlBlob], {type: mime})
|
||||
blob.name = name
|
||||
cb blob
|
||||
|
||||
handleUrl = (url, cb) ->
|
||||
<% 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
|
||||
contentType = @getResponseHeader('Content-Type')
|
||||
contentDisposition = @getResponseHeader('Content-Disposition')
|
||||
handleBlob @response, contentType, contentDisposition, url, cb
|
||||
else
|
||||
cb null
|
||||
xhr.onerror = (e) ->
|
||||
cb null
|
||||
xhr.send()
|
||||
<% } %>
|
||||
|
||||
<% 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++
|
||||
contentType = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)?[1]
|
||||
contentDisposition = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)?[1]
|
||||
handleBlob data, contentType, contentDisposition, url, cb
|
||||
onerror: (xhr) ->
|
||||
cb null
|
||||
<% } %>
|
||||
|
||||
return {request: handleUrl}
|
||||
|
||||
@ -5,6 +5,21 @@ DownloadLink =
|
||||
a = $.el 'a',
|
||||
className: 'download-link'
|
||||
textContent: 'Download file'
|
||||
|
||||
<% if (type === 'userscript') { %>
|
||||
unless chrome?
|
||||
# Firefox places same-origin restrictions on links with the download attribute.
|
||||
$.on a, 'click', (e) ->
|
||||
return true if @protocol is 'blob:'
|
||||
e.preventDefault()
|
||||
CrossOrigin.request @href, (blob) =>
|
||||
if blob
|
||||
@href = URL.createObjectURL blob
|
||||
@click()
|
||||
else
|
||||
new Notice 'error', "Could not download #{file.URL}", 30
|
||||
<% } %>
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'post'
|
||||
el: a
|
||||
|
||||
@ -293,56 +293,14 @@ QR =
|
||||
QR.handleFiles files
|
||||
$.addClass QR.nodes.el, 'dump'
|
||||
|
||||
handleBlob: (urlBlob, contentType, contentDisposition, url) ->
|
||||
name = url.match(/([^\/]+)\/*$/)?[1]
|
||||
mime = contentType?.match(/[^;]*/)[0] or 'application/octet-stream'
|
||||
match =
|
||||
contentDisposition?.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)?[1] or
|
||||
contentType?.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)?[1]
|
||||
if match
|
||||
name = match.replace /\\"/g, '"'
|
||||
blob = new Blob([urlBlob], {type: mime})
|
||||
blob.name = name
|
||||
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
|
||||
contentType = @getResponseHeader('Content-Type')
|
||||
contentDisposition = @getResponseHeader('Content-Disposition')
|
||||
QR.handleBlob @response, contentType, contentDisposition, url
|
||||
CrossOrigin.request url, (blob) ->
|
||||
if blob
|
||||
QR.handleFiles([blob])
|
||||
else
|
||||
QR.error "Can't load image."
|
||||
xhr.onerror = (e) ->
|
||||
QR.error "Can't load image."
|
||||
xhr.send()
|
||||
<% } %>
|
||||
|
||||
<% 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++
|
||||
contentType = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)?[1]
|
||||
contentDisposition = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)?[1]
|
||||
QR.handleBlob data, contentType, contentDisposition, url
|
||||
onerror: (xhr) ->
|
||||
QR.error "Can't load image."
|
||||
<% } %>
|
||||
|
||||
handleFiles: (files) ->
|
||||
if @ isnt QR # file input
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user