--- a/browser/modules/ExtensionsUI.jsm
+++ b/browser/modules/ExtensionsUI.jsm
@@ -32,16 +32,18 @@ const BRAND_PROPERTIES = "chrome://brand
const HTML_NS = "http://www.w3.org/1999/xhtml";
var ExtensionsUI = {
sideloaded: new Set(),
updates: new Set(),
sideloadListener: null,
histogram: null,
+ pendingNotifications: new WeakMap(),
+
async init() {
this.histogram = Services.telemetry.getHistogramById("EXTENSION_INSTALL_PROMPT_RESULT");
Services.obs.addObserver(this, "webextension-permission-prompt");
Services.obs.addObserver(this, "webextension-update-permissions");
Services.obs.addObserver(this, "webextension-install-notify");
Services.obs.addObserver(this, "webextension-optional-permission-prompt");
Services.obs.addObserver(this, "webextension-defaultsearch-prompt");
@@ -316,54 +318,67 @@ var ExtensionsUI = {
let appName = brandBundle.GetStringFromName("brandShortName");
let info2 = Object.assign({appName}, info);
let strings = ExtensionData.formatPermissionStrings(info2, bundle);
strings.addonName = info.addon.name;
return strings;
},
- showPermissionsPrompt(browser, strings, icon, histkey) {
- function eventCallback(topic) {
- let doc = this.browser.ownerDocument;
- if (topic == "showing") {
- let textEl = doc.getElementById("addon-webext-perm-text");
- textEl.textContent = strings.text;
- textEl.hidden = !strings.text;
-
- let listIntroEl = doc.getElementById("addon-webext-perm-intro");
- listIntroEl.textContent = strings.listIntro;
- listIntroEl.hidden = (strings.msgs.length == 0);
+ async showPermissionsPrompt(browser, strings, icon, histkey) {
+ let win = browser.ownerGlobal;
- let list = doc.getElementById("addon-webext-perm-list");
- while (list.firstChild) {
- list.firstChild.remove();
- }
-
- for (let msg of strings.msgs) {
- let item = doc.createElementNS(HTML_NS, "li");
- item.textContent = msg;
- list.appendChild(item);
- }
- } else if (topic == "swapping") {
- return true;
- }
- return false;
+ // Wait for any pending prompts in this window to complete before
+ // showing the next one.
+ let pending;
+ while ((pending = this.pendingNotifications.get(win))) {
+ await pending;
}
- let popupOptions = {
- hideClose: true,
- popupIconURL: icon || DEFAULT_EXTENSION_ICON,
- persistent: true,
- eventCallback,
- name: strings.addonName,
- };
+ let promise = new Promise(resolve => {
+ function eventCallback(topic) {
+ let doc = this.browser.ownerDocument;
+ if (topic == "showing") {
+ let textEl = doc.getElementById("addon-webext-perm-text");
+ textEl.textContent = strings.text;
+ textEl.hidden = !strings.text;
+
+ let listIntroEl = doc.getElementById("addon-webext-perm-intro");
+ listIntroEl.textContent = strings.listIntro;
+ listIntroEl.hidden = (strings.msgs.length == 0);
+
+ let list = doc.getElementById("addon-webext-perm-list");
+ while (list.firstChild) {
+ list.firstChild.remove();
+ }
- let win = browser.ownerGlobal;
- return new Promise(resolve => {
+ for (let msg of strings.msgs) {
+ let item = doc.createElementNS(HTML_NS, "li");
+ item.textContent = msg;
+ list.appendChild(item);
+ }
+ } else if (topic == "swapping") {
+ return true;
+ }
+ if (topic == "removed") {
+ Services.tm.dispatchToMainThread(() => {
+ resolve(false);
+ });
+ }
+ return false;
+ }
+
+ let popupOptions = {
+ hideClose: true,
+ popupIconURL: icon || DEFAULT_EXTENSION_ICON,
+ persistent: true,
+ eventCallback,
+ name: strings.addonName,
+ };
+
let action = {
label: strings.acceptText,
accessKey: strings.acceptKey,
callback: () => {
if (histkey) {
this.histogram.add(histkey + "Accepted");
}
resolve(true);
@@ -381,16 +396,20 @@ var ExtensionsUI = {
},
},
];
win.PopupNotifications.show(browser, "addon-webext-permissions", strings.header,
"addons-notification-icon", action,
secondaryActions, popupOptions);
});
+
+ this.pendingNotifications.set(win, promise);
+ promise.finally(() => this.pendingNotifications.delete(win));
+ return promise;
},
showDefaultSearchPrompt(browser, strings, icon) {
return new Promise(resolve => {
let popupOptions = {
hideClose: true,
popupIconURL: icon || DEFAULT_EXTENSION_ICON,
persistent: false,
--- a/toolkit/modules/PopupNotifications.jsm
+++ b/toolkit/modules/PopupNotifications.jsm
@@ -845,17 +845,21 @@ PopupNotifications.prototype = {
popupnotification.removeAttribute("learnmoreurl");
if (n.options.displayURI) {
let uri;
try {
if (n.options.displayURI instanceof Ci.nsIFileURL) {
uri = n.options.displayURI.pathQueryRef;
} else {
- uri = n.options.displayURI.hostPort;
+ try {
+ uri = n.options.displayURI.hostPort;
+ } catch (e) {
+ uri = n.options.displayURI.spec;
+ }
}
popupnotification.setAttribute("origin", uri);
} catch (e) {
Cu.reportError(e);
popupnotification.removeAttribute("origin");
}
} else
popupnotification.removeAttribute("origin");
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -1799,20 +1799,20 @@ var gCategories = {
this.node = document.getElementById("categories");
var types = AddonManager.addonTypes;
for (var type in types)
this.onTypeAdded(types[type]);
AddonManager.addTypeListener(this);
- // eslint-disable-next-line mozilla/use-default-preference-values
- try {
- this.node.value = Services.prefs.getCharPref(PREF_UI_LASTCATEGORY);
- } catch (e) { }
+ // Set this to the default value first, or setting it to a nonexistent value
+ // from the pref will leave the old value in place.
+ this.node.value = gViewDefault;
+ this.node.value = Services.prefs.getStringPref(PREF_UI_LASTCATEGORY, "");
// If there was no last view or no existing category matched the last view
// then switch to the default category
if (!this.node.selectedItem) {
this.node.value = gViewDefault;
}
this.node.addEventListener("select", () => {
deleted file mode 100644
index 20ae355390f71cfd7519219c2d7bf30f58837851..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/browser/addons/browser_bug567127_1/install.rdf
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:install-manifest">
- <em:id>bug567127_1@tests.mozilla.org</em:id>
- <em:version>1.0</em:version>
-
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.3</em:minVersion>
- <em:maxVersion>*</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <em:targetApplication>
- <Description>
- <em:id>toolkit@mozilla.org</em:id>
- <em:minVersion>0</em:minVersion>
- <em:maxVersion>*</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <!-- Front End MetaData -->
- <em:name>browser_bug567127 #1</em:name>
-
- </Description>
-</RDF>
deleted file mode 100644
index 3c99022cfb8c58adab0b34492ae796255ede8990..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/browser/addons/browser_bug567127_2/install.rdf
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:install-manifest">
- <em:id>bug567127_2@tests.mozilla.org</em:id>
- <em:version>1.0</em:version>
-
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.3</em:minVersion>
- <em:maxVersion>*</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <em:targetApplication>
- <Description>
- <em:id>toolkit@mozilla.org</em:id>
- <em:minVersion>0</em:minVersion>
- <em:maxVersion>*</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <!-- Front End MetaData -->
- <em:name>browser_bug567127 #2</em:name>
-
- </Description>
-</RDF>
index d8b4d083ca456a0ec114e4a7b53e3a1b10857d8c..c121d31c4df27dd8dce1c8499a4ae314e2646b62
GIT binary patch
literal 4278
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
U&oQz7dVuk801q?f68@$B12?$fNB{r;
rename from toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/install.rdf
rename to toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/manifest.json
--- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/install.rdf
+++ b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/manifest.json
@@ -1,30 +1,12 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:install-manifest">
- <em:id>dragdrop1@tests.mozilla.org</em:id>
- <em:version>1.0</em:version>
+{
+ "manifest_version": 2,
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.3</em:minVersion>
- <em:maxVersion>*</em:maxVersion>
- </Description>
- </em:targetApplication>
+ "applications": {
+ "gecko": {
+ "id": "dragdrop-1@tests.mozilla.org"
+ }
+ },
- <em:targetApplication>
- <Description>
- <em:id>toolkit@mozilla.org</em:id>
- <em:minVersion>0</em:minVersion>
- <em:maxVersion>*</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <!-- Front End MetaData -->
- <em:name>Drag Drop test 1</em:name>
-
- </Description>
-</RDF>
+ "name": "Drag Drop test 1",
+ "version": "1.0"
+}
index e4441cb19be481b2ba4bf366f9e02c6e9cf756bc..dc6cc1a36fc740e92536342fb44dc71730bc64f5
GIT binary patch
literal 4282
zc${^YXHXN^7RN&`g1|xy-GcPq5u|qm(gY!dCWPL54M?w{2m*>AW$7X%2na?g0#c>-
z8bZ+okd7hn+&A-P=Q+FQ&iU}abLX6U=KR0>48bI%OaK6Y5-@}E(IdLNOkkr00DS2I
zfWL0_H6N)8>ps*H_3#RHad)>9@%6KtdK@B`jpIBSNo{})GK1eW4(0_hgEixXlH3^@
zrQ)%YCmQ3awYs<QSpitQb^nbLzAq0?-l|c32KiJTMjXHLtMj{*pJ^M3+#_7VN5d3P
z{S;3LVO|+SYEcuqq;BM1V#HDz{t_ub9mh6OA^;7C4oQX50BM|e42`m7l)nTQAgikA
zse`krJQK0XEhP4SsoXict8&JVQKeOYG*D;YvsjeBcO?VO2)VdK&wkV*KB_QHKVkd(
zDmInTko$f6A4@)k*ENXAX-iIOXx#5aKFSI3Cp%h9lCeG`kQ1p>C`6NVKK%4`dTD{k
zD}{k5?gXSV7pw?>v@e&+G}0Tdv!CI6{)39Yq@80^tp92YwGG(l6x6s$XL+%s4B6KJ
zWu(V2lmZ59H~xe<G?-g7DF$Ofl;jsV{VPPmY#OF4F{BLmsQ5Iagl*0Jo_qA9sT}Ta
zpX8k)&<d8V2d9d5vnta!Np~W%x+r6!S9IA|8+`ia=2{u8jK(VzJrwU>brIcFM_h!y
z|21qjja~VCm;v2wbwG98B-sh~d3g0o+LDs1a9>+~;&VQoC8~oCJ9@HAxOff28G|*W
zNifDQV;^Ji^^MH&X-|}ik!1TQ7tR^ftJhZP^A;or9T5-}pL%!;;Zs)Bv_Gc4Wcqp(
zifwS}5>f8UmSNkLKgzGC=~P>mj;uo{OWbr|A-Pr?z5j7s1jVW!Rx?rWfB2~;DQauP
zQfZ0fac%>28PYD3FtJeQqyR4KFW*eo)ICRc*~jCTjo%4>WPf}uyK;JQBx2m*b;gKo
zkw4a+MDQ3LbjCF#P*u@WyVQ&?CDHGr@yf+xJfH;@0ovhqUq)<X(vLjD{KP~SB%qCt
zekf819vH{J*CjS;iVb)@Hc8On#t?bAyM6P7L}@i^U-W>)@;=B7lmohhw(hv;vn7}0
zTrHTH9_{CUDJ}V#S0m)akTW!t3OB7NY4BYUz$)}I`}Zs?Avf&;HP_wN1kIay2M)}#
z-x+9k(b~{Z4h@B@GCKq-Wv}l6<N79o7MZ@A;vDHd7nLS5Dyw-`Fcp4q1go%GQ^Kr-
zjoSG+fQ<)pDV;xYFE0;L$bp>FUBne$tr2cr0$ye^_cPXp-0{p-SF44p6xT_}&5HOX
zBp)TiV#J5<vCe|1ECy(%wzuRp$0))gQL9rWiQEc*dhoXJb;M5XXjK|Y4Pz1*P}~&u
zM$gcP5^rcjx+O2^`BcapsG{*f9IicrlxWgSS%&^+miOB!5WVg^O?1VL5Ky=`dhqI&
z@%AO|hl1`+oD{6Vt!D6Hr_iwbitBiL2xG%=;q6>qTs`tYNKjYRWs~_QN+hZci>*@1
zE&tGIGOk5!*(gsaD;GLb%gB)*MJPa`>v%QR%tgW4#n8}!{IBb3!6Soi9h#vjfE$%I
zY%G)AJ6nQE{24O-7Y}~qZR5bA^=y#`FRZ>fSGGJ@wzL{Mo;8k+dbc5nPCMk9t{k2b
z&bAAX43J$J%))^YUQ(WKcr>1~Y035M18eM_jNa8UwK%o0?l<L6xa&`D`Q@~7Wal*d
zer8(!vTY)}wyW!CO$3<J;@a1b9uRB4ZX#f|Zz6bBY%F~BTB$W|$pFMyo0ax<;x=$*
z{XUHnQk1r5ff{6rhcwLqE$h58rlDjzS<u^32e1&$WW>`Lqq{=;-_iyZAL*vYwRD|@
zpYFCqQNXq~Zysywi!jFW7b@L3`5uzapU;DIW1(p2<vFk^eU>vtNNmPozQnXeGa(pq
zYUEwC_3u?RIchuJr?p9WNUK!^>um{OKZ2VIcg2{rhlI;!dFg>4tiYZG8?WLNhu6R#
zP|f$+@)E|gs?*1`oneF5^cZ|YH)oQAW|;;3O<oCH@1Y(h`_>l{nDnKowFeU;&@1A%
zO{NL9Wa$Y0<IUim1kY1o!g6c0sy|7Z8%*6ov7&NP%Hi4)x5>2E;i_6w-I-2mi2;*N
zxhgJ19#5y7&}i6sIW|DJs(Cm<cW~+LTc(h?oz#Uktc#Q>^%m*byA+}uh&HDuO}E3q
z&khaFBBfj|pJghGv}Ut}wqP|>#f}2Ed<V6gM)x`lq>|6lntviJ6wuYpwIewatu#U2
z=^n4<s6uh2#cYXri%(~cH}(Yu^Wa}}cZGz#pz%vHHz0A8E3GP)r~7J<*=<KuoEZP=
z9QRBW+k;Gqc)mg{mCyCPH!vvV179#Ul^STnvi{=z%D9T&-UIKW?JTr!=BVHkgHnW{
zi3HA{QGbOxq-=IMhPfG!d>Gs2Ijba){bTpmGkfWsCsRG4TJ2d`$hh6Ct3b2$+ZqJs
z;!l~kBk@?LdD(dF*vgj}9On&HF0+x%wyp*tV+i>g`+9;LTb)4*k>7BqJ$!Cm-bwn}
zJ6Pw+@xv3ueF%xMzF=!TSxJJP#Hjp-?N-=MUCe2wc7Now;qWN;yZU8mY9C3PtDj;k
zKgEJxBX`Up@sy|K!fu6&#u2lNz9s&c&hm=I$vZd27#mg8+<FYRuQkZ)O{At)?aUCD
zXTOU_dfe;%nf5F-njn8?4r0(XO`;rUT;v={uZMS^9EtW*Q$BDx$G!KMGB>gj*YOLj
z*atx{MisJB)sHQM9t?G~-}G^0g432Ak!ikIba8dH8lw9^|JA&N;|?D%TvDgCxhmp~
zRf)%L;iw^8=Q$7RF^FR~$!plXf1c@;bEWP9Bqn^71uKvI<l((+ZZHy*Ybcp#NU*T-
zG8HN#3}>9taq*Ja-D066ro+Cx$Ck<(OZ-WsADNzaT4-CZSlp$$p>$)pk3uC>4re5%
zqOVU92L~~VGSX1tXGo&5Pwh1_##N2K>1)8c!x%@qT%yx8H0_da*>GA*pk!h+2Ckpo
zOev%RyrwDG^{wZj@2DdFWP3;Fc9?;|4BGif8BCYfSNvml#JKLA$m)4SXt)@yp|CoT
z>DD1`2eIk`-q*mTfVOrpp7>lFLAb=;N3SywiHS?q;f2Y9Jp%<v*4geJ@#*Jb3F^VS
z`8g3wyl6nL`ovTKb;N^+(QIGO(n7Vc)!Fl$pGcG+pF`5F&{&yBt`?0Ay8zP@Agk(v
zV)3}AQwuT*p3k-le6qK>LO)=joX3wx)#WMIZcV3&44m7W$G*b)Se9LuNQVW5=B&*t
z$U260j-`?NR=>yk&(1eJGY-M<OK0tjRyk*s7OYd^*K^&oX!{R&Ho0e{<@VxRm<PSI
zUhnH`D>1-0Isecrui@mO@?P9xF=ZA<2SNjf)~nO%Z{!J(n*=f*^S<3|E;2^9s0S4H
zzOB4|uUUo@t}oS7TUc#Vq<9ckYUJ8!8u;_Z8~P$t!T}8?E_|xlK-MJgNt{P89>K!_
z>(B;34W^z8)q4z~R>(WVUJb`8)N)%juop3T1_eex8V&Gs#xNHQgqz4)JM;vG2R}HW
z&7dN*YV!8*&G_@0?p*S2Cd-*6VY@k5d=j620+NJBGc*PAE_ydJ4XCSv0#fK~&oAE3
zFE?8YX6$11D}AbJAAOAlJr>*!a>CYcQn&J%A(7=ONF&|hIfeFiw}ko&zfH6zkQ(j%
zqjWrwr~t)YcE%+Pclt)*+PyhBnI?{!IxK1Wrhpb3)~YL4QNZi~KeH1QG(~{&Ps`ki
zjdT`XI`leNXA+P_@XfJ$N>^K7YW4VmJ+fQ*9|}mbsxKpZM@21g>E5}XM820$vd<SU
zj#UbafUY!$HfrO`lfVm$IJ=WYt$rPKe`8j};Js0!#IKd9vY<E9Ke-i%C&eUU1(dtd
zr5H8D=iu?RDMoSu*7xA0Ka!YA>vr5;EFyf<Erhy?iILLtS}#MxUp&k7VJ9Y+dDU9o
zn(8xUh~F?dNP0e<vb@&0cUP43#Om=)d)hGUM4)%2$@0oj$d9%4fVuNo=hJ!wV54zS
z_s|_(++<Jbn4ZpydNk1#Vt@g~O0L*LCQ;I{+9ZwW%Q$F}d!YINpNCbGCnsS-@NIMf
zcS)O8QZCoWbKY@LRx36O*(oXz9W+G_3hRYmjZZLL7XF|fDm5EB_sYegtw*1`aozYR
z%~jh&RL7aZ-<aGCEol9CUfbfZI%pJBx?y(64++jj1%98TmH9q-meO4?+BZ+gZ=E!d
z{loL#noa1dg}SG{!sd<%Pp{iZnR5l>Md+k5*z3e9_@-4;h@Dm)8H0{AB>SFpE$8S3
zE7OynjWuWzfF|;|@oXgg>h&(Xp==UdU{MiD=+l|{llWs&*<I6+FzM_38r+^1r?;|c
z0x5IyzfGY{+HE7h7W8jR!CzfLBV~TNWnLuduzg;r1sMxT*Tvd2v$>itLm5lZLi)l^
z-&|YcWR5X9P45GS<vtv!BufO8)W+t>@3f$IcD}5k#ZWWAM_!r`GqY>YW*y;MSlbrF
zpqiGH!V45X{Q3Gzf{=A3ycA9bsCY$e7VP-MT1yso7YL4AMHtDjIcjJTXbpeC6!m{$
zYAW7G4{C;q2>+$3e&sKw0(jVYx;Vo8{6$>-ygW4#s?;R6X*5p@?>Hy|dtr~Qh7=z#
zztNdWd;sF;!1vsk*I)fu1oGtr=w)|zH^U>_=82s;qAe!fE3=sczY)Lus-9=KcfxyB
z5@pL>{AR-g<15}GGV|i$#dYzl&2K-N<Q))u7`-q0E{s$%4Yu;O-ubvI2Iz6JYbB%M
z|1sa#w96jymzoFs&V2v-uZN@JkS?9NArsju0T1*NEfeVNQA>J_EO(yMrR6ScqlHJf
zu)Ta)P_PFTtV<E%(7LaKFLrh%%IYDC0;d`il|<@htDBJg*)Pjy8ZrSwGtv?xnOH+#
zXn1bvNZJmcrBh`*(3>{Qc_u9R=zEpCq8-Ec#5=R(?bZE#bA?{<oIGO}@Y`v05;0%q
zMKVyng!h)(hv4?ZH+ZRW`_IBN<`77N30G4J&xpV2vIaP@t#LgO5DxhNDb*etROJ6s
zs9(wWPh{)o2pcq_Q!`|aTEia-F3JvT&$^2U2=`S2#dFKmD_GaN*Jftk2b@}W81xSc
zbfaLtL-UB49PUoY?Wd)K*F`N7d^1ct&f>T+FAnnjsHMWuy>bepawn5x?{v34?b>Qg
zzCst5>6k{N`q}AMH>UZ?ItWSCY~Z6#5ny=Kc^;N^0vua}^w$anF+GMZXdmZr#9DWh
zkMV3=GXxV6Gm-o|rT;IYhyee>?EkF*_;+jm9s0Dt8TI$(zuV>S=0~*uY@XjM{Jx66
bE6iX2$Hf?e$;khDK>F(de$7}$_m}z)BBAO>
rename from toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/install.rdf
rename to toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/manifest.json
--- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/install.rdf
+++ b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/manifest.json
@@ -1,30 +1,12 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:install-manifest">
- <em:id>dragdrop2@tests.mozilla.org</em:id>
- <em:version>1.0</em:version>
+{
+ "manifest_version": 2,
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.3</em:minVersion>
- <em:maxVersion>*</em:maxVersion>
- </Description>
- </em:targetApplication>
+ "applications": {
+ "gecko": {
+ "id": "dragdrop-2@tests.mozilla.org"
+ }
+ },
- <em:targetApplication>
- <Description>
- <em:id>toolkit@mozilla.org</em:id>
- <em:minVersion>0</em:minVersion>
- <em:maxVersion>*</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <!-- Front End MetaData -->
- <em:name>Drag Drop test 2</em:name>
-
- </Description>
-</RDF>
+ "name": "Drag Drop test 2",
+ "version": "1.1"
+}
index 15410cefc0ba5b6fe4b9bbbf667c2e5627baaf94..050b2d2cd81379a31886e693744443a65105550f
GIT binary patch
literal 4319
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
L-yVla|5E<}|CIB6
rename from toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/install.rdf
rename to toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/manifest.json
--- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/install.rdf
+++ b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/manifest.json
@@ -1,23 +1,13 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:install-manifest">
- <em:id>dragdrop_incompat@tests.mozilla.org</em:id>
- <em:version>1.0</em:version>
- <em:strictCompatibility>true</em:strictCompatibility>
+{
+ "manifest_version": 2,
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>1.0</em:minVersion>
- <em:maxVersion>45.0</em:maxVersion>
- </Description>
- </em:targetApplication>
+ "applications": {
+ "gecko": {
+ "id": "dragdrop-incompat@tests.mozilla.org",
+ "strict_max_version": "45.0"
+ }
+ },
- <!-- Front End MetaData -->
- <em:name>Incomatible Drag Drop test</em:name>
-
- </Description>
-</RDF>
+ "name": "Incomatible Drag Drop test",
+ "version": "1.1"
+}
--- a/toolkit/mozapps/extensions/test/browser/browser.ini
+++ b/toolkit/mozapps/extensions/test/browser/browser.ini
@@ -1,17 +1,15 @@
[DEFAULT]
tags = addons
support-files =
addons/*
addon_about.xul
addon_prefs.xul
discovery.html
- discovery_frame.html
- discovery_install.html
head.js
more_options.xul
options.xul
plugin_test.html
redirect.sjs
releaseNotes.xhtml
blockNoPlugins.xml
blockPluginHard.xml
@@ -62,17 +60,16 @@ skip-if = os == "linux" && !debug # Bug
[browser_bug608316.js]
[browser_bug616841.js]
[browser_bug618502.js]
[browser_bug679604.js]
[browser_bug590347.js]
[browser_checkAddonCompatibility.js]
[browser_details.js]
[browser_discovery.js]
-[browser_discovery_install.js]
[browser_dragdrop.js]
skip-if = buildapp == 'mulet'
[browser_dragdrop_incompat.js]
[browser_experiments.js]
[browser_file_xpi_no_process_switch.js]
[browser_getmorethemes.js]
[browser_globalwarnings.js]
[browser_gmpProvider.js]
--- a/toolkit/mozapps/extensions/test/browser/browser_bug567127.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_bug567127.js
@@ -4,94 +4,88 @@
// Tests bug 567127 - Add install button to the add-ons manager
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
var gManagerWindow;
-function checkInstallConfirmation(...urls) {
+/**
+ * Wait for the given PopupNotification to display
+ *
+ * @param {string} name
+ * The name of the notification to wait for.
+ *
+ * @returns {Promise}
+ * Resolves with the notification window.
+ */
+function promisePopupNotificationShown(name) {
return new Promise(resolve => {
- let nurls = urls.length;
+ function popupshown() {
+ let notification = PopupNotifications.getNotification(name);
+ if (!notification) { return; }
- let notificationCount = 0;
- let observer = {
- observe(aSubject, aTopic, aData) {
- var installInfo = aSubject.wrappedJSObject;
- isnot(installInfo.browser, null, "Notification should have non-null browser");
- notificationCount++;
- }
- };
- Services.obs.addObserver(observer, "addon-install-started");
+ ok(notification, `${name} notification shown`);
+ ok(PopupNotifications.isPanelOpen, "notification panel open");
- let windows = new Set();
-
- function handleDialog(window) {
- let list = window.document.getElementById("itemList");
- is(list.childNodes.length, 1, "Should be 1 install");
- let idx = urls.indexOf(list.children[0].url);
- isnot(idx, -1, "Install target is an expected url");
- urls.splice(idx, 1);
-
- window.document.documentElement.cancelDialog();
+ PopupNotifications.panel.removeEventListener("popupshown", popupshown);
+ resolve(PopupNotifications.panel.firstChild);
}
- let listener = {
- handleEvent(event) {
- let window = event.currentTarget;
- is(window.document.location.href, INSTALL_URI, "Should have opened the correct window");
+ PopupNotifications.panel.addEventListener("popupshown", popupshown);
+ });
+}
- executeSoon(() => handleDialog(window));
- },
+async function checkInstallConfirmation(...names) {
+ let notificationCount = 0;
+ let observer = {
+ observe(aSubject, aTopic, aData) {
+ var installInfo = aSubject.wrappedJSObject;
+ isnot(installInfo.browser, null, "Notification should have non-null browser");
+ notificationCount++;
+ }
+ };
+ Services.obs.addObserver(observer, "addon-install-started");
- onOpenWindow(window) {
- windows.add(window);
- let domwindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- domwindow.addEventListener("load", this, false, {once: true});
- },
+ let results = [];
- onCloseWindow(window) {
- if (!windows.has(window)) {
- return;
- }
- windows.delete(window);
+ let promise = promisePopupNotificationShown("addon-webext-permissions");
+ for (let i = 0; i < names.length; i++) {
+ let panel = await promise;
+ let name = panel.getAttribute("name");
+ results.push(name);
- if (windows.size > 0) {
- return;
- }
-
- is(urls.length, 0, "Saw install dialogs for all expected urls");
+ info(`Saw install for ${name}`);
+ if (results.length < names.length) {
+ info(`Waiting for installs for ${names.filter(n => !results.includes(n))}`);
- Services.wm.removeListener(listener);
-
- is(notificationCount, nurls, `Saw ${nurls} addon-install-started notifications`);
- Services.obs.removeObserver(observer, "addon-install-started");
+ promise = promisePopupNotificationShown("addon-webext-permissions");
+ }
+ panel.secondaryButton.click();
+ }
- resolve();
- }
- };
+ Assert.deepEqual(results.sort(), names.sort(), "Got expected installs");
- Services.wm.addListener(listener);
- });
+ is(notificationCount, names.length, `Saw ${names.length} addon-install-started notification`);
+ Services.obs.removeObserver(observer, "addon-install-started");
}
add_task(async function test_install_from_file() {
gManagerWindow = await open_manager("addons://list/extension");
var filePaths = [
- get_addon_file_url("browser_bug567127_1.xpi"),
- get_addon_file_url("browser_bug567127_2.xpi")
+ get_addon_file_url("browser_dragdrop1.xpi"),
+ get_addon_file_url("browser_dragdrop2.xpi")
];
MockFilePicker.setFiles(filePaths.map(aPath => aPath.file));
// Set handler that executes the core test after the window opens,
// and resolves the promise when the window closes
- let pInstallURIClosed = checkInstallConfirmation(...filePaths.map(path => path.spec));
+ let pInstallURIClosed = checkInstallConfirmation("Drag Drop test 1", "Drag Drop test 2");
gManagerWindow.gViewController.doCommand("cmd_installFromFile");
await pInstallURIClosed;
MockFilePicker.cleanup();
await close_manager(gManagerWindow);
});
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/browser/browser_discovery_install.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Tests that the discovery view can install add-ons correctly
-
-const MAIN_URL = "https://example.com/" + RELATIVE_DIR + "discovery_install.html";
-const GOOD_FRAMED_URL = "https://example.com/" + RELATIVE_DIR + "discovery_frame.html";
-const BAD_FRAMED_URL = "https://example.org/" + RELATIVE_DIR + "discovery_frame.html";
-
-const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts";
-
-// Allow SSL from non-built-in certs
-Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false);
-// Allow installs from the test site
-Services.perms.add(NetUtil.newURI("https://example.com/"), "install",
- Ci.nsIPermissionManager.ALLOW_ACTION);
-Services.perms.add(NetUtil.newURI("https://example.org/"), "install",
- Ci.nsIPermissionManager.ALLOW_ACTION);
-
-registerCleanupFunction(() => {
- Services.perms.remove(NetUtil.newURI("https://example.com/"), "install");
- Services.perms.remove(NetUtil.newURI("https://example.org/"), "install");
- Services.prefs.clearUserPref(PREF_INSTALL_REQUIREBUILTINCERTS);
-});
-
-function clickLink(frameLoader, id) {
- let link = frameLoader.contentDocument.getElementById(id);
- EventUtils.sendMouseEvent({type: "click"}, link);
-}
-
-function waitForInstall() {
- return new Promise(resolve => {
- wait_for_window_open((window) => {
- is(window.location, "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul",
- "Should have seen the install window");
- window.document.documentElement.cancelDialog();
- resolve();
- });
- });
-}
-
-function waitForFail() {
- return new Promise(resolve => {
- let listener = (subject, topic, data) => {
- Services.obs.removeObserver(listener, topic);
- resolve();
- };
- Services.obs.addObserver(listener, "addon-install-origin-blocked");
- });
-}
-
-// Tests that navigating to an XPI attempts to install correctly
-add_task(async function test_install_direct() {
- Services.prefs.setCharPref(PREF_DISCOVERURL, MAIN_URL);
-
- let managerWindow = await open_manager("addons://discover/");
- let browser = managerWindow.document.getElementById("discover-browser");
-
- clickLink(browser, "install-direct");
- await waitForInstall();
-
- await close_manager(managerWindow);
-});
-
-// Tests that installing via JS works correctly
-add_task(async function test_install_js() {
- Services.prefs.setCharPref(PREF_DISCOVERURL, MAIN_URL);
-
- let managerWindow = await open_manager("addons://discover/");
- let browser = managerWindow.document.getElementById("discover-browser");
-
- clickLink(browser, "install-js");
- await waitForInstall();
-
- await close_manager(managerWindow);
-});
-
-// Installing from an inner-frame of the same origin should work
-add_task(async function test_install_inner_direct() {
- Services.prefs.setCharPref(PREF_DISCOVERURL, GOOD_FRAMED_URL);
-
- let managerWindow = await open_manager("addons://discover/");
- let browser = managerWindow.document.getElementById("discover-browser");
- let frame = browser.contentDocument.getElementById("frame");
-
- clickLink(frame, "install-direct");
- await waitForInstall();
-
- await close_manager(managerWindow);
-});
-
-add_task(async function test_install_inner_js() {
- Services.prefs.setCharPref(PREF_DISCOVERURL, GOOD_FRAMED_URL);
-
- let managerWindow = await open_manager("addons://discover/");
- let browser = managerWindow.document.getElementById("discover-browser");
- let frame = browser.contentDocument.getElementById("frame");
-
- clickLink(frame, "install-js");
- await waitForInstall();
-
- await close_manager(managerWindow);
-});
-
-// Installing from an inner-frame of a different origin should fail
-add_task(async function test_install_xorigin_direct() {
- Services.prefs.setCharPref(PREF_DISCOVERURL, BAD_FRAMED_URL);
-
- let managerWindow = await open_manager("addons://discover/");
- let browser = managerWindow.document.getElementById("discover-browser");
- let frame = browser.contentDocument.getElementById("frame");
-
- clickLink(frame, "install-direct");
- await waitForFail();
-
- await close_manager(managerWindow);
-});
-
-add_task(async function test_install_xorigin_js() {
- Services.prefs.setCharPref(PREF_DISCOVERURL, BAD_FRAMED_URL);
-
- let managerWindow = await open_manager("addons://discover/");
- let browser = managerWindow.document.getElementById("discover-browser");
- let frame = browser.contentDocument.getElementById("frame");
-
- clickLink(frame, "install-js");
- await waitForFail();
-
- await close_manager(managerWindow);
-});
--- a/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js
@@ -9,76 +9,76 @@
// this automatically.
// Instead of loading EventUtils.js into the test scope in browser-test.js for all tests,
// we only need EventUtils.js for a few files which is why we are using loadSubScript.
var gManagerWindow;
var EventUtils = {};
Services.scriptloader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-function checkInstallConfirmation(...urls) {
- let nurls = urls.length;
+/**
+ * Wait for the given PopupNotification to display
+ *
+ * @param {string} name
+ * The name of the notification to wait for.
+ *
+ * @returns {Promise}
+ * Resolves with the notification window.
+ */
+function promisePopupNotificationShown(name) {
+ return new Promise(resolve => {
+ function popupshown() {
+ let notification = PopupNotifications.getNotification(name);
+ if (!notification) { return; }
+ ok(notification, `${name} notification shown`);
+ ok(PopupNotifications.isPanelOpen, "notification panel open");
+
+ PopupNotifications.panel.removeEventListener("popupshown", popupshown);
+ resolve(PopupNotifications.panel.firstChild);
+ }
+
+ PopupNotifications.panel.addEventListener("popupshown", popupshown);
+ });
+}
+
+async function checkInstallConfirmation(...names) {
let notificationCount = 0;
let observer = {
observe(aSubject, aTopic, aData) {
var installInfo = aSubject.wrappedJSObject;
isnot(installInfo.browser, null, "Notification should have non-null browser");
notificationCount++;
}
};
Services.obs.addObserver(observer, "addon-install-started");
- let windows = new Set();
+ let results = [];
+
+ let promise = promisePopupNotificationShown("addon-webext-permissions");
+ for (let i = 0; i < names.length; i++) {
+ let panel = await promise;
+ let name = panel.getAttribute("name");
+ results.push(name);
- function handleDialog(window) {
- let list = window.document.getElementById("itemList");
- is(list.childNodes.length, 1, "Should be 1 install");
- let idx = urls.indexOf(list.children[0].url);
- isnot(idx, -1, "Install target is an expected url");
- urls.splice(idx, 1);
+ info(`Saw install for ${name}`);
+ if (results.length < names.length) {
+ info(`Waiting for installs for ${names.filter(n => !results.includes(n))}`);
- window.document.documentElement.cancelDialog();
+ promise = promisePopupNotificationShown("addon-webext-permissions");
+ }
+ panel.secondaryButton.click();
}
- let listener = {
- handleEvent(event) {
- let window = event.currentTarget;
- is(window.document.location.href, INSTALL_URI, "Should have opened the correct window");
-
- executeSoon(() => handleDialog(window));
- },
-
- onOpenWindow(window) {
- windows.add(window);
- let domwindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- domwindow.addEventListener("load", this, false, {once: true});
- },
+ Assert.deepEqual(results.sort(), names.sort(), "Got expected installs");
- onCloseWindow(window) {
- if (!windows.has(window)) {
- return;
- }
- windows.delete(window);
-
- if (windows.size > 0 || urls.length > 0) {
- return;
- }
+ is(notificationCount, names.length, `Saw ${names.length} addon-install-started notification`);
+ Services.obs.removeObserver(observer, "addon-install-started");
- Services.wm.removeListener(listener);
-
- is(notificationCount, nurls, `Saw ${nurls} addon-install-started notifications`);
- Services.obs.removeObserver(observer, "addon-install-started");
-
- executeSoon(run_next_test);
- }
- };
-
- Services.wm.addListener(listener);
+ executeSoon(run_next_test);
}
function test() {
waitForExplicitFinish();
open_manager("addons://list/extension", function(aWindow) {
gManagerWindow = aWindow;
run_next_test();
@@ -87,77 +87,77 @@ function test() {
function end_test() {
close_manager(gManagerWindow, function() {
finish();
});
}
// Simulates dropping a URL onto the manager
-add_test(function() {
+add_test(function test_drop_url() {
var url = TESTROOT + "addons/browser_dragdrop1.xpi";
- checkInstallConfirmation(url);
+ checkInstallConfirmation("Drag Drop test 1");
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "text/x-moz-url", data: url}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
// Simulates dropping a file onto the manager
-add_test(function() {
+add_test(function test_drop_file() {
var fileurl = get_addon_file_url("browser_dragdrop1.xpi");
- checkInstallConfirmation(fileurl.spec);
+ checkInstallConfirmation("Drag Drop test 1");
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "application/x-moz-file", data: fileurl.file}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
// Simulates dropping two urls onto the manager
-add_test(function() {
+add_test(function test_drop_multiple_urls() {
var url1 = TESTROOT + "addons/browser_dragdrop1.xpi";
var url2 = TESTROOT2 + "addons/browser_dragdrop2.xpi";
- checkInstallConfirmation(url1, url2);
+ checkInstallConfirmation("Drag Drop test 1", "Drag Drop test 2");
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "text/x-moz-url", data: url1}],
[{type: "text/x-moz-url", data: url2}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
// Simulates dropping two files onto the manager
-add_test(function() {
+add_test(function test_drop_multiple_files() {
var fileurl1 = get_addon_file_url("browser_dragdrop1.xpi");
var fileurl2 = get_addon_file_url("browser_dragdrop2.xpi");
- checkInstallConfirmation(fileurl1.spec, fileurl2.spec);
+ checkInstallConfirmation("Drag Drop test 1", "Drag Drop test 2");
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "application/x-moz-file", data: fileurl1.file}],
[{type: "application/x-moz-file", data: fileurl2.file}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
// Simulates dropping a file and a url onto the manager (weird, but should still work)
-add_test(function() {
+add_test(function test_drop_file_and_url() {
var url = TESTROOT + "addons/browser_dragdrop1.xpi";
var fileurl = get_addon_file_url("browser_dragdrop2.xpi");
- checkInstallConfirmation(url, fileurl.spec);
+ checkInstallConfirmation("Drag Drop test 1", "Drag Drop test 2");
var viewContainer = gManagerWindow.document.getElementById("view-port");
var effect = EventUtils.synthesizeDrop(viewContainer, viewContainer,
[[{type: "text/x-moz-url", data: url}],
[{type: "application/x-moz-file", data: fileurl.file}]],
"copy", gManagerWindow);
is(effect, "copy", "Drag should be accepted");
});
--- a/toolkit/mozapps/extensions/test/browser/browser_file_xpi_no_process_switch.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_file_xpi_no_process_switch.js
@@ -1,12 +1,12 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-const ADDON_INSTALL_ID = "addon-install-confirmation";
+const ADDON_INSTALL_ID = "addon-webext-permissions";
let fileurl1 = get_addon_file_url("browser_dragdrop1.xpi");
let fileurl2 = get_addon_file_url("browser_dragdrop2.xpi");
function promiseInstallNotification(aBrowser) {
return new Promise(resolve => {
function popupshown(event) {
if (event.target.getAttribute("popupid") != ADDON_INSTALL_ID) {
@@ -16,17 +16,17 @@ function promiseInstallNotification(aBro
let notification =
PopupNotifications.getNotification(ADDON_INSTALL_ID, aBrowser);
if (!notification) {
return;
}
PopupNotifications.panel.removeEventListener("popupshown", popupshown);
ok(true, `Got ${ADDON_INSTALL_ID} popup for browser`);
- notification.remove();
+ event.target.firstChild.secondaryButton.click();
resolve();
}
PopupNotifications.panel.addEventListener("popupshown", popupshown);
});
}
function waitForAnyNewTabAndInstallNotification() {
@@ -39,16 +39,20 @@ function waitForAnyNewTabAndInstallNotif
}
function CheckBrowserInPid(browser, expectedPid, message) {
return ContentTask.spawn(browser, { expectedPid, message }, (arg) => {
is(Services.appinfo.processID, arg.expectedPid, arg.message);
});
}
+window.addEventListener("popupshown", ({target}) => {
+ dump(`MEH ${target.outerHTML}\n`);
+}, true);
+
async function testOpenedAndDraggedXPI(aBrowser) {
// Get the current pid for browser for comparison later.
let browserPid = await ContentTask.spawn(aBrowser, null, () => {
return Services.appinfo.processID;
});
// No process switch for XPI file:// URI in the urlbar.
let promiseNotification = promiseInstallNotification(aBrowser);
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/browser/discovery_frame.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<body>
-<iframe id="frame" width="100%" height="100%" src="https://example.com/browser/toolkit/mozapps/extensions/test/browser/discovery_install.html"></iframe>
-</body>
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/browser/discovery_install.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<html>
-<head>
-<script type="text/javascript">
-/* globals InstallTrigger */
-/* exported install */
-function install() {
- InstallTrigger.install({
- "Test Add-on": {
- URL: "https://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi"
- }
- });
-}
-</script>
-</head>
-<body>
- <h1>Test page for the discovery pane</h1>
- <p><a id="install-direct" href="https://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi">Direct install</a></p>
- <p><a id="install-js" href="javascript:install()">JS install</a></p>
-</body>
-</html>