From ceffb307ba1a1b8e6f4ad02559ce23ddd139e1b1 Mon Sep 17 00:00:00 2001 From: NeverDecaf Date: Fri, 7 Oct 2022 09:33:07 -0400 Subject: [PATCH] pack 1.5.2 --- Chromium Web Store.crx | Bin 48399 -> 47207 bytes en_nolocale/managed_storage.json | 7 +- en_nolocale/manifest.json | 2 +- en_nolocale/options.html | 6 + en_nolocale/scripts/background.js | 116 ++++++++++------ en_nolocale/scripts/inject.js | 74 ++++------- en_nolocale/scripts/options.js | 67 +++++----- en_nolocale/scripts/popup.js | 4 +- en_nolocale/scripts/util.js | 213 +++++++++++++++++------------- 9 files changed, 267 insertions(+), 222 deletions(-) diff --git a/Chromium Web Store.crx b/Chromium Web Store.crx index 870958c1973a69c8a1e0e5b46d491bcb703f3e3c..560ed8fffd20c03621eb894b1166d46afe84451c 100644 GIT binary patch delta 9507 zcmZ8nWlWu2vppQ3xVyVM#i3AK3dP;s9g6c5r#Kv}xLa{|x8m+jai_T6_kM5gkMGW( zNmlk`_UvS3lC^g16Zqf~TrCI%BobV0vb0=8^!nLI_dnu%me|W9=(G~fYe*2@t`{QF zY$(8-ZcpX-Vc7XgWPQlTq)e(a0MnVLEW}Jhgrg)WAN-(>tR9P4)i_vg&P)Fw_&z)U z6+L6F&5al9IcKz*nQnlGdXzc-q}#EfE-KPb`xgv5;r*?Z^W5mwT9#xE$g9T~u)BPv zN2ig|JjQVgSeo@HM|7b&J*VDL;xf8hwLP419(P`sRb{qS*|i$I3yL!^C86_wv!b)J zWgg`~)N+-HW)JNb;j7pFP^lnc>+R8&1>_6qPZxLY*&oFQb2#UwGBT{a9(y>tLV-4S z%r(_WwON?*eEYvzdFbWuD%tl&$iescC{kl1hFU8e%r#yk9KAbSK+^F4ey)?gV!wKNyL#qaY=3+< zw|Pa{?^@MyJX%?nYWTegxyW%rE_;(jzHHLKEy`!mi6@3uZpJI3yeDU6pu)?Y-C?2e zFEu_ zQ4dfVKMCm6mL~1UVX*5yLc}Rq6S;zwUCy0;(;^}`X#+I8Z+vPySh;&D{5aWvQ~i?6 z=_K;dHByAc+R^1udpLvKqKWAZH6w_rv6$e`B7eU@8C%hDnZ1)zeXrAepPVJU$CUoM zoYaEDlEi6*jObpNdOD=R#SqgzJ8E&*>W!hV`SAwh%7_tb;n}dYxk{2JK5uukO^IYT!15Hc_)o5_Hw*D}N+( zCDU+1xDl$E@!~-A&r>l}rQtuD#ofcX!SR}?`e!2Go49@5)7XKTpgz(fPOO z6NAt8%h+?R5J<8JH(_U~YoQdMFEHt34~9bHedGW)*$1R87*d)apv+MxHYXo(D^T5H z_x6LSjE>lkN$PJ0)A*oXt2R;!2sgbH?`TiKoC0*iWPm%>?UE($=ii;cBm2+%#ICl_)H+MZ# z{6T&b(d6gs`?pDys*DRx3%ZiI9WI|VFSOwg?Ro>oU$Uk5nbvV2=iZIX4*-=OTA#@)cmE-LP5QvEgGS0^aG-zKqtn#408{}Mc+k7_0E6X_T zQ))gG;8oy-R?y`_<;kIk(aE!C)+mN{1osZ!%s?uJo#=UP{o(KIZlVm`O=fLeS5?hP`mWR{5}tu`+57qN~6 z9N9`kXJ>PR5z)H&oWki}X2P>`#`h>JXB5^iz)$#mpIFcVzk+xQpV1)_Cd@D`9JQmQ|JYK|nL<9uCLH>VmJHukjWyL3YQT!5*A@ zqPi3z@iavxtK}_P(Eo+=I~;~*o+AnmDjDxg;HB-n49`pxKnc%hIkk$(9QLXqx91`R z5USsNnMfh{f!RqqPfBohSlaJ{Adl(~dVEU%rL5*TlzX zQ;VOhZVz2#$yWaQ3tBkp56hQ48ojiXgDP6hD$A>ZKjVKE|3?1ht$R3YTfR9jJY{o>U4Ajn}*mDt^>`b|_D%FWa*V4hKDH$5O-uSzv6?Y1nImytKdm6Bf36d2iY zZ-MqcwOklI?HcC8^WiF4+@d+f;OGoE6e4djNIuDQ=8(wWg~`my$RPgmJp0?fHTU^; zYWHxabRn1I=7}Sqq2aQ_TOB$|aKdowk2iy7&&b|PRNJ0w{-}1TQD4Ff#1`({ZPmbik;Wxx-hgRqjRcCk>S!nO8?C@^*nCer=`6y z%Vf+=%HpH>N!xcg%9C4#%LUt)Zx_*So5|wMM_p{mzaX`?E#GJ6)sq>^IQga{QnQ4O z1v+gDkeSbyY|NNP8H_ULcL6O&MuW>gVL1|$Tc%cp8C4pb5BJ$!Z&H?_u%cK$SlvU> zo<0tlSpf4M&2^+$>!GF%b8tNt4Od{*z=miSQDw_v5!l| zK3SJ;!;a@DNAU%7@|4F)*%h!wk1lFFx@GYCgc?cqx-YlcYXEt&rJe} z2eZgCd31|pY2k;fhKPKO759F#KQnzDFCKVYKNt3A|AyJo`w*+2kg%=^H;59*ve1V+m3A8q>Ujp zlNC0eX{~Baa$ofM&$dw&j7#ZQSat2to#vSp#s#F%+8aK4KLF^TN_dY9b&9vW5%Lgw znIr+&RO}8*^+$7*p-57dHe6_c(sfe?L5AgA!yk9dqE;+fzv56C6-T z$0&~|k))ZJ&`4$R!I{o+wT6-<@2VL&i>qfI2F)Uylvl%i{>}5Ck*6ad;PVcrGlgt3 z;bJ32PVPP{TMe{JGGLF#iq;L4Zh4W|Y90Jqu(pQTpX}x%F_+$gwSp4bDv5E7H7fV+ z;5s&m_FKJGKZ$P0hUWKvBhGxd64Tv|rWtza-Efvn`GxHNqRNp&NQFg&PQ#mZ>;=vC zDCIGgR{QpC%u0OH=Khx!REf{-CwnRWCU=;*VQvunh!>FcOuSi>?_(EFaGb0;GOKRy zLFQBSNiTMUCXVSSkd`)l)u0@?>y*b~aHp}dyCS7^-2IdAPy%fuQrRN*NE_4cN9Nqf z1gh8Wmk33`7jw_<$Vfm*pUB>ESEu9Hzd!Vss-@=60?n=_Qu)IZWm8s>kG> zLrdbu5)sYEo&$6R{_G-j8ee~&)?h70R-^u`wGN2d&Ds=}oHOkX5_*4}G@4N^Zu zu-Mp*qp@Xh^lGE7N9p$vrd9HOe*c|Qv>={t+4~L^oLrQ7otHYb;fei*X}w5r#_7^i z1T#xHLKAMOI;>V|M^jnr$DJQ0qH05NFP%?qK1_9Au11twfRx-#Z>W@K3;jMA#w3u1V>qnp9#ZdGaUVdJRhmr1L@p-3gjMVz z^X{ZrlIf})QdFTV6sfnMM-f4HB&6Loj}l==amDOZynK%QDg0GTvaf3=4sR1E^!Na~ zQ8BL)kBLeqdW?pwOyD z83}84Gk`qJm8x)RpQ3x-s@HThqcO2zt395shN0^~yI}uq$4ea}q}4#&)G{>zU*(IT zF52`q)<7}*pd$`rfXzJ3cO@slYGjz<(R-nywfHrlioe>W{`{@me7#8Jfutc3Yijz@y78{ApPTqAxW?)9 zl*#7g1|5Rl(eX#OFK6x@HCZ?Y!rGbmA28u~f4r{{m%}7WFwom|S96E~X!UJ5Qe+E$ zCJjxd*oF3es{!PRqzv`nYaoc$isP+ zEwzxB8nDh=u8+#$Q`I;aRA?NTUl1hVJ6bPyXdwRc_jRGxucU&jydRsl5zJnOpq9V{K^~ss_*aC=LIOXNyj{c9ov)OH71cfX1Gt2WQ=pp`>b(Q7{w%U80@^urDc z*QuyCYV0|O+;n$kJqEAPdq-rWI-)m0IOp5O!&kl{MJ^y9$x{A-SNRfK2pmQe=EB}EUVtEDODqm z)KU}CP?GqC0hBM((kf|ZTEXJ_rTPnnoN*@ccIUe)!nfSdY7rIul#(!mjY$n%Axo{`os%CsE91P;V=Kxf-B_p4xrH`CCHeBt{_ z>5lge!8g2n6t!&5C+AbD$r`>I!pSKS5lPKB{Eyc!{?dK=ws`%mcxQ@$ojS&l~%MljrP~k zEf}tN<+!{Tc-|CES{E_k{&qETdDx!bg~nK4ztB(_VS#jKU-@PrxCG%q+f_@ZM!=1Vr*5Zfc-li&~T4i2WT@>2()&?=yYnmtdsLuG;E{baU@iYTd9!Lv2OIKGfO%tA&*h&~-a z$SsEr{5E%A+3zxsNtyAwnu^_UN3WT_x-NHXY;5Nt)Ri2wFAdE)4{s2^y^wwUunD8} zgW{`&!2ouA!QVs0aG1%eYm2UY0_klbShvx7xMaV2!P&*cr}#}D;M%+E(f2;nd12*(r)+XvmoQga|57Kk^zJ~DzHixd zt6fcAhEXt^F-?O%Q|Rp(u1-zX3Io;6Qd+(JiysOO8VJt?Rea=aJ5<96F*(Ql)>MsXn7ty2-TDj zeie!E*EHXQ^H2!b2jC?zkZUN?hsLDUFt)CjKY4u-UmyNXE6RSg6y_vhdKcgW%3mLF z#&1Yh7;=R&ce9bjA4Moq(6ZVWDE}FbP^=I(*?_#LsJW@X+5UWhL+&NNYz0Y{U9tkB z(a|D^4O*vXB$)FY+|J+Qk@+_hbap&k?ObR&R{6IRbou~)f&KN^#qhnykKkxpXZA#< zM%gheixK~W7=E&_1O-CyczV$Ar~A?-e%33L07_nb6n%it{gv7RbW@fT=){9!VV8(y zoG!#V+rw~+b?k-4&K=o1YOS3VQc{hHmFhr~bnnqdyqC{sZks82HBi z)tBx=fdDTlfFaaK*6<-Sl%%49n@iQ!lS4RbdsjjzYnKWo2;LC&YOjg9`=1T!w5U3L{X z3{8|ijV3!;i%3|d-+x*R^|~IhazxGO{XBXIlKMxz?3XF+jA=PhWKMkCBiT#o2|wzr zk(b^jC1b`VmeIW$b8{F>sFjibV6qby2W#4kqp=|>hec!-h(uc^g7G?se2N2M;B@G@ z;M)=a#MnP_FpR}i(BG`#Q?EdiEQPIX!PDS(RBw|Bk=#8kzFJ-8`7}?>*rf{o6KFOiu|~cUvzL^tIOFXC6P7uZmgQk5=3{oijr>BIvn%YBMej;x?^4>t9cYO zT3CRIb6wyR(tXwtydLYn!u|(uJ^RypALgRd6F$*k5THe4%l&_7e^9W z+3HAZGgr&mbNP^&75>D=FJjsyp@J=9V|Ku8rkVj06rD&^7w(ACQTBd(M6Gr1;rBa~ z(nyu?sAgM%Hy#2(A>UEXlGXd6=O?uS%!1D>T1}X)q9!AArh@B%6lgo3LOS~mmu~*v zmwkezx1MD$kLtb+w1&FB0aqr@Aoigln?Dbp(-%D!hqrLxE%=R@+#aK=r}e$@$%`r{ z;z0v9*C3?N&=`B;jf8ck4fBI{yUpuF%sn4~p`7{+ z(4Fxwtc;qN#75hpj;%v@w+*W?H_fz;Vu22+KB!eCTmb_wYspgcv2@X7v&Qh)4K`wFcf{Cx8kbr z$(cfeZ>>vmeE*;n=nB`wwjfAfS-gNL6n(}5rDikIchw((FPlb2n?D-cMvKCbm=%flkN92-S_Vsckh-= z%aBbq8M`!PJwq*``>9DSDyp^$@4NXW&E2YNEDqIIT9@6N;M&2e^fmhSY4A#(y5NR< zhF!`%#BR|J5Vt-b^pqV2y6aBp{25p9V`ef;^lqLXI#h^;Dnc3o`il5`au6sRpz z#Xb=1d)Cw+QYd3;kzGhXfx!G3pU*o%HpnQpdO1}_Un*Fk?*VEfuRk)M^KqNe&-PeA zC_Kk$7C%6Cl1l;L%iR`6ABk#=JR%JP8A+{{g|#P z?s;3fYfdsW6~NixjFHN0kRf>dJXS|UdP~RiH&#T?@zAuGu~KPEQh%#t%%M&~w^W+? zjpEl?tk7OU>!R+n|i_y7snKjqLbUYejvo31&l$gUjuC+(_=Cg!9a1 zL~DpK9_d^+=@J(av-yT*dIyr8RIjR`SDo^wfD@oV+JrM@_h#IIn;&F8HSeGQ8 zaDu#U1urfAfx)|?glqEgqWx1s* z_}qlVvIVqw+&xL)g&-0KVgh3ukbCpF44Il#J=Gj7YnuS}=40u-;AS zcF{|ytb>;m8ZIbMmCo%;*2Kr@-> zQ9=}#98d*t+vjRb+jzJU-D7^ja745lXtmVK6eAIDj0I1`M^45YCtbwci6n(FJaaqD z;!1ytobb5b7Y?&qbJ7e#a2o|9h66BPM}JUVqyJ;RDZV+o{(Vd9hZ5l2`X1oSJ}vwC zL4yHfm^q(nEkrHUacImmuR z7lv2(ktj~6R-`>VOpYHF=z|?lmENc8v`2=53Cr2J4);QpH3}2RrHq*w_5Ob1rR|&K zzyJr-F+02+r+1J-+!c(2h7@`W72l}KUb^2I+}*Roinw6#iAW8pCpY2r7VM}xlqUN7 z?pWM~O)7Y==4ubmyCsvN#0;>+*39y2uV9waOs=_a^kgRNW{8A}xb0(?0MdX{^na<-XReQHC&ctsfUcK5|Hj|Is$!vUf&4Q6N_T zbEbhd>)0Xy(CPPrAi?feX9c1hy#R%NaG!Gkh3SPnhfj1+fokoK6etNlNH??mG=ptrCCC|s`i>o?Evv>lL0pNtQyW9?Q zfa|Nf$VT0Iaz9N2b?*8MXUu4e%PPJe10Q)-`a!udosnpWFc2|RrR;?zVuVsW4a?GG zj$;~o55pG}gw@sTUFxg)o~_Ptnkjlo<%3Sa4n9!Be6KF#aH?EuAup5AH1{o*q$tO1 zAJQ@DcY{Y)-Wu=D^}rKW`A;kR#K zlq@5*WzbDFliF-}R{w(LvK)rY!QSMtQ%iVqlR$T_^i8%VZVlTFS$;^)?xs!P_6*@@zTWGyh@F1)v5A-0<9+s+4*XtN$J=%phn~ybU%jo~6 zbEUXaqXi`?`^k350KXLKxAHakSJltR@tlx{pZ>9+t=lHbSrAmb*MzHWhjr1nVwaX~ zmrHP=h??YYaajsCJ z=AI9*AKmy>3S*ZZ;RnVvMpR5q(e6=&H?-gKhWw&NSf*^y1F(411Ag(^R&cgFDwp$= z)F>aHg6zsdHOccjr5fY)(MHML8M(QF?R9hUyYx#KKG^9BOIOCitQI4xHYnni*#xDf z+gY+0K{pdxNmhHWI_&Nj`twbiWBHS})$3THz6CqvnF#r{Qre7A--kh~>ssrmh$G`v z5P$W>DQ^PH0LK+2CD~gnGahbS#=M?Ul~S^I2N=&QWxm<|+Ch z(E!w@FR@xISxBdpv%*ql9$tHW*arzN($U{8y)&Z#%91s(m~b{48zQc_Hji1=O@EY? zFy*}b3Ct6(xr{KBRGUTLz=0uM`CE`j^X@(1)ol*meuAtOPj;}`rUo-Z@(oo(t|P>V z>wyZZMjUpHij2yz2OS*V-^XMrN+lw=1q-mXWZq$nW$un!$=u!P?JGjv z7&GAj#-wbfb?(GXDSM)&T8A_CPVqQSW?P+QI)9p1pIzvE&D{2&9yT$Tln_ErVzC6rUE?bS@^InKHl1E6b7I0eeYKS>Y(Mo<-(Q=S%pC6Ixf33;xB|y$8d% zce;!FaA||du{<8$6$1AMCpjT4%aKo)-vekeIePmLtBG8qWcNr4ZcsAYs2fymcNK*2)dYbBr+89b=2hlCCQV5Kp6jZCifF$rS20nAPIsv z%VI-V>lwiw(h!|`VKCuWNLoE9`F|?{AkaU;z<=W37V8?2rFuc|M+*o}!$+`#1w^hv z5WH^*32P7r&s#%=8ic^2_7K>{&tP~5h;$=2SkeLF-^d3Y;sAoAyAwh-n~@=#jilf* z7s&fR@UaUh!TVp-sEHID>;d`S#0T#8fV4JAg7JMJP|ZSMJzt1Ovn;skJ0zl+4}9?* z(%&oz{u2yAYT<*X4go;~q6i^IEsWr+a7a`OADH6@WUxgNtQieKY2|}Xi3UL`694Vs z&`Jt!h=;_q3PL}`gCM9sN&a)4|AkMIAUJJ;VAf=aN}CLrIt`N1#s_Vd27-9!{#*On zMhZsChLE)LL4U~xL5z$3ZxnP$Ogk#LKOd6SE(i@*0D_SGB7r=%qkj-7{oiN%ACX@n AfB*mh delta 10712 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 wf!s9mf>C}zSehik_4yF@CSLG$KBW2|*_A-"], "action": {"default_icon": {"16": "assets/icon/icon_16.png", "24": "assets/icon/icon_24.png"}, "default_title": "Chromium Web Store", "default_popup": "popup.html#is_cws_popup"}, "content_scripts": [{"matches": ["https://chrome.google.com/webstore*", "https://addons.opera.com/*extensions/details/*", "https://microsoftedge.microsoft.com/addons/*"], "js": ["scripts/util.js", "scripts/inject.js"], "run_at": "document_end"}], "background": {"service_worker": "scripts/background.js"}, "update_url": "https://raw.githubusercontent.com/NeverDecaf/chromium-web-store/master/updates_en_nolocale.xml", "icons": {"16": "assets/icon/icon_16.png", "24": "assets/icon/icon_24.png", "32": "assets/icon/icon_32.png", "48": "assets/icon/icon_48.png", "64": "assets/icon/icon_64.png", "128": "assets/icon/icon_128.png"}, "homepage_url": "https://github.com/NeverDecaf/chromium-web-store", "options_ui": {"page": "options.html"}, "storage": {"managed_schema": "managed_storage.json"}} \ No newline at end of file diff --git a/en_nolocale/options.html b/en_nolocale/options.html index 3e5207e..affcd7e 100644 --- a/en_nolocale/options.html +++ b/en_nolocale/options.html @@ -27,6 +27,12 @@

