@ -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); |
@ -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); | |||
}; |