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
|
### v1.7.51
|
||||||
*2014-06-02*
|
*2014-06-02*
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ module.exports = (grunt) ->
|
|||||||
'src/General/Get.coffee'
|
'src/General/Get.coffee'
|
||||||
'src/General/UI.coffee'
|
'src/General/UI.coffee'
|
||||||
'src/General/Notice.coffee'
|
'src/General/Notice.coffee'
|
||||||
|
'src/General/CrossOrigin.coffee'
|
||||||
'src/Filtering/**/*.coffee'
|
'src/Filtering/**/*.coffee'
|
||||||
'src/Quotelinks/**/*.coffee'
|
'src/Quotelinks/**/*.coffee'
|
||||||
'src/Posting/QR.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.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 4chan X
|
// @name 4chan X
|
||||||
// @version 1.7.51
|
// @version 1.7.52
|
||||||
// @minGMVer 1.14
|
// @minGMVer 1.14
|
||||||
// @minFFVer 26
|
// @minFFVer 26
|
||||||
// @namespace 4chan-X
|
// @namespace 4chan-X
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Generated by CoffeeScript
|
// Generated by CoffeeScript
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 4chan X
|
// @name 4chan X
|
||||||
// @version 1.7.51
|
// @version 1.7.52
|
||||||
// @minGMVer 1.14
|
// @minGMVer 1.14
|
||||||
// @minFFVer 26
|
// @minFFVer 26
|
||||||
// @namespace 4chan-X
|
// @namespace 4chan-X
|
||||||
@ -24,7 +24,7 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 4chan X - Version 1.7.51 - 2014-06-02
|
* 4chan X - Version 1.7.52 - 2014-06-02
|
||||||
*
|
*
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||||
@ -106,7 +106,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(function() {
|
(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,
|
__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; },
|
__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,
|
__hasProp = {}.hasOwnProperty,
|
||||||
@ -194,6 +194,7 @@
|
|||||||
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
||||||
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
||||||
'Delete Link': [true, 'Add post and image deletion links to the menu.'],
|
'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.']
|
'Archive Link': [true, 'Add an archive link to the menu.']
|
||||||
},
|
},
|
||||||
'Monitoring': {
|
'Monitoring': {
|
||||||
@ -372,7 +373,7 @@
|
|||||||
doc = d.documentElement;
|
doc = d.documentElement;
|
||||||
|
|
||||||
g = {
|
g = {
|
||||||
VERSION: '1.7.51',
|
VERSION: '1.7.52',
|
||||||
NAMESPACE: '4chan X.',
|
NAMESPACE: '4chan X.',
|
||||||
boards: {}
|
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 = {
|
Anonymize = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
||||||
@ -6052,44 +6097,16 @@
|
|||||||
QR.handleFiles(files);
|
QR.handleFiles(files);
|
||||||
return $.addClass(QR.nodes.el, 'dump');
|
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() {
|
handleUrl: function() {
|
||||||
var url;
|
var url;
|
||||||
url = prompt("Insert an url:");
|
url = prompt("Insert an url:");
|
||||||
if (url === null) {
|
if (url === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return GM_xmlhttpRequest({
|
return CrossOrigin.request(url, function(blob) {
|
||||||
method: "GET",
|
if (blob) {
|
||||||
url: url,
|
return QR.handleFiles([blob]);
|
||||||
overrideMimeType: "text/plain; charset=x-user-defined",
|
} else {
|
||||||
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 QR.error("Can't load image.");
|
return QR.error("Can't load image.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -9320,6 +9337,24 @@
|
|||||||
className: 'download-link',
|
className: 'download-link',
|
||||||
textContent: 'Download file'
|
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', {
|
return $.event('AddMenuEntry', {
|
||||||
type: 'post',
|
type: 'post',
|
||||||
el: a,
|
el: a,
|
||||||
@ -12444,7 +12479,7 @@
|
|||||||
Settings.dialog = dialog = $.el('div', {
|
Settings.dialog = dialog = $.el('div', {
|
||||||
id: 'fourchanx-settings',
|
id: 'fourchanx-settings',
|
||||||
className: 'dialog',
|
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($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||||
@ -13289,7 +13324,7 @@
|
|||||||
}
|
}
|
||||||
if (previousversion) {
|
if (previousversion) {
|
||||||
el = $.el('span', {
|
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);
|
new Notice('info', el, 15);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Binary file not shown.
BIN
builds/crx.crx
BIN
builds/crx.crx
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "4chan X",
|
"name": "4chan X",
|
||||||
"version": "1.7.51",
|
"version": "1.7.52",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||||
"icons": {
|
"icons": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Generated by CoffeeScript
|
// 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.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||||
@ -82,7 +82,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(function() {
|
(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,
|
__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; },
|
__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,
|
__hasProp = {}.hasOwnProperty,
|
||||||
@ -170,7 +170,7 @@
|
|||||||
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
||||||
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
||||||
'Delete Link': [true, 'Add post and image deletion links to the menu.'],
|
'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.']
|
'Archive Link': [true, 'Add an archive link to the menu.']
|
||||||
},
|
},
|
||||||
'Monitoring': {
|
'Monitoring': {
|
||||||
@ -348,7 +348,7 @@
|
|||||||
doc = d.documentElement;
|
doc = d.documentElement;
|
||||||
|
|
||||||
g = {
|
g = {
|
||||||
VERSION: '1.7.51',
|
VERSION: '1.7.52',
|
||||||
NAMESPACE: '4chan X.',
|
NAMESPACE: '4chan X.',
|
||||||
boards: {}
|
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 = {
|
Anonymize = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
||||||
@ -6090,43 +6131,19 @@
|
|||||||
QR.handleFiles(files);
|
QR.handleFiles(files);
|
||||||
return $.addClass(QR.nodes.el, 'dump');
|
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() {
|
handleUrl: function() {
|
||||||
var url, xhr;
|
var url;
|
||||||
url = prompt("Insert an url:");
|
url = prompt("Insert an url:");
|
||||||
if (url === null) {
|
if (url === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xhr = new XMLHttpRequest();
|
return CrossOrigin.request(url, function(blob) {
|
||||||
xhr.open('GET', url, true);
|
if (blob) {
|
||||||
xhr.responseType = 'blob';
|
return QR.handleFiles([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);
|
|
||||||
} else {
|
} else {
|
||||||
return QR.error("Can't load image.");
|
return QR.error("Can't load image.");
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
xhr.onerror = function(e) {
|
|
||||||
return QR.error("Can't load image.");
|
|
||||||
};
|
|
||||||
return xhr.send();
|
|
||||||
},
|
},
|
||||||
handleFiles: function(files) {
|
handleFiles: function(files) {
|
||||||
var file, i, _i, _len;
|
var file, i, _i, _len;
|
||||||
@ -12438,7 +12455,7 @@
|
|||||||
Settings.dialog = dialog = $.el('div', {
|
Settings.dialog = dialog = $.el('div', {
|
||||||
id: 'fourchanx-settings',
|
id: 'fourchanx-settings',
|
||||||
className: 'dialog',
|
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($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||||
@ -13270,7 +13287,7 @@
|
|||||||
}
|
}
|
||||||
if (previousversion) {
|
if (previousversion) {
|
||||||
el = $.el('span', {
|
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);
|
new Notice('info', el, 15);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.51' />
|
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.52' />
|
||||||
</app>
|
</app>
|
||||||
</gupdate>
|
</gupdate>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "4chan X",
|
"name": "4chan X",
|
||||||
"version": "1.7.51",
|
"version": "1.7.52",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||||
"icons": {
|
"icons": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Generated by CoffeeScript
|
// 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.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||||
@ -82,7 +82,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(function() {
|
(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,
|
__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; },
|
__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,
|
__hasProp = {}.hasOwnProperty,
|
||||||
@ -170,7 +170,7 @@
|
|||||||
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
|
||||||
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
|
||||||
'Delete Link': [true, 'Add post and image deletion links to the menu.'],
|
'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.']
|
'Archive Link': [true, 'Add an archive link to the menu.']
|
||||||
},
|
},
|
||||||
'Monitoring': {
|
'Monitoring': {
|
||||||
@ -348,7 +348,7 @@
|
|||||||
doc = d.documentElement;
|
doc = d.documentElement;
|
||||||
|
|
||||||
g = {
|
g = {
|
||||||
VERSION: '1.7.51',
|
VERSION: '1.7.52',
|
||||||
NAMESPACE: '4chan X.',
|
NAMESPACE: '4chan X.',
|
||||||
boards: {}
|
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 = {
|
Anonymize = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
|
||||||
@ -6090,43 +6131,19 @@
|
|||||||
QR.handleFiles(files);
|
QR.handleFiles(files);
|
||||||
return $.addClass(QR.nodes.el, 'dump');
|
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() {
|
handleUrl: function() {
|
||||||
var url, xhr;
|
var url;
|
||||||
url = prompt("Insert an url:");
|
url = prompt("Insert an url:");
|
||||||
if (url === null) {
|
if (url === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xhr = new XMLHttpRequest();
|
return CrossOrigin.request(url, function(blob) {
|
||||||
xhr.open('GET', url, true);
|
if (blob) {
|
||||||
xhr.responseType = 'blob';
|
return QR.handleFiles([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);
|
|
||||||
} else {
|
} else {
|
||||||
return QR.error("Can't load image.");
|
return QR.error("Can't load image.");
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
xhr.onerror = function(e) {
|
|
||||||
return QR.error("Can't load image.");
|
|
||||||
};
|
|
||||||
return xhr.send();
|
|
||||||
},
|
},
|
||||||
handleFiles: function(files) {
|
handleFiles: function(files) {
|
||||||
var file, i, _i, _len;
|
var file, i, _i, _len;
|
||||||
@ -12438,7 +12455,7 @@
|
|||||||
Settings.dialog = dialog = $.el('div', {
|
Settings.dialog = dialog = $.el('div', {
|
||||||
id: 'fourchanx-settings',
|
id: 'fourchanx-settings',
|
||||||
className: 'dialog',
|
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($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||||
@ -13270,7 +13287,7 @@
|
|||||||
}
|
}
|
||||||
if (previousversion) {
|
if (previousversion) {
|
||||||
el = $.el('span', {
|
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);
|
new Notice('info', el, 15);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "4chan-X",
|
"name": "4chan-X",
|
||||||
"version": "1.7.51",
|
"version": "1.7.52",
|
||||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||||
"meta": {
|
"meta": {
|
||||||
"name": "4chan X",
|
"name": "4chan X",
|
||||||
|
|||||||
@ -229,12 +229,10 @@ Config =
|
|||||||
true
|
true
|
||||||
'Add post and image deletion links to the menu.'
|
'Add post and image deletion links to the menu.'
|
||||||
]
|
]
|
||||||
<% if (type === 'crx') { %>
|
|
||||||
'Download Link': [
|
'Download Link': [
|
||||||
true
|
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': [
|
'Archive Link': [
|
||||||
true
|
true
|
||||||
'Add an archive link to the menu.'
|
'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',
|
a = $.el 'a',
|
||||||
className: 'download-link'
|
className: 'download-link'
|
||||||
textContent: 'Download file'
|
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',
|
$.event 'AddMenuEntry',
|
||||||
type: 'post'
|
type: 'post'
|
||||||
el: a
|
el: a
|
||||||
|
|||||||
@ -293,56 +293,14 @@ QR =
|
|||||||
QR.handleFiles files
|
QR.handleFiles files
|
||||||
$.addClass QR.nodes.el, 'dump'
|
$.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: ->
|
handleUrl: ->
|
||||||
url = prompt("Insert an url:")
|
url = prompt("Insert an url:")
|
||||||
return if url is null
|
return if url is null
|
||||||
|
CrossOrigin.request url, (blob) ->
|
||||||
<% if (type === 'crx') { %>
|
if blob
|
||||||
xhr = new XMLHttpRequest();
|
QR.handleFiles([blob])
|
||||||
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
|
|
||||||
else
|
else
|
||||||
QR.error "Can't load image."
|
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) ->
|
handleFiles: (files) ->
|
||||||
if @ isnt QR # file input
|
if @ isnt QR # file input
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user