Update Options

Ignored Extensions

+

Advanced

+
+ +

Import / Export

diff --git a/en_nolocale/scripts/background.js b/en_nolocale/scripts/background.js index a7fb53d..9d22dfe 100644 --- a/en_nolocale/scripts/background.js +++ b/en_nolocale/scripts/background.js @@ -1,12 +1,8 @@ -var extensionsDownloads = {}; -var default_options = { - auto_update: true, - check_store_apps: true, - check_external_apps: true, - update_period_in_minutes: 60, -}; +importScripts("./util.js"); +const nonWebstoreExtensionsDownloading = new Set(); +const manualInstallExtensionsDownloading = new Set(); const tabsAwaitingInstall = new Set(); - +const extensionsTabId = {}; function handleContextClick(info, tab) { if (info.menuItemId == "updateAll") checkForUpdates(function ( @@ -16,8 +12,8 @@ function handleContextClick(info, tab) { updatever, is_webstore ) { - let crx_url = updateCheck.getAttribute("codebase"); - promptInstall(crx_url, is_webstore, extensionsDownloads); + let crx_url = updateCheck["@codebase"]; + promptInstall(crx_url, is_webstore); }); else if (info.menuItemId == "installExt") chrome.tabs.sendMessage(tab.id, { @@ -34,14 +30,14 @@ function updateBadge(modified_ext_id = null) { } function startupTasks() { - chrome.storage.sync.get(default_options, function (settings) { + chrome.storage.sync.get(DEFAULT_MANAGEMENT_OPTIONS, function (settings) { chrome.storage.local.get( { badge_display: "", last_scheduled_update: 0, }, (localstore) => { - chrome.browserAction.setBadgeText({ + chrome.action.setBadgeText({ text: localstore.badge_display, }); chrome.alarms.create("cws_check_extension_updates", { @@ -61,8 +57,8 @@ function startupTasks() { ); }); } -chrome.browserAction.setBadgeBackgroundColor({ - color: "#F00", +chrome.action.setBadgeBackgroundColor({ + color: "#FE0000", }); chrome.management.onInstalled.addListener(function (ext) { updateBadge(ext.id); @@ -87,30 +83,33 @@ chrome.runtime.onStartup.addListener(function () { }); chrome.alarms.onAlarm.addListener(function (alarm) { if (alarm.name == "cws_check_extension_updates") - chrome.storage.sync.get(default_options, function (settings) { - if (settings.auto_update) { - updateBadge(); - chrome.storage.local.set({ - last_scheduled_update: Date.now(), - }); - chrome.alarms.create("cws_check_extension_updates", { - delayInMinutes: settings.update_period_in_minutes, - periodInMinutes: settings.update_period_in_minutes, - }); + chrome.storage.sync.get( + DEFAULT_MANAGEMENT_OPTIONS, + function (settings) { + if (settings.auto_update) { + updateBadge(); + chrome.storage.local.set({ + last_scheduled_update: Date.now(), + }); + chrome.alarms.create("cws_check_extension_updates", { + delayInMinutes: settings.update_period_in_minutes, + periodInMinutes: settings.update_period_in_minutes, + }); + } } - }); + ); }); chrome.runtime.onInstalled.addListener(function () { startupTasks(); chrome.contextMenus.create({ title: "Update all extensions", id: "updateAll", - contexts: ["browser_action"], + contexts: ["action"], }); chrome.contextMenus.create({ title: "🔗 Chrome Web Store", id: "cws", - contexts: ["browser_action"], + contexts: ["action"], }); chrome.contextMenus.create({ title: "Add to Chromium", @@ -122,9 +121,27 @@ chrome.runtime.onInstalled.addListener(function () { ], }); }); -chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { - if (request.downloadId) { - extensionsDownloads[request.downloadId] = true; +const msgHandler = function (request, sender, sendResponse) { + if (request.nonWebstoreDownloadUrl) { + chrome.downloads.download( + { + url: request.nonWebstoreDownloadUrl, + }, + (dlid) => { + nonWebstoreExtensionsDownloading.add(dlid); + } + ); + } + if (request.manualInstallDownloadUrl) { + chrome.downloads.download( + { + url: request.manualInstallDownloadUrl, + saveAs: true, // required to suppress warning: "Apps, extensions and user scripts cannot be added from this website" + }, + (dlid) => { + manualInstallExtensionsDownloading.add(dlid); + } + ); } if (request.newTabUrl) { chrome.tabs.create({ active: false }, (tab) => { @@ -148,20 +165,35 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (request.installExt) { tabsAwaitingInstall.add(sender.tab.id); } -}); +}; +chrome.runtime.onMessage.addListener(msgHandler); chrome.downloads.onChanged.addListener((d) => { - if (d.endTime && extensionsDownloads[d.id]) { - delete extensionsDownloads[d.id]; - chrome.downloads.search( - { - id: d.id, - }, - (di) => { - chrome.tabs.create({ - url: "file:///" + di[0].filename, + // open chrome://extensions if user has "Always download CRX files" checked, for easy drag-and-drop installation + if (d.endTime && manualInstallExtensionsDownloading.has(d.id)) { + manualInstallExtensionsDownloading.delete(d.id); + chrome.tabs.get(extensionsTabId?.id ?? 0, (tab) => { + if (!chrome.runtime.lastError) + chrome.tabs.highlight({ + tabs: tab.index, + windowId: tab.windowId, }); - } - ); + else + chrome.tabs.create( + { + url: "chrome://extensions/", + }, + (tab) => { + extensionsTabId.id = tab.id; + } + ); + }); + // chrome.notifications.create("manually_install", { + // type: "basic", + // iconUrl: "assets/icon/icon_128.png", + // title: "Extension downloaded! Please install manually:", + // message: "1. Enable Developer mode (top right) +2. Drag .crx from downloads bar onto extensions page", + // }); } }); chrome.contextMenus.onClicked.addListener(handleContextClick); diff --git a/en_nolocale/scripts/inject.js b/en_nolocale/scripts/inject.js index 3ddb4ff..989935a 100644 --- a/en_nolocale/scripts/inject.js +++ b/en_nolocale/scripts/inject.js @@ -1,7 +1,6 @@ const is_cws = /chrome.google.com\/webstore/i; const is_ows = /addons.opera.com\/.*extensions/i; const is_ews = /microsoftedge\.microsoft\.com\/addons\//i; -const is_ews_addon_page = /microsoftedge\.microsoft\.com\/addons\/detail\//i; const cws_re = /.*detail\/[^\/]*\/([a-z]{32})/i; const ows_re = /.*details\/([^\/?#]+)/i; const ews_re = /.*addons\/.+?\/([a-z]{32})/i; @@ -79,7 +78,7 @@ function createButton(newParent, addBtn = true) { chrome.runtime.sendMessage({ installExt: getExtensionId(window.location.href), }); - window.open(dlurl); + promptInstall(dlurl, true); } else { chrome.runtime.sendMessage( { @@ -139,24 +138,27 @@ attachMainObserver = new MutationObserver(function (mutations, observer) { if (is_ews.test(window.location.href)) { new MutationObserver(function (mutations, observer) { mutations.forEach(function (mutation) { - if (is_ews_addon_page.test(window.location.href)) { - let btn = mutation.target.querySelector("button[disabled]"); - if (btn) { + mutation.target + .querySelectorAll('button[id^="getOrRemoveButton-"][disabled]') + .forEach((btn) => { btn.classList.remove( - btn.className.split(" ").sort().reverse()[0] + btn.className + .split(" ") + .sort( + (a, b) => + parseInt(b.slice(1)) - parseInt(a.slice(1)) + )[btn.name == "GetButton" ? 1 : 0] ); btn.removeAttribute("disabled"); btn.addEventListener("click", () => { - // normal methods fail because microsoft's official web store redirects you from HTTPS to an insecure HTTP url. - // instead use chrome.tabs to open the url in a new tab. - chrome.runtime.sendMessage({ - newTabUrl: buildExtensionUrl( - getExtensionId(window.location.href) - ), - }); + promptInstall( + buildExtensionUrl(btn.id.split("-")[1]), + true, + WEBSTORE.edge + ); }); - } - } + dlBtn = btn; + }); }); }).observe(document.body, { childList: true, @@ -179,30 +181,13 @@ if (is_ows.test(window.location.href)) { dlBtn.innerHTML = "Add to Chromium"; sidebar.replaceChild(wrapper, installDiv); wrapper.appendChild(dlBtn); - let url = buildExtensionUrl(getExtensionId(window.location.href)); - function fetchExt() { - let filename = "ext.crx"; - fetch(url) - .then((r) => { - r.headers.forEach((h) => { - let v = /filename=([^ ]+)/.exec(h); - if (v) { - filename = v[1]; - return; - } - }); - return r.blob(); - }) - .then((blob) => { - // set mime type to prevent automatic install; reference: https://stackoverflow.com/questions/57834691/how-to-serve-crx-file-in-a-way-that-is-not-automatically-installed - blob = blob.slice(0, blob.size, "application/zip"); - const blobURL = window.URL.createObjectURL(blob); - dlBtn.href = blobURL; - dlBtn.download = filename; - dlBtn.click(); - }); - } - dlBtn.addEventListener("click", fetchExt, { once: true }); + dlBtn.addEventListener("click", () => + promptInstall( + buildExtensionUrl(getExtensionId(window.location.href)), + true, + WEBSTORE.opera + ) + ); } window.onload = () => { chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { @@ -212,16 +197,7 @@ window.onload = () => { "opening extension URL:", buildExtensionUrl(getExtensionId(window.location.href)) ); - if (is_ows.test(window.location.href)) { - dlBtn.click(); - } else if ( - is_cws.test(window.location.href) || - is_ews.test(window.location.href) - ) { - window.open( - buildExtensionUrl(getExtensionId(window.location.href)) - ); - } + if (dlBtn) dlBtn.click(); break; case "extInstalled": if (request.extId == getExtensionId(window.location.href)) diff --git a/en_nolocale/scripts/options.js b/en_nolocale/scripts/options.js index 316363b..829ec2a 100644 --- a/en_nolocale/scripts/options.js +++ b/en_nolocale/scripts/options.js @@ -1,11 +1,6 @@ function load_options() { var maindiv = document.getElementById("updatetoggle"); - var default_options = { - auto_update: true, - check_store_apps: true, - check_external_apps: true, - update_period_in_minutes: 60, - }; + var default_options = { ...DEFAULT_MANAGEMENT_OPTIONS }; chrome.management.getAll(function (e) { e = e.filter((ex) => ex.updateUrl); installed_extensions = e.map((ex) => ex.id); @@ -94,7 +89,7 @@ function load_options() { updatever, is_webstore ) { - let crx_url = updateCheck.getAttribute("codebase"); + let crx_url = updateCheck["@codebase"]; promptInstall(crx_url, is_webstore); }, null, @@ -111,36 +106,38 @@ function load_options() { delete items.ignored_extensions; for (const [setting, value] of Object.entries(items)) { let node = document.getElementById(setting); - if (node.type == "checkbox") { - if (!node.checked) node.checked = value; - node.addEventListener("change", (e) => { - const checked = e.target.checked; - chrome.storage.sync.set( - { - [e.target.id]: checked, - }, - function () { - if (chrome.runtime.lastError) { - node.checked = !checked; + if (node) { + if (node.type == "checkbox") { + if (!node.checked) node.checked = value; + node.addEventListener("change", (e) => { + const checked = e.target.checked; + chrome.storage.sync.set( + { + [e.target.id]: checked, + }, + function () { + if (chrome.runtime.lastError) { + node.checked = !checked; + } } - } - ); - }); - } else { - node.value = value; - node.addEventListener("input", (e) => { - const val = parseInt(e.target.value) || 60; - chrome.storage.sync.set( - { - [e.target.id]: Math.max(1, val), - }, - function () { - if (chrome.runtime.lastError) { - node.value = "60"; + ); + }); + } else { + node.value = value; + node.addEventListener("input", (e) => { + const val = parseInt(e.target.value) || 60; + chrome.storage.sync.set( + { + [e.target.id]: Math.max(1, val), + }, + function () { + if (chrome.runtime.lastError) { + node.value = "60"; + } } - } - ); - }); + ); + }); + } } } document.querySelectorAll("label.sub").forEach((node) => { diff --git a/en_nolocale/scripts/popup.js b/en_nolocale/scripts/popup.js index 57f6301..3941dc8 100644 --- a/en_nolocale/scripts/popup.js +++ b/en_nolocale/scripts/popup.js @@ -71,8 +71,8 @@ checkForUpdates( ); li.appendChild(storepage); } - li.setAttribute("crx_url", updateCheck.getAttribute("codebase")); - let crx_url = updateCheck.getAttribute("codebase"); + li.setAttribute("crx_url", updateCheck["@codebase"]); + let crx_url = updateCheck["@codebase"]; li.addEventListener("click", function (evt) { if (evt.target.tagName != "A") promptInstall(crx_url, is_webstore); }); diff --git a/en_nolocale/scripts/util.js b/en_nolocale/scripts/util.js index 64c4b28..dfa2ab1 100644 --- a/en_nolocale/scripts/util.js +++ b/en_nolocale/scripts/util.js @@ -1,6 +1,18 @@ const chromeVersion = /Chrome\/([0-9.]+)/.exec(navigator.userAgent)[1]; const store_extensions = new Map(); const googleUpdateUrl = "https://clients2.google.com/service/update2/crx"; +const WEBSTORE = { chrome: 0, edge: 1, opera: 2 }; +const DEFAULT_MANAGEMENT_OPTIONS = { + auto_update: true, + check_store_apps: true, + check_external_apps: true, + update_period_in_minutes: 60, + removed_extensions: {}, + manually_install: false, +}; +var fromXML; +// prettier-ignore +!function(r){var t={"&":"&","<":"<",">":">","'":"'",""":'"'};function n(r){return r&&r.replace(/^\s+|\s+$/g,"")}function s(r){return r.replace(/(&(?:lt|gt|amp|apos|quot|#(?:\d{1,6}|x[0-9a-fA-F]{1,5}));)/g,(function(r){if("#"===r[1]){var n="x"===r[2]?parseInt(r.substr(3),16):parseInt(r.substr(2),10);if(n>-1)return String.fromCharCode(n)}return t[r]||r}))}function e(r,t){if("string"==typeof r)return r;var u=r.r;if(u)return u;var a,o=function(r,t){if(r.t){for(var e,u,a=r.t.split(/([^\s='"]+(?:\s*=\s*(?:'[\S\s]*?'|"[\S\s]*?"|[^\s'"]*))?)/),o=a.length,i=0;i1)a=o||{},i.forEach((function(r){"string"==typeof r?f(a,"#",r):f(a,r.n,e(r,t))}));else if(l){var c=i[0];if(a=e(c,t),c.n){var p={};p[c.n]=a,a=p}}else a=r.c?null:"";return t&&(a=t(r.n||"",a)),a}function f(r,t,n){if(void 0!==n){var s=r[t];s instanceof Array?s.push(n):r[t]=t in r?[s,n]:n}}r.fromXML=fromXML=function(r,t){return e(function(r){for(var t=String.prototype.split.call(r,/<([^!<>?](?:'[\S\s]*?'|"[\S\s]*?"|[^'"<>])*|!(?:--[\S\s]*?--|\[[^\[\]'"<>]+\[[\S\s]*?]]|DOCTYPE[^\[<>]*?\[[\S\s]*?]|(?:ENTITY[^"<>]*?"[\S\s]*?")?[\S\s]*?)|\?[\S\s]*?\?)>/),e=t.length,f={f:[]},u=f,a=[],o=0;o { - if (extension_dl_ids !== undefined) extension_dl_ids[dlid] = 1; - chrome.runtime.sendMessage({ - downloadId: dlid, - }); +function promptInstall(crx_url, is_webstore, browser = WEBSTORE.chrome) { + chrome.storage.sync.get(DEFAULT_MANAGEMENT_OPTIONS, function (settings) { + if (is_webstore && !settings.manually_install) { + switch (browser) { + case WEBSTORE.edge: + // normal methods fail because microsoft's official web store redirects you from HTTPS to an insecure HTTP url. + // instead use chrome.tabs to open the url in a new tab. + chrome.runtime.sendMessage({ + newTabUrl: crx_url, + }); + break; + case WEBSTORE.opera: + chrome.runtime.sendMessage({ + manualInstallDownloadUrl: crx_url, + }); + break; + default: + // copy the edge method instead of window.open(,_blank) so this works in the service worker + chrome.runtime.sendMessage({ + newTabUrl: crx_url, + }); + break; } - ); + return; + } + if (settings.manually_install) { + chrome.runtime.sendMessage({ + manualInstallDownloadUrl: crx_url, + }); + return; + } else { + chrome.runtime.sendMessage({ + nonWebstoreDownloadUrl: crx_url, + }); + return; + } + }); } function checkForUpdates( @@ -59,12 +94,7 @@ function checkForUpdates( ) { chrome.management.getAll(function (e) { e.push(...custom_ext_list); - let default_options = { - auto_update: true, - check_store_apps: true, - check_external_apps: true, - removed_extensions: {}, - }; + let default_options = { ...DEFAULT_MANAGEMENT_OPTIONS }; e.forEach(function (ex) { default_options[ex.id] = false; }); @@ -126,88 +156,80 @@ function checkForUpdates( return Promise.reject(); } else return r.text(); }) - .then((txt) => - new window.DOMParser().parseFromString( - txt, - "text/xml" - ) - ) + .then((txt) => { + let xml = fromXML(txt); + if (xml.gupdate.app["@appid"]) { + // its a single ext, put into array of size 1 + xml.gupdate.app = [xml.gupdate.app]; + } + return xml; + }) .then((data) => { - let updates = data.getElementsByTagName("app"); let updateCount = 0; - for (let i = 0; i < updates.length; i++) { + for (extinfo of data?.gupdate?.app ?? []) { + if (!extinfo.updatecheck) continue; + let updatever = + extinfo.updatecheck["@version"]; + let appid = extinfo["@appid"]; + let updatestatus = + extinfo.updatecheck["@status"]; if ( - (updateCheck = - updates[i].querySelector("*")) + (updatestatus == "ok" || + !is_webstore) && + updatever && + installed_versions[appid] !== + undefined && + version_is_newer( + installed_versions[appid].version, + updatever + ) ) { - let updatever = - updateCheck.getAttribute("version"); - let appid = - updates[i].getAttribute("appid"); - let updatestatus = - updateCheck.getAttribute("status"); + updateCount++; + if (update_callback) + update_callback( + extinfo.updatecheck, + installed_versions, + appid, + updatever, + is_webstore + ); if ( - (updatestatus == "ok" || - !is_webstore) && - updatever && - installed_versions[appid] !== - undefined && - version_is_newer( - installed_versions[appid] - .version, - updatever - ) + appid in + stored_values["removed_extensions"] ) { - updateCount++; - if (update_callback) - update_callback( - updateCheck, - installed_versions, - appid, - updatever, - is_webstore - ); - if ( - appid in - stored_values[ - "removed_extensions" - ] - ) { - delete stored_values[ - "removed_extensions" - ][appid]; - chrome.storage.sync.set({ - removed_extensions: - stored_values[ - "removed_extensions" - ], - }); - } + delete stored_values[ + "removed_extensions" + ][appid]; + chrome.storage.sync.set({ + removed_extensions: + stored_values[ + "removed_extensions" + ], + }); } - if ( - failure_callback && - updatestatus == "noupdate" && - !( - appid in - stored_values[ - "removed_extensions" - ] - ) - ) - failure_callback( - true, - installed_versions[appid] - ); } + if ( + failure_callback && + updatestatus == "noupdate" && + !( + appid in + stored_values["removed_extensions"] + ) + ) + failure_callback( + true, + installed_versions[appid] + ); + // } } - chrome.browserAction.getBadgeText( + chrome.action.getBadgeText( {}, function (currentText) { let disp = (updateCount || "") + (parseInt(currentText) || "") + ""; - chrome.browserAction.setBadgeText( + chrome.action.setBadgeText( { text: disp, }, @@ -226,6 +248,12 @@ function checkForUpdates( ); }) .catch((e) => { + console.log( + `Error updating extension [${ + ext_id || ext_name + }]:`, + e + ); if (failure_callback) { if (ext_id) failure_callback( @@ -241,21 +269,22 @@ function checkForUpdates( }); }); } - chrome.browserAction.setBadgeText( + chrome.action.setBadgeText( { text: "", }, () => { - let promises = updateUrls.map((uurl) => - update_extension(uurl.url, uurl.id, uurl.name) - ); + let promises = updateUrls.map((uurl) => { + if (uurl.url) + update_extension(uurl.url, uurl.id, uurl.name); + }); Promise.allSettled(promises).then((plist) => { if (plist.some((x) => x.status == "rejected")) { - chrome.browserAction.getBadgeText( + chrome.action.getBadgeText( {}, function (currentText) { if (!(parseInt(currentText) > 0)) - chrome.browserAction.setBadgeText({ + chrome.action.setBadgeText({ text: "?", }); }