8 changed files with 348 additions and 0 deletions
-
81background.js
-
98formdata.js
-
BINicon_128.png
-
BINicon_19.png
-
28manifest.json
-
44options.html
-
68options.js
-
29worker.js
@ -0,0 +1,81 @@ |
|||
function getCurrentTabUrl(callback) { |
|||
var queryInfo = { |
|||
active: true, |
|||
currentWindow: true |
|||
}; |
|||
|
|||
chrome.tabs.query(queryInfo, function(tabs) { |
|||
var tab = tabs[0]; |
|||
|
|||
var url = tab.url; |
|||
|
|||
callback(url); |
|||
}); |
|||
} |
|||
|
|||
chrome.pageAction.onClicked.addListener(function(tab) { |
|||
getCurrentTabUrl(function(url) { |
|||
var filename = url.substr(url.lastIndexOf("/")); |
|||
|
|||
chrome.storage.sync.get({url: '', behaviour: ''}, function(items) { |
|||
if(items.url == '') { |
|||
alert("Please select a Pomf clone."); |
|||
chrome.tabs.create({ url: "options.html" }); |
|||
return; |
|||
} |
|||
|
|||
var worker = new Worker('worker.js'); |
|||
worker.onmessage = function(event) { |
|||
var response = JSON.parse(event.data); |
|||
|
|||
var newUrl = response.files[0].url; |
|||
|
|||
switch(items.behaviour) |
|||
{ |
|||
case "newtab": |
|||
chrome.tabs.create({url: newUrl}); |
|||
break; |
|||
case "replacetab": |
|||
chrome.tabs.update({url: newUrl}); |
|||
break; |
|||
} |
|||
}; |
|||
worker.postMessage(JSON.stringify({pomfclone: items.url, url: url, filename: filename})); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
function isCoolUrl(url) { |
|||
url = url.toLowerCase(); |
|||
|
|||
var extensionIndex = url.lastIndexOf('.'); |
|||
var extension = url.substr(extensionIndex + 1); |
|||
|
|||
var validExtensions = ["jpg", "jpeg", "png", "gif", "webm"]; |
|||
|
|||
var blackList = ["pomf", "mixtape.moe", "catgirlsare.sexy", "cocaine.ninja"]; |
|||
|
|||
for(black of blackList) { |
|||
if(url.indexOf(black) != -1) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return validExtensions.indexOf(extension) != -1; |
|||
} |
|||
|
|||
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { |
|||
if(isCoolUrl(tab.url) && tab.active) |
|||
{ |
|||
chrome.pageAction.show(tabId); |
|||
} |
|||
}); |
|||
|
|||
chrome.tabs.onActivated.addListener(function(activeInfo) { |
|||
chrome.tabs.get(activeInfo.tabId, function(tab) { |
|||
if(isCoolUrl(tab.url)) |
|||
{ |
|||
chrome.pageAction.show(activeInfo.tabId); |
|||
} |
|||
}); |
|||
}); |
@ -0,0 +1,98 @@ |
|||
/* |
|||
* FormData for XMLHttpRequest 2 - Polyfill for Web Worker |
|||
* (c) 2014 Rob Wu <rob@robwu.nl> |
|||
* License: MIT |
|||
* - append(name, value[, filename]) |
|||
* - XMLHttpRequest.prototype.send(object FormData) |
|||
* |
|||
* Specification: http://www.w3.org/TR/XMLHttpRequest/#formdata
|
|||
* http://www.w3.org/TR/XMLHttpRequest/#the-send-method
|
|||
* The .append() implementation also accepts Uint8Array and ArrayBuffer objects |
|||
* Web Workers do not natively support FormData: |
|||
* http://dev.w3.org/html5/workers/#apis-available-to-workers
|
|||
* Originally released in 2012 as a part of http://stackoverflow.com/a/10002486.
|
|||
* Updates since initial release: |
|||
* - Forward-compatibility by testing whether FormData exists before defining it. |
|||
* - Increased robustness of .append. |
|||
* - Allow any typed array in .append. |
|||
* - Remove use of String.prototype.toString to work around a Firefox bug. |
|||
* - Use typed array in xhr.send instead of arraybuffer to get rid of deprecation |
|||
* warnings. |
|||
**/ |
|||
(function(exports) { |
|||
if (exports.FormData) { |
|||
// Don't replace FormData if it already exists
|
|||
//return;
|
|||
} |
|||
// Export variable to the global scope
|
|||
exports.FormData = FormData; |
|||
|
|||
var ___send$rw = XMLHttpRequest.prototype.send; |
|||
XMLHttpRequest.prototype.send = function(data) { |
|||
if (data instanceof FormData) { |
|||
if (!data.__endedMultipart) data.__append('--' + data.boundary + '--\r\n'); |
|||
data.__endedMultipart = true; |
|||
this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + data.boundary); |
|||
data = new Uint8Array(data.data); |
|||
} |
|||
// Invoke original XHR.send
|
|||
return ___send$rw.call(this, data); |
|||
}; |
|||
|
|||
function FormData() { |
|||
// Force a Constructor
|
|||
if (!(this instanceof FormData)) return new FormData(); |
|||
// Generate a random boundary - This must be unique with respect to the form's contents.
|
|||
this.boundary = '------RWWorkerFormDataBoundary' + Math.random().toString(36); |
|||
var internal_data = this.data = []; |
|||
/** |
|||
* Internal method. |
|||
* @param inp String | ArrayBuffer | Uint8Array Input |
|||
*/ |
|||
this.__append = function(inp) { |
|||
var i = 0, len; |
|||
if (typeof inp == 'string') { |
|||
for (len = inp.length; i < len; ++i) |
|||
internal_data.push(inp.charCodeAt(i) & 0xff); |
|||
} else if (inp && inp.byteLength) {/*If ArrayBuffer or typed array */ |
|||
if (!('byteOffset' in inp)) /* If ArrayBuffer, wrap in view */ |
|||
inp = new Uint8Array(inp); |
|||
for (len = inp.byteLength; i < len; ++i) |
|||
internal_data.push(inp[i] & 0xff); |
|||
} |
|||
}; |
|||
} |
|||
/** |
|||
* @param name String Key name |
|||
* @param value String|Blob|File|typed array|ArrayBuffer Value |
|||
* @param filename String Optional File name (when value is not a string). |
|||
**/ |
|||
FormData.prototype.append = function(name, value, filename) { |
|||
if (this.__endedMultipart) { |
|||
// Truncate the closing boundary
|
|||
this.data.length -= this.boundary.length + 6; |
|||
this.__endedMultipart = false; |
|||
} |
|||
if (arguments.length < 2) { |
|||
throw new SyntaxError('Not enough arguments'); |
|||
} |
|||
var part = '--' + this.boundary + '\r\n' + |
|||
'Content-Disposition: form-data; name="' + name + '"'; |
|||
|
|||
if (value instanceof File || value instanceof Blob) { |
|||
return this.append(name, |
|||
new Uint8Array(new FileReaderSync().readAsArrayBuffer(value)), |
|||
filename || value.name); |
|||
} else if (typeof value.byteLength == 'number') { |
|||
// Duck-typed typed array or array buffer
|
|||
part += '; filename="'+ (filename || 'blob').replace(/"/g,'%22') +'"\r\n'; |
|||
part += 'Content-Type: application/octet-stream\r\n\r\n'; |
|||
this.__append(part); |
|||
this.__append(value); |
|||
part = '\r\n'; |
|||
} else { |
|||
part += '\r\n\r\n' + value + '\r\n'; |
|||
} |
|||
this.__append(part); |
|||
}; |
|||
})(this || self); |
After Width: 128 | Height: 128 | Size: 5.7 KiB |
After Width: 19 | Height: 19 | Size: 706 B |
@ -0,0 +1,28 @@ |
|||
{ |
|||
"manifest_version": 2, |
|||
|
|||
"name": "pomf-rehost", |
|||
"description": "This extension rehosts an image by uploading it to a Pomf-based file hosting service", |
|||
"version": "1.0", |
|||
|
|||
"icons":{ "128": "icon_128.png"}, |
|||
|
|||
"options_page": "options.html", |
|||
|
|||
"background": { |
|||
"scripts": ["background.js"], |
|||
"presistent": false |
|||
}, |
|||
|
|||
"page_action": { |
|||
"default_icon": "icon_19.png" |
|||
}, |
|||
|
|||
"permissions": [ |
|||
"activeTab", |
|||
"tabs", |
|||
"storage", |
|||
"http://*/*", |
|||
"https://*/*" |
|||
] |
|||
} |
@ -0,0 +1,44 @@ |
|||
<!doctype html> |
|||
<html> |
|||
<head><title>pomf-rehost options</title></head> |
|||
<body> |
|||
|
|||
Pomf clone: |
|||
<select id="pomfclone"> |
|||
<option value="https://pomf.lesderid.net">pomf.lesderid.net (HTTPS)</option> |
|||
<!--<option value="https://fuwa.se">fuwa.se (HTTPS)</option>--> |
|||
<!--<option value="http://1339.cf">1339.cf (HTTP)</option>--> |
|||
<option value="http://catgirlsare.sexy">catgirlsare.sexy (HTTP)</option> |
|||
<option value="https://cocaine.ninja">cocaine.ninja (HTTPS)</option> |
|||
<!--<option value="https://cuntflaps.me">cuntflaps.me (HTTPS)</option>--> |
|||
<!--<option value="https://kyaa.sg">kyaa.sg (HTTPS)</option>--> |
|||
<!--<option value="https://pomf.hummingbird.moe">pomf.hummingbird.moe (HTTPS)</option>--> |
|||
<option value="https://pomf.is">pomf.is (HTTPS)</option> |
|||
<option value="https://mixtape.moe">mixtape.moe (HTTPS)</option> |
|||
<option value="custom">Custom</option> |
|||
</select> |
|||
|
|||
<br /> |
|||
|
|||
URL: |
|||
<input type="textbox" id="urlbox"> |
|||
|
|||
<br /> |
|||
<br /> |
|||
|
|||
After upload:<br /> |
|||
<input type="radio" name="behaviour" id="newtab" value="newtab" checked> Open new tab<br /> |
|||
<input type="radio" name="behaviour" id="replacetab" value="replacetab"> Replace current tab |
|||
|
|||
<br /> |
|||
<br /> |
|||
|
|||
<button id="save">Save</button> |
|||
|
|||
<br /> |
|||
|
|||
<div id="status"></div> |
|||
|
|||
<script src="options.js"></script> |
|||
</body> |
|||
</html> |
@ -0,0 +1,68 @@ |
|||
document.getElementById('status').textContent = 'Loading...'; |
|||
|
|||
custom = false; |
|||
|
|||
function setUrlBox() { |
|||
var pomfclone = document.getElementById('pomfclone').value; |
|||
var urlbox = document.getElementById('urlbox'); |
|||
|
|||
if(custom) { |
|||
customUrl = urlbox.value; |
|||
} |
|||
|
|||
if(pomfclone != "custom") { |
|||
urlbox.value = pomfclone; |
|||
urlbox.disabled = true; |
|||
|
|||
custom = false; |
|||
} else { |
|||
urlbox.value = customUrl; |
|||
urlbox.disabled = false; |
|||
|
|||
custom = true; |
|||
} |
|||
} |
|||
|
|||
function saveOptions() { |
|||
var pomfclone = document.getElementById('pomfclone').value; |
|||
var url = document.getElementById('urlbox').value; |
|||
var behaviour = document.querySelector('input[name="behaviour"]:checked').value; |
|||
|
|||
chrome.storage.sync.set({ |
|||
pomfclone: pomfclone, |
|||
url: url, |
|||
customUrl: customUrl, |
|||
behaviour: behaviour |
|||
}, function() { |
|||
var status = document.getElementById('status'); |
|||
status.textContent = 'Options saved.'; |
|||
setTimeout(function() { |
|||
status.textContent = ''; |
|||
}, 750); |
|||
}); |
|||
} |
|||
|
|||
function restoreOptions() { |
|||
var firstPomfclone = document.getElementById('pomfclone').getElementsByTagName('option')[0]; |
|||
|
|||
chrome.storage.sync.get({ |
|||
pomfclone: firstPomfclone.innerHTML, |
|||
url: firstPomfclone.value, |
|||
customUrl: '', |
|||
behaviour: document.querySelector('input[name="behaviour"]:checked').value |
|||
}, function(items) { |
|||
document.getElementById('pomfclone').value = items.pomfclone; |
|||
document.getElementById('urlbox').value = items.url; |
|||
customUrl = items.customUrl; |
|||
custom = items.pomfclone == "custom"; |
|||
setUrlBox(); |
|||
|
|||
document.getElementById(items.behaviour).checked = true; |
|||
}); |
|||
|
|||
document.getElementById('status').textContent = ''; |
|||
} |
|||
|
|||
document.addEventListener('DOMContentLoaded', restoreOptions); |
|||
document.getElementById('save').addEventListener('click', saveOptions); |
|||
document.getElementById('pomfclone').onchange = setUrlBox; |
@ -0,0 +1,29 @@ |
|||
importScripts('formdata.js') |
|||
|
|||
self.onmessage = function(event) { |
|||
var data = JSON.parse(event.data); |
|||
|
|||
var request = new XMLHttpRequest(); |
|||
request.open('GET', data.url, true); |
|||
request.responseType = 'arraybuffer'; |
|||
request.onload = function(e) { |
|||
if (request.status == 200) { |
|||
uploadBuffer(data.pomfclone, request.response, data.filename); |
|||
} |
|||
}; |
|||
request.send(); |
|||
}; |
|||
|
|||
function uploadBuffer(pomfclone, buffer, filename) { |
|||
var formData = new FormData(); |
|||
formData.append('files[]', buffer, filename); |
|||
|
|||
var request = new XMLHttpRequest(); |
|||
request.open('POST', pomfclone + '/upload.php', true); |
|||
request.onload = function(e) { |
|||
console.log(request.response); |
|||
|
|||
postMessage(request.response); |
|||
}; |
|||
request.send(formData); |
|||
}; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue