From 6511dcb585a2535389ea94cd2987c0a54eccdaa6 Mon Sep 17 00:00:00 2001 From: Les De Ridder Date: Mon, 18 Jan 2016 05:12:37 +0100 Subject: [PATCH] Implement basic functionality --- background.js | 81 +++++++++++++++++++++++++++++++++++++++++ formdata.js | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ icon_128.png | Bin 0 -> 5817 bytes icon_19.png | Bin 0 -> 706 bytes manifest.json | 28 +++++++++++++++ options.html | 44 +++++++++++++++++++++++ options.js | 68 +++++++++++++++++++++++++++++++++++ worker.js | 29 +++++++++++++++ 8 files changed, 348 insertions(+) create mode 100644 background.js create mode 100644 formdata.js create mode 100644 icon_128.png create mode 100644 icon_19.png create mode 100644 manifest.json create mode 100644 options.html create mode 100644 options.js create mode 100644 worker.js diff --git a/background.js b/background.js new file mode 100644 index 0000000..9b63519 --- /dev/null +++ b/background.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); + } + }); +}); diff --git a/formdata.js b/formdata.js new file mode 100644 index 0000000..923f24a --- /dev/null +++ b/formdata.js @@ -0,0 +1,98 @@ +/* + * FormData for XMLHttpRequest 2 - Polyfill for Web Worker + * (c) 2014 Rob Wu + * 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); diff --git a/icon_128.png b/icon_128.png new file mode 100644 index 0000000000000000000000000000000000000000..3f9c06b2fd7ea13969f8f3985e909b9bcaf1665a GIT binary patch literal 5817 zcmV;q7DnlbP)004R=004l4008;_004mL004C`008P>0026e000+nl3&F}00006 zVoOIv0RI600RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru+yo8=77|z6 zA1VL<6{tx>K~#9!?VWj$T-9~PfA@7aqiwW}Hjn^;KteVM2nMq#CYU$|6M~ErY+@2) zCxLQhAqz!fJ1#1Tt8B*(u`3RgA&KKa2-pV15+KHAH3kIO7$cAXNh}fwX|#;cIy3!l z{`lUVci-z}x_g%Ho_Sx@tLf=}%YFBrd(OG%oO_O;K?Fg7wH5$l3}F~f0S*U_0u}%r zz-HiSU>y)P`mABXu|OVpuF36aDdg+DzzuvDh5((w@z&b2fnNod09|PC4bTU?0bC1Q z2kdX+yPg;QeXfaZXipep2!fpZHvoUmx+mn-=`m&;*{Y2+0q z0}liDA>wS{{eyuvxX(ku5Z+~U;k|4g_!Z!vfb~F;@`Jq>cpG>#`s}`c9GF(^S;hny zGw{41I)6TJ2;w$IZOXZiwc=!82e1)XTwf0iJZE0imYPRDpU?a6Q?`47iNK6{?mL{Q zC<1~YAPhsoFw6rd0e=8o0L)39YLTp81w4va>_*@~bj=r|^NxtF?J4&>V+_`Y08@bv z0KbU{Zf5k1Zs1wqwlFL{4)hNGdM3J*vw`V|h~5XhTzeN;5C{22)SkzI+kkuV^cpvt zon8dc-`@`yg9dpzFdGrkVMt#(6zNO*fls4}(=rHvWD<3H&{p$?3*!2W~}5)l|?Rm>?)8xBt?+ZXKfba+n5u z3E0Wt`h+{~0Or>4F2?|GdDs0Mm{mt#Ob33PdiLEw!8>O*@O!{_5eMu>3UICOvJY{o zQAZ^aZ~|~8VqFf~fxCczM@zc{#u&E*1ZydJC+Bi`ipBn=-dCH^0GI3FuOSxbC@2Ir z01pB$MBgt1&LNulzzU>i{8iN1m9T{5fG#=GbBavhQ&IOjIem+3V{=0zx0zTxm zzY>aQuy+Dm5zF6%R!Xl8I$EQMUnge6Mc{Ve3?iy`13w660Y4+A^6LwQLi(Hzq*VF} zPI)EjC?AI+dFjsC6g{^pqR#wBk{sj23a3v&tUf(}uc2934HJ-_ zQBG!G>z#K55=HK}&!le@l-G}10wcBdT)_Zq24H1ApMNcN&P7PBgE+)j5xcDlE5ZB& zq?3RYu;mp_pMhp!8iycFy&B#RoK@ks1F1grXLvDvau|jbi$z)y!$tremwPYp1!4tq z1Mr_(6Axe}T3We_ehS=F$Kzf^%Av!lro6>vZuG1)3P_)*^ezE#F|pyQhok~~fXcA6 z5r&BX1~ldcz%{^oq96K!Zvm@Q7o3QkGazmHCgK@g3wERBoWl}p?bI^oEkI(xUGu8< z+xxxW60p`DgKQEGKSGM0gTLwsyneJa-|1BshD-pO`4%MOuLXX?`}q!%3X{Vb$hroy zH9XY7qt|$!=c46U8ix@tbvFZd63@^jl@OgNON|0ftu|4CD`d**Fj{J^pHaw zz+p4+3u1#y0GwLpzGo4eWsAt_xtpZX%ohO-x%Ax1pxGY5x(L8)Y#t5xjlefa&a?-C zOVP{*TQVW0lVsN$8f^Q1;+YswY73YM9PItS2@!#>JDfz)L)n3pQ)eSs1N;yXliydq zN?)@M5Cp+MA4V&KoVB(oUO>O`HN#rlfwbrAfR#vAx{lwEEMC74yjW#obRs(eXaKj4 z(7Sb#^jy9f{e9B=ZV^d6;5gt+@BcfIxwaYsq;-G+iuVWHnara;JQ^8`ZlHb}%dnzW z6V$=LZv&qIK1iv&eFgXm@ISyl&yHRW6N%+%5wX`s+wRZ2^g??k;x?dJxiR|ub0j{d zN9P=mL<7j(?feGah{z#1%iZ%TVc@qYYAO%Rw$?61BIk_gnez}~^@Di=Y*UoSS_ohw zTFP}%YCheDG~|ED<#KDCv7^f1gJ!=YfPQ3gYy|$SEJpxyh?jW>h<)wrk=Qvgy8aa8 z%$Y}0iG2(w#!69Xux!+>S!gNzKD69C9<3@SmAU3zu*V?V#;Btf0?3h+r69I_4`N|Y z1O0Vax+V~N&H8AZ0Q~!uBcyr6;%PTB8DosuZmoTucm;3*BJvNAv|rptWrI&83J-v* zP!P=F#7o_B*hB0rYLp8O8TEJ}dZPy4gB&ow1o{SH_vMgQ4jNrHO(o_ey{JQd974zOKoQyA zZv~zJ^A1?+2ENY0homn(PXj@k5#|zefIXDj8|HhTyOC4N;TLGuO+k9VM^RL>!@bDk z=-?bZ4n6@?(suh1*IA3WnB zk{gXNd(~Z*L=X*N!{!vlwkLvQeQL%gtPXbge?UqK$i2aGYBQs>Mf4oKNgd2{nysqYT}cU7>+6-g?Q67b~lY_!?JH`m^5OSP&w#B6#G<%3OjBF~_^b`43+xoFlVAjqF!VfOU%M(d=CM>99`pZ3tD5RF_(BCdMLjgZ7KZ#1ZPBiX(WDRZX*e~9e%ZeX8A zL^GhBdrPl*-g9?z~i(aG) zJYkIK8_f6;hJ&uvpNft&-bEWtrbo|QH$r_i>M)F+R$D-E1~($bY(KGqB}D9Z6`J*P zp!zN)Z|hnfD2!y-RrIX%-hj42OElV(zXc=`jwbe>_n=wzl3ck^&Gur9p-?E$*VpGn z!ibt))3*H#L%?9O+DlWDAwz}?88T$ZkRd~cMvFZWgKC`Fqr`R7IH zU>O=@f2Qt7`vT7++S%&{wt<*}S;R@HEaD^!oBh%mgtL)?=g<1JsJ=lb)SM4_Ff2p5 zf>Rj(SYPYDeg=^Yqla^d!@*r1;~(H{Q5)t#xsrH=a3AGE-3FdJ+5|C9$ZsHa@C=j< z#N`QgJDQ6WXY{76qI3ma9IJVdz+h_UQYH-c>}~ zyheEDT}^ev(SF30ZbxG1Fb3))wN;dP%iu3sm0bJ={1MMON2RJ)|FTgTDh7 z`B}zB0^>vkZ~@9k>~w4Ah?jY_{A1v?rrMwE0@cW zPnFM!+A{|w+I*B!LRg1tEVNg^L6cEH$tztae%%aG$+1~Tafuly*YaADM6d%@VjDC0 z2}T-=iOadHqk7%KR>TstVb=FZ?nSGL2}8K=xWVrtt=gise%rv~29wcpbvwyAgI}bD ztB$n_t|6BFCpEh4@NAk|}b>H5MS_&!x?7$jD$|mS2eC3S8{rmCbHht6&C7asQE_-l)YtTh&qBKQ(7#a7foV;vh%;VV}#I|OqdZJy44sF*|f^6_I8mlE3sHZ%4NV6{U#eFGEZa%LQ* zm+L|q&z&yt&t^PtJZMIoeGA~T#Jim~AO$hQIKrW5Te{-{S2epq8AcypB_@EUNLFjl zFb=Ss*ju;{IJeS?W6?>HK_&5AG3p7Z&Qe)q1TZ$ygDRIgETh6MsEh!{E}ru~AAxEq zmLMa5v5R#mgdF4|E*lh+5y03*H*vA7DU>F?0@|#=QKQJ^@=;Zf;&`g;v6r}5RtFWT zw6`?}$mjDlS^A2_ep4*=2hiL-fujt+oLxYL$v!F^AP91`ROPB0{r#%k7Uk~EBTAo) zsJ#n0f(pPkYkA4qu-oPE9S4{|ymQE}aGt=Z5I`6fJJ6QwPDG8a9J^1YE^SIcT$nK* zy+lWJOhS9@ry#9%8Zg6JJCnFzbbyQ?ucGv>&jK4T?7=dgM8Hgw)zca}U;bAgy#3;tX?%mnu_9vab;Bj@^rbAGf0*k1f&B z4eT<;^g^6i$>r7w!*IN?{4`D`o-p0CLQqT)1myE0Lvy)YL&+S+DrTb%F;4d1Nd-&b zs4fG;Fsv$rJ31!N*Vj8RV_o4#h%0e8#V?I0;d2JzOjOUn;VGam%P}-Q&`G>2+9HMc z^kz3I!|35slC_ubCsqbCj7505&#@%;2kZwfZg%@Jj1K0JWc^P0>uh$zGK>(snLh{Z zg7OFdHB`JJ!`Q^Y;2(){4Er^Ub^xDjb_<)1AeY0K>N)w_IA_1x3bu;m%-;rFMmy~K zGRD;G(HkZN$RIKSSsc57DQ%cg;RxVslqR5F3w(?^yu3||2gv91oPWV5Sb6)+Icu$J zuIS+{<#U19Yv?E;`ikh?eY^hs z!2Ko&unoAnn;sHojIqEzYwhd6>&BRegCL+-Eanlro{G4_wCM9>#35YU`w`{uL9={k zbo3w(VlnwVH~ei|k|j@E_WGXQ0zy8*n<*2*9~I~xm+&cKx)%L z_t8Oe%lr1B+^p#Ykj7vh!+Kz?t>`^$V@yYe9}xF@XDByo>!8qaio=Mrg6^h4?&y#a zK>OhYV*CEvsO((B$OxdlkVkod99}}kpoWnVKzm^ks&ww~IM6>7b52G8DX3Ut~81}lb-B<7^=l=6Cdbb7rEN$G*@1E-GaE$S}Of1K&iQ{ura5c6Ao;9pa>qF3#`d zW_QeZ!a|g6$yM_HIFT!Mgt@`di1YY^zYF+OvpZxw;={<{;s)Uwq7}k$rK0uh4hI1r zB`$a8R|@?cE$F-(^N5lyUq)P(B}Bn17okwIhKxskuxeD?VHt3}_Z)ZZMoYl9E_~VU z$OBiP*aW|b^GcM3GqLrm95E<+c}bvd2a@U6kSq)9j<0SyA1OI^X@%mFbM7qLil&NGL zT1NJxnLZE2I=&Y;3dK66S%pjSegp6yz?OCiSREJeCgW^Wo^1_DO}*Sq_H!XsI(iY& zTn!xUW_@PnZAlC$ZU%+1UjaObW_vYa@Q)CQju+8d|Kq^HZs1)qjM00W40U55@s!x} zRJ5;QIogo91hM>Sh|OEzT~x_9}t~ezY^4{6D}`y`oP-F%tj)03~!q zSaf7zbY(hYa%Ew3WdJfTF*YqQF)cANR4_6+Fg7|cG%GMMIxsN)-R(^P001R)MObuX zVRU6WZEs|0W_bWIFflSMFf=VOG*mD)Ix;dkF*qwQGCD9YHoKID00000NkvXXu0mjf Dk+aGo literal 0 HcmV?d00001 diff --git a/icon_19.png b/icon_19.png new file mode 100644 index 0000000000000000000000000000000000000000..bbbe24c7165d0709fa8611fddf382fbe99294dab GIT binary patch literal 706 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S1|*9D%+3HQmUKs7M+SzCeKo%WCjCx45bDP46hOx7_4S6Fo@?*ia+WGRLhp+?e4O>_%)r16w1!)lkzv*x37{Z*iKnkC`yCcOHZh^_+wxir42&B+T^vI!PEWmZx7#;R zg6+fod(WAl|Im7pe59qb^I6)d)<fZCe8W)c8sBM%B-ypxbklX#Ei0HA8yuuaD?pYZL zQq={#yEmA2>~geg?zd*Fs#CA-2sv?j(S()Ddw!k1F(vpK zM^oAl;}x^#9CXsqo+Y`+FsHlJKkJ3->EvD?j=wwp?0c3j$tC{J(L}ZMSnnKp)w1OE zA<>^J)aL)=^Lwz%r&_aXQC`jA`%yW6e=gUl*H&K0517na>Sq^*OT~)*VdCBswbjhJA_N$pswJ)wB`Jv|saDBFsX&Us z$iUD{*T7KM&?v;f$jZRX%D_b1z|hLT;NRW1z_f&G{~Z1 + + pomf-rehost options + + + Pomf clone: + + +
+ + URL: + + +
+
+ + After upload:
+ Open new tab
+ Replace current tab + +
+
+ + + +
+ +
+ + + + diff --git a/options.js b/options.js new file mode 100644 index 0000000..92520ee --- /dev/null +++ b/options.js @@ -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; diff --git a/worker.js b/worker.js new file mode 100644 index 0000000..24a98eb --- /dev/null +++ b/worker.js @@ -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); +};