mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Merge m-c to inbound.
This commit is contained in:
commit
cf27d1f9fe
@ -199,6 +199,11 @@ AutoCompleteResult.prototype =
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex)
|
||||
{
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
|
@ -783,10 +783,6 @@ var CustomEventManager = {
|
||||
case 'inputmethod-update-layouts':
|
||||
KeyboardHelper.handleEvent(detail);
|
||||
break;
|
||||
case 'nfc-hardware-state-change':
|
||||
Services.obs.notifyObservers(null, 'nfc-hardware-state-change',
|
||||
JSON.stringify({ nfcHardwareState: detail.nfcHardwareState }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
|
||||
@ -131,6 +131,6 @@
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="8afce6d5d48b71b6e7cb917179fb6147fb747521"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="72e3a520e3c700839f07ba0113fd527b923c3330"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="6a7ada569fd37c09ed4bbee6eb78cea5b467b229"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="baaf899afb158b9530690002f3656e958e3eb047"/>
|
||||
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
||||
</manifest>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="52c909ccead537f8f9dbf634f3e6639078a8b0bd">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "26f2c60c0ba0e64114467663c33c82360c13f4cf",
|
||||
"revision": "38d1561fe26c12f371c44a47c498722ce06518c2",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
|
||||
@ -127,7 +127,7 @@
|
||||
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
||||
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="6a7ada569fd37c09ed4bbee6eb78cea5b467b229"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="baaf899afb158b9530690002f3656e958e3eb047"/>
|
||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="76c94ac5dc3b8e17cc23d9cc3e2662b0d5d28b2e"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7e93b6de9633a162b735252e8182974456f741f4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -122,37 +122,38 @@ tabbrowser {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.tab-background {
|
||||
/* Explicitly set the visibility to override the value (collapsed)
|
||||
* we inherit from #TabsToolbar[collapsed] upon opening a browser window. */
|
||||
visibility: visible;
|
||||
/* The transition is only delayed for opening tabs. */
|
||||
transition: visibility 0ms 25ms;
|
||||
}
|
||||
|
||||
.tab-background:not([fadein]):not([pinned]) {
|
||||
visibility: hidden;
|
||||
/* Closing tabs are hidden without a delay. */
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
|
||||
.tab-background,
|
||||
.tab-close-button,
|
||||
.tab-label {
|
||||
/* Explicitly set the visibility to override the value (collapsed)
|
||||
* we inherit from #TabsToolbar[collapsed] upon opening a browser window. */
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.tab-background[fadein] {
|
||||
/* This transition is only wanted for opening tabs. */
|
||||
transition: visibility 0ms 25ms;
|
||||
}
|
||||
|
||||
.tab-background:not([fadein]) {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.tab-close-button[fadein],
|
||||
.tab-label[fadein] {
|
||||
/* This transition is only wanted for opening tabs. */
|
||||
transition: opacity 70ms 230ms,
|
||||
visibility 0ms 230ms;
|
||||
}
|
||||
|
||||
.tab-close-button:not([fadein]):not([pinned]),
|
||||
.tab-label:not([fadein]):not([pinned]) {
|
||||
.tab-close-button:not([fadein]),
|
||||
.tab-label:not([fadein]) {
|
||||
visibility: collapse;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.tab-throbber:not([fadein]):not([pinned]),
|
||||
.tab-icon-image:not([fadein]):not([pinned]) {
|
||||
.tab-throbber:not([fadein]),
|
||||
.tab-icon-image:not([fadein]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,10 @@ let gPage = {
|
||||
// Listen for 'unload' to unregister this page.
|
||||
addEventListener("unload", this, false);
|
||||
|
||||
// Listen for toggle button clicks.
|
||||
let button = document.getElementById("newtab-toggle");
|
||||
button.addEventListener("click", this, false);
|
||||
// XXX bug 991111 - Not all click events are correctly triggered when
|
||||
// listening from xhtml nodes -- in particular middle clicks on sites, so
|
||||
// listen from the xul window and filter then delegate
|
||||
addEventListener("click", this, false);
|
||||
|
||||
// Initialize sponsored panel
|
||||
this._sponsoredPanel = document.getElementById("sponsored-panel");
|
||||
@ -196,7 +197,22 @@ let gPage = {
|
||||
gAllPages.unregister(this);
|
||||
break;
|
||||
case "click":
|
||||
gAllPages.enabled = !gAllPages.enabled;
|
||||
let {button, target} = aEvent;
|
||||
if (target.id == "newtab-toggle") {
|
||||
if (button == 0) {
|
||||
gAllPages.enabled = !gAllPages.enabled;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Go up ancestors until we find a Site or not
|
||||
while (target) {
|
||||
if (target.hasOwnProperty("_newtabSite")) {
|
||||
target._newtabSite.onClick(aEvent);
|
||||
break;
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
break;
|
||||
case "dragover":
|
||||
if (gDrag.isValid(aEvent) && gDrag.draggedSite)
|
||||
|
@ -170,10 +170,6 @@ Site.prototype = {
|
||||
this._node.addEventListener("dragend", this, false);
|
||||
this._node.addEventListener("mouseover", this, false);
|
||||
|
||||
// XXX bug 991111 - Not all click events are correctly triggered when
|
||||
// listening from the xhtml node, so listen from the xul window and filter
|
||||
addEventListener("click", this, false);
|
||||
|
||||
// Specially treat the sponsored icon to prevent regular hover effects
|
||||
let sponsored = this._querySelector(".newtab-control-sponsored");
|
||||
sponsored.addEventListener("mouseover", () => {
|
||||
@ -218,11 +214,19 @@ Site.prototype = {
|
||||
/**
|
||||
* Handles site click events.
|
||||
*/
|
||||
_onClick: function Site_onClick(aEvent) {
|
||||
let target = aEvent.target;
|
||||
onClick: function Site_onClick(aEvent) {
|
||||
let {button, target} = aEvent;
|
||||
if (target.classList.contains("newtab-link") ||
|
||||
target.parentElement.classList.contains("newtab-link")) {
|
||||
this._recordSiteClicked(this.cell.index);
|
||||
// Record for primary and middle clicks
|
||||
if (button == 0 || button == 1) {
|
||||
this._recordSiteClicked(this.cell.index);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Only handle primary clicks for the remaining targets
|
||||
if (button != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -242,13 +246,6 @@ Site.prototype = {
|
||||
*/
|
||||
handleEvent: function Site_handleEvent(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "click":
|
||||
// Check the bitmask if the click event is for the site's descendants
|
||||
if (this._node.compareDocumentPosition(aEvent.target) &
|
||||
this._node.DOCUMENT_POSITION_CONTAINED_BY) {
|
||||
this._onClick(aEvent);
|
||||
}
|
||||
break;
|
||||
case "mouseover":
|
||||
this._node.removeEventListener("mouseover", this, false);
|
||||
this._speculativeConnect();
|
||||
|
@ -290,7 +290,6 @@
|
||||
return;
|
||||
|
||||
this.moveTabTo(aTab, this._numPinnedTabs - 1);
|
||||
aTab.setAttribute("fadein", "true");
|
||||
aTab.removeAttribute("pinned");
|
||||
aTab.style.MozMarginStart = "";
|
||||
this.tabContainer._unlockTabSizing();
|
||||
|
@ -17,6 +17,7 @@ skip-if = os == "mac" # Intermittent failures, bug 898317
|
||||
[browser_newtab_bug876313.js]
|
||||
[browser_newtab_bug991111.js]
|
||||
[browser_newtab_bug991210.js]
|
||||
[browser_newtab_bug998387.js]
|
||||
[browser_newtab_disable.js]
|
||||
[browser_newtab_drag_drop.js]
|
||||
[browser_newtab_drag_drop_ext.js]
|
||||
|
@ -8,7 +8,7 @@ function runTests() {
|
||||
// Remember if the click handler was triggered
|
||||
let cell = getCell(0);
|
||||
let clicked = false;
|
||||
cell.site._onClick = e => {
|
||||
cell.site.onClick = e => {
|
||||
clicked = true;
|
||||
executeSoon(TestRunner.next);
|
||||
};
|
||||
|
25
browser/base/content/test/newtab/browser_newtab_bug998387.js
Normal file
25
browser/base/content/test/newtab/browser_newtab_bug998387.js
Normal file
@ -0,0 +1,25 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function runTests() {
|
||||
yield setLinks("0");
|
||||
yield addNewTabPageTab();
|
||||
|
||||
// Remember if the click handler was triggered
|
||||
let {site} = getCell(0);
|
||||
let origOnClick = site.onClick;
|
||||
let clicked = false;
|
||||
site.onClick = e => {
|
||||
origOnClick.call(site, e);
|
||||
clicked = true;
|
||||
executeSoon(TestRunner.next);
|
||||
};
|
||||
|
||||
// Send a middle-click and make sure it happened
|
||||
let block = getContentDocument().querySelector(".newtab-control-block");
|
||||
yield EventUtils.synthesizeMouseAtCenter(block, {button: 1}, getContentWindow());
|
||||
ok(clicked, "middle click triggered click listener");
|
||||
|
||||
// Make sure the cell didn't actually get blocked
|
||||
checkGrid("0");
|
||||
}
|
@ -149,6 +149,7 @@ support-files =
|
||||
[browser_dbg_listaddons.js]
|
||||
[browser_dbg_listtabs-01.js]
|
||||
[browser_dbg_listtabs-02.js]
|
||||
[browser_dbg_listtabs-03.js]
|
||||
[browser_dbg_location-changes-01-simple.js]
|
||||
[browser_dbg_location-changes-02-blank.js]
|
||||
[browser_dbg_location-changes-03-new.js]
|
||||
|
80
browser/devtools/debugger/test/browser_dbg_listtabs-03.js
Normal file
80
browser/devtools/debugger/test/browser_dbg_listtabs-03.js
Normal file
@ -0,0 +1,80 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure the listTabs request works as specified.
|
||||
*/
|
||||
|
||||
const TAB1_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
|
||||
|
||||
let gTab1, gTab1Actor, gTab2, gTab2Actor, gClient;
|
||||
|
||||
function listTabs() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.listTabs(aResponse => {
|
||||
deferred.resolve(aResponse.tabs);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function request(params) {
|
||||
let deferred = promise.defer();
|
||||
gClient.request(params, deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(Task.async(function*(aType, aTraits) {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
let tab = yield addTab(TAB1_URL);
|
||||
|
||||
let tabs = yield listTabs();
|
||||
is(tabs.length, 2, "Should be two tabs");
|
||||
let tabGrip = tabs.filter(a => a.url ==TAB1_URL).pop();
|
||||
ok(tabGrip, "Should have an actor for the tab");
|
||||
|
||||
let response = yield request({ to: tabGrip.actor, type: "attach" });
|
||||
is(response.type, "tabAttached", "Should have attached");
|
||||
|
||||
tabs = yield listTabs();
|
||||
|
||||
response = yield request({ to: tabGrip.actor, type: "detach" });
|
||||
is(response.type, "detached", "Should have detached");
|
||||
|
||||
let newGrip = tabs.filter(a => a.url ==TAB1_URL).pop();
|
||||
is(newGrip.actor, tabGrip.actor, "Should have the same actor for the same tab");
|
||||
|
||||
response = yield request({ to: tabGrip.actor, type: "attach" });
|
||||
is(response.type, "tabAttached", "Should have attached");
|
||||
response = yield request({ to: tabGrip.actor, type: "detach" });
|
||||
is(response.type, "detached", "Should have detached");
|
||||
|
||||
yield removeTab(tab);
|
||||
yield closeConnection();
|
||||
finish();
|
||||
}));
|
||||
}
|
||||
|
||||
function closeConnection() {
|
||||
let deferred = promise.defer();
|
||||
gClient.close(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab1 = null;
|
||||
gTab1Actor = null;
|
||||
gTab2 = null;
|
||||
gTab2Actor = null;
|
||||
gClient = null;
|
||||
});
|
@ -53,6 +53,7 @@
|
||||
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gCspPRLog;
|
||||
@ -814,11 +815,10 @@ NotifyOffThreadScriptLoadCompletedRunnable::Run()
|
||||
static void
|
||||
OffThreadScriptLoaderCallback(void *aToken, void *aCallbackData)
|
||||
{
|
||||
NotifyOffThreadScriptLoadCompletedRunnable* aRunnable =
|
||||
static_cast<NotifyOffThreadScriptLoadCompletedRunnable*>(aCallbackData);
|
||||
nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> aRunnable =
|
||||
dont_AddRef(static_cast<NotifyOffThreadScriptLoadCompletedRunnable*>(aCallbackData));
|
||||
aRunnable->SetToken(aToken);
|
||||
NS_DispatchToMainThread(aRunnable);
|
||||
NS_RELEASE(aRunnable);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -848,12 +848,9 @@ nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NotifyOffThreadScriptLoadCompletedRunnable* runnable =
|
||||
nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> runnable =
|
||||
new NotifyOffThreadScriptLoadCompletedRunnable(aRequest, this);
|
||||
|
||||
// This reference will be consumed by OffThreadScriptLoaderCallback.
|
||||
NS_ADDREF(runnable);
|
||||
|
||||
if (!JS::CompileOffThread(cx, options,
|
||||
aRequest->mScriptText.get(), aRequest->mScriptText.Length(),
|
||||
OffThreadScriptLoaderCallback,
|
||||
@ -863,6 +860,7 @@ nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
|
||||
|
||||
mDocument->BlockOnload();
|
||||
|
||||
unused << runnable.forget();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -76,13 +76,11 @@ function InterAppCommService() {
|
||||
// "app://subApp1.gaiamobile.org/manifest.webapp": {
|
||||
// pageURL: "app://subApp1.gaiamobile.org/handler.html",
|
||||
// description: "blah blah",
|
||||
// appStatus: Ci.nsIPrincipal.APP_STATUS_CERTIFIED,
|
||||
// rules: { ... }
|
||||
// },
|
||||
// "app://subApp2.gaiamobile.org/manifest.webapp": {
|
||||
// pageURL: "app://subApp2.gaiamobile.org/handler.html",
|
||||
// description: "blah blah",
|
||||
// appStatus: Ci.nsIPrincipal.APP_STATUS_PRIVILEGED,
|
||||
// rules: { ... }
|
||||
// }
|
||||
// },
|
||||
@ -90,7 +88,6 @@ function InterAppCommService() {
|
||||
// "app://subApp3.gaiamobile.org/manifest.webapp": {
|
||||
// pageURL: "app://subApp3.gaiamobile.org/handler.html",
|
||||
// description: "blah blah",
|
||||
// appStatus: Ci.nsIPrincipal.APP_STATUS_INSTALLED,
|
||||
// rules: { ... }
|
||||
// }
|
||||
// }
|
||||
@ -214,14 +211,14 @@ function InterAppCommService() {
|
||||
|
||||
InterAppCommService.prototype = {
|
||||
registerConnection: function(aKeyword, aHandlerPageURI, aManifestURI,
|
||||
aDescription, aAppStatus, aRules) {
|
||||
aDescription, aRules) {
|
||||
let manifestURL = aManifestURI.spec;
|
||||
let pageURL = aHandlerPageURI.spec;
|
||||
|
||||
if (DEBUG) {
|
||||
debug("registerConnection: aKeyword: " + aKeyword +
|
||||
" manifestURL: " + manifestURL + " pageURL: " + pageURL +
|
||||
" aDescription: " + aDescription + " aAppStatus: " + aAppStatus +
|
||||
" aDescription: " + aDescription +
|
||||
" aRules.minimumAccessLevel: " + aRules.minimumAccessLevel +
|
||||
" aRules.manifestURLs: " + aRules.manifestURLs +
|
||||
" aRules.installOrigins: " + aRules.installOrigins);
|
||||
@ -235,7 +232,6 @@ InterAppCommService.prototype = {
|
||||
subAppManifestURLs[manifestURL] = {
|
||||
pageURL: pageURL,
|
||||
description: aDescription,
|
||||
appStatus: aAppStatus,
|
||||
rules: aRules,
|
||||
manifestURL: manifestURL
|
||||
};
|
||||
@ -300,7 +296,7 @@ InterAppCommService.prototype = {
|
||||
return false;
|
||||
},
|
||||
|
||||
_matchInstallOrigins: function(aRules, aManifestURL) {
|
||||
_matchInstallOrigins: function(aRules, aInstallOrigin) {
|
||||
if (!aRules || !Array.isArray(aRules.installOrigins)) {
|
||||
if (DEBUG) {
|
||||
debug("rules.installOrigins is not available. No need to match.");
|
||||
@ -308,31 +304,30 @@ InterAppCommService.prototype = {
|
||||
return true;
|
||||
}
|
||||
|
||||
let installOrigin =
|
||||
appsService.getAppByManifestURL(aManifestURL).installOrigin;
|
||||
|
||||
let installOrigins = aRules.installOrigins;
|
||||
if (installOrigins.indexOf(installOrigin) != -1) {
|
||||
if (installOrigins.indexOf(aInstallOrigin) != -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
debug("rules.installOrigins is not matched!" +
|
||||
" aManifestURL: " + aManifestURL +
|
||||
" installOrigins: " + installOrigins +
|
||||
" installOrigin : " + installOrigin);
|
||||
" installOrigin : " + aInstallOrigin);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_matchRules: function(aPubAppManifestURL, aPubAppStatus, aPubRules,
|
||||
aSubAppManifestURL, aSubAppStatus, aSubRules) {
|
||||
_matchRules: function(aPubAppManifestURL, aPubRules,
|
||||
aSubAppManifestURL, aSubRules) {
|
||||
let pubApp = appsService.getAppByManifestURL(aPubAppManifestURL);
|
||||
let subApp = appsService.getAppByManifestURL(aSubAppManifestURL);
|
||||
|
||||
// TODO Bug 907068 In the initiative step, we only expose this API to
|
||||
// certified apps to meet the time line. Eventually, we need to make
|
||||
// it available for the non-certified apps as well. For now, only the
|
||||
// certified apps can match the rules.
|
||||
if (aPubAppStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED ||
|
||||
aSubAppStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
|
||||
if (pubApp.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED ||
|
||||
subApp.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
|
||||
if (DEBUG) {
|
||||
debug("Only certified apps are allowed to do connections.");
|
||||
}
|
||||
@ -347,8 +342,8 @@ InterAppCommService.prototype = {
|
||||
}
|
||||
|
||||
// Check minimumAccessLevel.
|
||||
if (!this._matchMinimumAccessLevel(aPubRules, aSubAppStatus) ||
|
||||
!this._matchMinimumAccessLevel(aSubRules, aPubAppStatus)) {
|
||||
if (!this._matchMinimumAccessLevel(aPubRules, subApp.appStatus) ||
|
||||
!this._matchMinimumAccessLevel(aSubRules, pubApp.appStatus)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -359,8 +354,8 @@ InterAppCommService.prototype = {
|
||||
}
|
||||
|
||||
// Check installOrigins.
|
||||
if (!this._matchInstallOrigins(aPubRules, aSubAppManifestURL) ||
|
||||
!this._matchInstallOrigins(aSubRules, aPubAppManifestURL)) {
|
||||
if (!this._matchInstallOrigins(aPubRules, subApp.installOrigin) ||
|
||||
!this._matchInstallOrigins(aSubRules, pubApp.installOrigin)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -452,7 +447,6 @@ InterAppCommService.prototype = {
|
||||
let pubAppManifestURL = aMessage.manifestURL;
|
||||
let outerWindowID = aMessage.outerWindowID;
|
||||
let requestID = aMessage.requestID;
|
||||
let pubAppStatus = aMessage.appStatus;
|
||||
|
||||
let subAppManifestURLs = this._registeredConnections[keyword];
|
||||
if (!subAppManifestURLs) {
|
||||
@ -486,12 +480,11 @@ InterAppCommService.prototype = {
|
||||
|
||||
// Only rule-matched publishers/subscribers are allowed to connect.
|
||||
let subscribedInfo = subAppManifestURLs[subAppManifestURL];
|
||||
let subAppStatus = subscribedInfo.appStatus;
|
||||
let subRules = subscribedInfo.rules;
|
||||
|
||||
let matched =
|
||||
this._matchRules(pubAppManifestURL, pubAppStatus, pubRules,
|
||||
subAppManifestURL, subAppStatus, subRules);
|
||||
this._matchRules(pubAppManifestURL, pubRules,
|
||||
subAppManifestURL, subRules);
|
||||
if (!matched) {
|
||||
if (DEBUG) {
|
||||
debug("Rules are not matched. Skipping: " + subAppManifestURL);
|
||||
|
76
dom/apps/src/ScriptPreloader.jsm
Normal file
76
dom/apps/src/ScriptPreloader.jsm
Normal file
@ -0,0 +1,76 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ScriptPreloader"];
|
||||
|
||||
function debug(aMsg) {
|
||||
//dump("--*-- ScriptPreloader: " + aMsg + "\n");
|
||||
}
|
||||
|
||||
this.ScriptPreloader = {
|
||||
#ifdef MOZ_B2G
|
||||
_enabled: true,
|
||||
#else
|
||||
_enabled: false,
|
||||
#endif
|
||||
|
||||
preload: function(aApp, aManifest) {
|
||||
debug("Preloading " + aApp.origin);
|
||||
let deferred = Promise.defer();
|
||||
|
||||
if (!this._enabled) {
|
||||
deferred.resolve();
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
if (aManifest.precompile &&
|
||||
Array.isArray(aManifest.precompile) &&
|
||||
aManifest.precompile.length > 0) {
|
||||
let origin = Services.io.newURI(aApp.origin, null, null);
|
||||
let toLoad = aManifest.precompile.length;
|
||||
let principal =
|
||||
Services.scriptSecurityManager
|
||||
.getAppCodebasePrincipal(origin, aApp.localId, false);
|
||||
|
||||
aManifest.precompile.forEach((aPath) => {
|
||||
let uri = Services.io.newURI(aPath, null, origin);
|
||||
debug("Script to compile: " + uri.spec);
|
||||
try {
|
||||
Services.scriptloader.precompileScript(uri, principal,
|
||||
(aSubject, aTopic, aData) => {
|
||||
let uri = aSubject.QueryInterface(Ci.nsIURI);
|
||||
debug("Done compiling " + uri.spec);
|
||||
|
||||
toLoad--;
|
||||
if (toLoad == 0) {
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// Resolve the promise if precompileScript throws.
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// The precompile field is not an array, let the developer know.
|
||||
// We don't want to have to enable debug for that to show up.
|
||||
if (aManifest.precompile) {
|
||||
Cu.reportError("ASM.JS compilation failed: the 'precompile' manifest " +
|
||||
"property should be an array of script uris.\n");
|
||||
}
|
||||
deferred.resolve();
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
}
|
@ -486,7 +486,6 @@ WebappsApplication.prototype = {
|
||||
rules: aRules,
|
||||
manifestURL: this.manifestURL,
|
||||
outerWindowID: this._id,
|
||||
appStatus: this._appStatus,
|
||||
requestID: this.getPromiseResolverId({
|
||||
resolve: aResolve,
|
||||
reject: aReject
|
||||
|
@ -61,6 +61,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "WebappOSUtils",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ScriptPreloader",
|
||||
"resource://gre/modules/ScriptPreloader.jsm");
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
XPCOMUtils.defineLazyGetter(this, "libcutils", function() {
|
||||
Cu.import("resource://gre/modules/systemlibs.js");
|
||||
@ -734,7 +737,6 @@ this.DOMApplicationRegistry = {
|
||||
handlerPageURI,
|
||||
manifestURI,
|
||||
connection.description,
|
||||
AppsUtils.getAppManifestStatus(manifest),
|
||||
connection.rules);
|
||||
}
|
||||
},
|
||||
@ -1489,7 +1491,9 @@ this.DOMApplicationRegistry = {
|
||||
|
||||
delete app.retryingDownload;
|
||||
|
||||
this._saveApps().then(() => {
|
||||
// Update the asm.js scripts we need to compile.
|
||||
ScriptPreloader.preload(app, aData)
|
||||
.then(() => this._saveApps()).then(() => {
|
||||
// Update the handlers and permissions for this app.
|
||||
this.updateAppHandlers(aOldManifest, aData, app);
|
||||
|
||||
@ -2595,13 +2599,19 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
manifest: aManifest,
|
||||
manifestURL: aNewApp.manifestURL
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: ["downloadsuccess", "downloadapplied"],
|
||||
manifestURL: aNewApp.manifestURL
|
||||
});
|
||||
if (aInstallSuccessCallback) {
|
||||
aInstallSuccessCallback(aManifest, zipFile.path);
|
||||
}
|
||||
|
||||
// Check if we have asm.js code to preload for this application.
|
||||
ScriptPreloader.preload(aNewApp, aManifest)
|
||||
.then(() => {
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: ["downloadsuccess", "downloadapplied"],
|
||||
manifestURL: aNewApp.manifestURL
|
||||
});
|
||||
if (aInstallSuccessCallback) {
|
||||
aInstallSuccessCallback(aManifest, zipFile.path);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -36,6 +36,7 @@ EXTRA_JS_MODULES += [
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'AppsUtils.jsm',
|
||||
'OperatorApps.jsm',
|
||||
'ScriptPreloader.jsm',
|
||||
'Webapps.jsm',
|
||||
]
|
||||
|
||||
|
@ -16,7 +16,7 @@ interface nsIURI;
|
||||
*
|
||||
* [1] https://wiki.mozilla.org/WebAPI/Inter_App_Communication_Alt_proposal
|
||||
*/
|
||||
[scriptable, uuid(7fdd8b68-0b0a-11e3-9b4c-afbc236da250)]
|
||||
[scriptable, uuid(b3d711a4-c6a4-11e3-8fd3-738e7fbcb6d6)]
|
||||
interface nsIInterAppCommService : nsISupports
|
||||
{
|
||||
/*
|
||||
@ -27,14 +27,11 @@ interface nsIInterAppCommService : nsISupports
|
||||
* @param handlerPageURI The URI of the handler's page.
|
||||
* @param manifestURI The webapp's manifest URI.
|
||||
* @param description The connection's description.
|
||||
* @param appStatus The app status can be Ci.nsIPrincipal.APP_STATUS_[
|
||||
* NOT_INSTALLED, INSTALLED, PRIVILEGED, CERTIFIED].
|
||||
* @param rules The connection's rules.
|
||||
*/
|
||||
void registerConnection(in DOMString keyword,
|
||||
in nsIURI handlerPageURI,
|
||||
in nsIURI manifestURI,
|
||||
in DOMString description,
|
||||
in unsigned short appStatus,
|
||||
in jsval rules);
|
||||
};
|
||||
|
@ -416,7 +416,6 @@ function Nfc() {
|
||||
this.worker.onmessage = this.onmessage.bind(this);
|
||||
|
||||
Services.obs.addObserver(this, NFC.TOPIC_MOZSETTINGS_CHANGED, false);
|
||||
Services.obs.addObserver(this, NFC.TOPIC_HARDWARE_STATE, false);
|
||||
|
||||
gMessageManager.init(this);
|
||||
let lock = gSettingsService.createLock();
|
||||
@ -657,28 +656,11 @@ Nfc.prototype = {
|
||||
this.handle(setting.key, setting.value);
|
||||
}
|
||||
break;
|
||||
case NFC.TOPIC_HARDWARE_STATE:
|
||||
let state = JSON.parse(data);
|
||||
if (state) {
|
||||
let level = this.hardwareStateToPowerlevel(state.nfcHardwareState);
|
||||
this.setConfig({ powerLevel: level });
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
setConfig: function setConfig(prop) {
|
||||
this.sendToWorker("config", prop);
|
||||
},
|
||||
|
||||
hardwareStateToPowerlevel: function hardwareStateToPowerlevel(state) {
|
||||
switch (state) {
|
||||
case 0: return NFC.NFC_POWER_LEVEL_DISABLED;
|
||||
case 1: return NFC.NFC_POWER_LEVEL_ENABLED;
|
||||
case 2: return NFC.NFC_POWER_LEVEL_ENABLED;
|
||||
case 3: return NFC.NFC_POWER_LEVEL_LOW;
|
||||
default: return NFC.NFC_POWER_LEVEL_UNKNOWN;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -45,10 +45,15 @@ this.NFC_NOTIFICATION_TECH_DISCOVERED = 2001;
|
||||
this.NFC_NOTIFICATION_TECH_LOST = 2002;
|
||||
|
||||
this.NFC_TECHS = {
|
||||
0:'NDEF',
|
||||
1:'NDEF_WRITEABLE',
|
||||
2:'NDEF_FORMATABLE',
|
||||
3:'P2P'
|
||||
0:"NDEF",
|
||||
1:"NDEF_WRITEABLE",
|
||||
2:"NDEF_FORMATABLE",
|
||||
3:"P2P",
|
||||
4:"NFC_A",
|
||||
5:"NFC_B",
|
||||
6:"NFC_F",
|
||||
7:"NFC_V",
|
||||
8:"NFC_ISO_DEP"
|
||||
};
|
||||
|
||||
// TODO: Bug 933595. Fill-in all error codes for Gonk/nfcd protocol
|
||||
@ -63,7 +68,6 @@ this.NFC_POWER_LEVEL_ENABLED = 2;
|
||||
|
||||
this.TOPIC_MOZSETTINGS_CHANGED = "mozsettings-changed";
|
||||
this.TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
|
||||
this.TOPIC_HARDWARE_STATE = "nfc-hardware-state-change";
|
||||
this.SETTING_NFC_ENABLED = "nfc.enabled";
|
||||
|
||||
this.NFC_PEER_EVENT_READY = 0x01;
|
||||
|
@ -4346,6 +4346,8 @@ JS::ReadOnlyCompileOptions::copyPODOptions(const ReadOnlyCompileOptions &rhs)
|
||||
extraWarningsOption = rhs.extraWarningsOption;
|
||||
werrorOption = rhs.werrorOption;
|
||||
asmJSOption = rhs.asmJSOption;
|
||||
forceAsync = rhs.forceAsync;
|
||||
installedFile = rhs.installedFile;
|
||||
sourcePolicy = rhs.sourcePolicy;
|
||||
introductionType = rhs.introductionType;
|
||||
introductionLineno = rhs.introductionLineno;
|
||||
|
@ -6,7 +6,11 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(b21f1579-d994-4e99-a85d-a685140f3ec1)]
|
||||
interface nsIURI;
|
||||
interface nsIPrincipal;
|
||||
interface nsIObserver;
|
||||
|
||||
[scriptable, uuid(19533e7b-f321-4ef1-bc59-6e812dc2a733)]
|
||||
interface mozIJSSubScriptLoader : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -39,4 +43,22 @@ interface mozIJSSubScriptLoader : nsISupports
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
jsval loadSubScriptWithOptions(in AString url, in jsval options);
|
||||
|
||||
/*
|
||||
* Compiles a JS script off the main thread and calls back the
|
||||
* observer once it's done.
|
||||
* The script will be cached in temporary or persistent storage depending
|
||||
* on the principal used.
|
||||
* We fire the notification callback in all cases - there is no fatal
|
||||
* error there.
|
||||
* @param uri the uri of the script to load.
|
||||
* @param principal the principal from which we get the app id if any.
|
||||
* @param observer this observer will be called once the script has
|
||||
* been precompiled. The notification topic will be
|
||||
* 'script-precompiled' and the subject the uri of the
|
||||
* script as a nsIURI.
|
||||
*/
|
||||
void precompileScript(in nsIURI uri,
|
||||
in nsIPrincipal principal,
|
||||
in nsIObserver observer);
|
||||
};
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "nsIFileURL.h"
|
||||
#include "nsScriptLoader.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
@ -25,13 +26,16 @@
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "xpcpublic.h" // For xpc::SystemErrorReporter
|
||||
#include "xpcprivate.h" // For xpc::OptionsBase
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "mozilla/scache/StartupCache.h"
|
||||
#include "mozilla/scache/StartupCacheUtils.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
using namespace mozilla::scache;
|
||||
using namespace JS;
|
||||
using namespace xpc;
|
||||
using namespace mozilla;
|
||||
|
||||
class MOZ_STACK_CLASS LoadSubScriptOptions : public OptionsBase {
|
||||
public:
|
||||
@ -365,3 +369,211 @@ mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString &url,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Let us compile scripts from a URI off the main thread.
|
||||
*/
|
||||
|
||||
class ScriptPrecompiler : public nsIStreamLoaderObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMLOADEROBSERVER
|
||||
|
||||
ScriptPrecompiler(nsIObserver* aObserver,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIChannel* aChannel)
|
||||
: mObserver(aObserver)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mChannel(aChannel)
|
||||
{}
|
||||
|
||||
virtual ~ScriptPrecompiler()
|
||||
{}
|
||||
|
||||
static void OffThreadCallback(void *aToken, void *aData);
|
||||
|
||||
/* Sends the "done" notification back. Main thread only. */
|
||||
void SendObserverNotification();
|
||||
|
||||
private:
|
||||
nsRefPtr<nsIObserver> mObserver;
|
||||
nsRefPtr<nsIPrincipal> mPrincipal;
|
||||
nsRefPtr<nsIChannel> mChannel;
|
||||
nsString mScript;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ScriptPrecompiler, nsIStreamLoaderObserver);
|
||||
|
||||
class NotifyPrecompilationCompleteRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
NotifyPrecompilationCompleteRunnable(ScriptPrecompiler* aPrecompiler)
|
||||
: mPrecompiler(aPrecompiler)
|
||||
, mToken(nullptr)
|
||||
{}
|
||||
|
||||
void SetToken(void* aToken) {
|
||||
MOZ_ASSERT(aToken && !mToken);
|
||||
mToken = aToken;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsRefPtr<ScriptPrecompiler> mPrecompiler;
|
||||
void* mToken;
|
||||
};
|
||||
|
||||
/* RAII helper class to send observer notifications */
|
||||
class AutoSendObserverNotification {
|
||||
public:
|
||||
AutoSendObserverNotification(ScriptPrecompiler* aPrecompiler)
|
||||
: mPrecompiler(aPrecompiler)
|
||||
{}
|
||||
|
||||
~AutoSendObserverNotification() {
|
||||
if (mPrecompiler) {
|
||||
mPrecompiler->SendObserverNotification();
|
||||
}
|
||||
}
|
||||
|
||||
void Disarm() {
|
||||
mPrecompiler = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
ScriptPrecompiler* mPrecompiler;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
NotifyPrecompilationCompleteRunnable::Run(void)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mPrecompiler);
|
||||
|
||||
AutoSendObserverNotification notifier(mPrecompiler);
|
||||
|
||||
if (mToken) {
|
||||
JSRuntime *rt = XPCJSRuntime::Get()->Runtime();
|
||||
NS_ENSURE_TRUE(rt, NS_ERROR_FAILURE);
|
||||
JS::FinishOffThreadScript(nullptr, rt, mToken);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScriptPrecompiler::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
nsISupports* aContext,
|
||||
nsresult aStatus,
|
||||
uint32_t aLength,
|
||||
const uint8_t* aString)
|
||||
{
|
||||
AutoSendObserverNotification notifier(this);
|
||||
|
||||
// Just notify that we are done with this load.
|
||||
NS_ENSURE_SUCCESS(aStatus, NS_OK);
|
||||
|
||||
// Convert data to jschar* and prepare to call CompileOffThread.
|
||||
nsAutoString hintCharset;
|
||||
nsresult rv =
|
||||
nsScriptLoader::ConvertToUTF16(mChannel, aString, aLength,
|
||||
hintCharset, nullptr, mScript);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
|
||||
// Our goal is to cache persistently the compiled script and to avoid quota
|
||||
// checks. Since the caching mechanism decide the persistence type based on
|
||||
// the principal, we create a new global with the app's principal.
|
||||
// We then enter its compartment to compile with its principal.
|
||||
AutoSafeJSContext cx;
|
||||
RootedValue v(cx);
|
||||
SandboxOptions sandboxOptions;
|
||||
sandboxOptions.sandboxName.AssignASCII("asm.js precompilation");
|
||||
sandboxOptions.invisibleToDebugger = true;
|
||||
rv = CreateSandboxObject(cx, &v, mPrincipal, sandboxOptions);
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
|
||||
JSAutoCompartment ac(cx, js::UncheckedUnwrap(&v.toObject()));
|
||||
|
||||
JS::CompileOptions options(cx, JSVERSION_DEFAULT);
|
||||
options.setSourcePolicy(CompileOptions::NO_SOURCE);
|
||||
options.forceAsync = true;
|
||||
options.compileAndGo = true;
|
||||
options.installedFile = true;
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
mChannel->GetURI(getter_AddRefs(uri));
|
||||
nsAutoCString spec;
|
||||
uri->GetSpec(spec);
|
||||
options.setFile(spec.get());
|
||||
|
||||
if (!JS::CanCompileOffThread(cx, options, mScript.Length())) {
|
||||
NS_WARNING("Can't compile script off thread!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<NotifyPrecompilationCompleteRunnable> runnable =
|
||||
new NotifyPrecompilationCompleteRunnable(this);
|
||||
|
||||
if (!JS::CompileOffThread(cx, options,
|
||||
mScript.get(), mScript.Length(),
|
||||
OffThreadCallback,
|
||||
static_cast<void*>(runnable))) {
|
||||
NS_WARNING("Failed to compile script off thread!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
unused << runnable.forget();
|
||||
notifier.Disarm();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
ScriptPrecompiler::OffThreadCallback(void* aToken, void* aData)
|
||||
{
|
||||
nsRefPtr<NotifyPrecompilationCompleteRunnable> runnable =
|
||||
dont_AddRef(static_cast<NotifyPrecompilationCompleteRunnable*>(aData));
|
||||
runnable->SetToken(aToken);
|
||||
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
void
|
||||
ScriptPrecompiler::SendObserverNotification()
|
||||
{
|
||||
MOZ_ASSERT(mChannel && mObserver);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
mChannel->GetURI(getter_AddRefs(uri));
|
||||
mObserver->Observe(uri, "script-precompiled", nullptr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozJSSubScriptLoader::PrecompileScript(nsIURI* aURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIObserver *aObserver)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
aURI, nullptr, nullptr, nullptr,
|
||||
nsIRequest::LOAD_NORMAL, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<ScriptPrecompiler> loadObserver =
|
||||
new ScriptPrecompiler(aObserver, aPrincipal, channel);
|
||||
|
||||
nsCOMPtr<nsIStreamLoader> loader;
|
||||
rv = NS_NewStreamLoader(getter_AddRefs(loader), loadObserver);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIStreamListener> listener = loader.get();
|
||||
rv = channel->AsyncOpen(listener, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.fxa.authenticator.AccountPickler;
|
||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||
import org.mozilla.gecko.fxa.sync.FxAccountSyncAdapter;
|
||||
import org.mozilla.gecko.fxa.sync.FxAccountSyncStatusHelper;
|
||||
import org.mozilla.gecko.sync.ThreadPool;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
|
||||
@ -61,6 +62,13 @@ public class FirefoxAccounts {
|
||||
SyncHint.IGNORE_LOCAL_RATE_LIMIT,
|
||||
SyncHint.IGNORE_REMOTE_SERVER_BACKOFF);
|
||||
|
||||
public interface SyncStatusListener {
|
||||
public Context getContext();
|
||||
public Account getAccount();
|
||||
public void onSyncStarted();
|
||||
public void onSyncFinished();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a FirefoxAccount exists, false otherwise.
|
||||
*
|
||||
@ -200,13 +208,15 @@ public class FirefoxAccounts {
|
||||
* Any hints are strictly optional: the actual requested sync is scheduled by
|
||||
* the Android sync scheduler, and the sync mechanism may ignore hints as it
|
||||
* sees fit.
|
||||
* <p>
|
||||
* It is safe to call this method from any thread.
|
||||
*
|
||||
* @param account to sync.
|
||||
* @param syncHints to pass to sync.
|
||||
* @param stagesToSync stage names to sync.
|
||||
* @param stagesToSkip stage names to skip.
|
||||
*/
|
||||
public static void requestSync(Account account, EnumSet<SyncHint> syncHints, String[] stagesToSync, String[] stagesToSkip) {
|
||||
public static void requestSync(final Account account, EnumSet<SyncHint> syncHints, String[] stagesToSync, String[] stagesToSkip) {
|
||||
if (account == null) {
|
||||
throw new IllegalArgumentException("account must not be null");
|
||||
}
|
||||
@ -221,8 +231,37 @@ public class FirefoxAccounts {
|
||||
Logger.info(LOG_TAG, "Requesting sync.");
|
||||
logSyncHints(syncHints);
|
||||
|
||||
for (String authority : AndroidFxAccount.getAndroidAuthorities()) {
|
||||
ContentResolver.requestSync(account, authority, extras);
|
||||
}
|
||||
// We get strict mode warnings on some devices, so make the request on a
|
||||
// background thread.
|
||||
ThreadPool.run(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (String authority : AndroidFxAccount.getAndroidAuthorities()) {
|
||||
ContentResolver.requestSync(account, authority, extras);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Start notifying <code>syncStatusListener</code> of sync status changes.
|
||||
* <p>
|
||||
* Only a weak reference to <code>syncStatusListener</code> is held.
|
||||
*
|
||||
* @param syncStatusListener to start notifying.
|
||||
*/
|
||||
public static void addSyncStatusListener(SyncStatusListener syncStatusListener) {
|
||||
// startObserving null-checks its argument.
|
||||
FxAccountSyncStatusHelper.getInstance().startObserving(syncStatusListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop notifying <code>syncStatusListener</code> of sync status changes.
|
||||
*
|
||||
* @param syncStatusListener to stop notifying.
|
||||
*/
|
||||
public static void removeSyncStatusListener(SyncStatusListener syncStatusListener) {
|
||||
// stopObserving null-checks its argument.
|
||||
FxAccountSyncStatusHelper.getInstance().stopObserving(syncStatusListener);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import org.mozilla.gecko.fxa.login.State.Action;
|
||||
import org.mozilla.gecko.fxa.sync.FxAccountSyncStatusHelper;
|
||||
import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
@ -43,7 +44,7 @@ public class FxAccountConfirmAccountActivity extends FxAccountAbstractActivity i
|
||||
// Set in onResume.
|
||||
protected AndroidFxAccount fxAccount;
|
||||
|
||||
protected final SyncStatusDelegate syncStatusDelegate = new SyncStatusDelegate();
|
||||
protected final InnerSyncStatusDelegate syncStatusDelegate = new InnerSyncStatusDelegate();
|
||||
|
||||
public FxAccountConfirmAccountActivity() {
|
||||
super(CANNOT_RESUME_WHEN_NO_ACCOUNTS_EXIST);
|
||||
@ -102,7 +103,7 @@ public class FxAccountConfirmAccountActivity extends FxAccountAbstractActivity i
|
||||
}
|
||||
}
|
||||
|
||||
protected class SyncStatusDelegate implements FxAccountSyncStatusHelper.Delegate {
|
||||
protected class InnerSyncStatusDelegate implements FirefoxAccounts.SyncStatusListener {
|
||||
protected final Runnable refreshRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -111,17 +112,22 @@ public class FxAccountConfirmAccountActivity extends FxAccountAbstractActivity i
|
||||
};
|
||||
|
||||
@Override
|
||||
public AndroidFxAccount getAccount() {
|
||||
return fxAccount;
|
||||
public Context getContext() {
|
||||
return FxAccountConfirmAccountActivity.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSyncStarted() {
|
||||
public Account getAccount() {
|
||||
return fxAccount.getAndroidAccount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncStarted() {
|
||||
Logger.info(LOG_TAG, "Got sync started message; ignoring.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSyncFinished() {
|
||||
public void onSyncFinished() {
|
||||
if (fxAccount == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -19,7 +19,9 @@ import org.mozilla.gecko.fxa.login.State;
|
||||
import org.mozilla.gecko.fxa.sync.FxAccountSyncStatusHelper;
|
||||
import org.mozilla.gecko.sync.SyncConfiguration;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
@ -72,7 +74,7 @@ public class FxAccountStatusFragment extends PreferenceFragment implements OnPre
|
||||
// single account. (That is, it does not capture a single account instance.)
|
||||
protected Runnable requestSyncRunnable;
|
||||
|
||||
protected final SyncStatusDelegate syncStatusDelegate = new SyncStatusDelegate();
|
||||
protected final InnerSyncStatusDelegate syncStatusDelegate = new InnerSyncStatusDelegate();
|
||||
|
||||
protected Preference ensureFindPreference(String key) {
|
||||
Preference preference = findPreference(key);
|
||||
@ -240,7 +242,7 @@ public class FxAccountStatusFragment extends PreferenceFragment implements OnPre
|
||||
setCheckboxesEnabled(true);
|
||||
}
|
||||
|
||||
protected class SyncStatusDelegate implements FxAccountSyncStatusHelper.Delegate {
|
||||
protected class InnerSyncStatusDelegate implements FirefoxAccounts.SyncStatusListener {
|
||||
protected final Runnable refreshRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -249,12 +251,17 @@ public class FxAccountStatusFragment extends PreferenceFragment implements OnPre
|
||||
};
|
||||
|
||||
@Override
|
||||
public AndroidFxAccount getAccount() {
|
||||
return fxAccount;
|
||||
public Context getContext() {
|
||||
return FxAccountStatusFragment.this.getActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSyncStarted() {
|
||||
public Account getAccount() {
|
||||
return fxAccount.getAndroidAccount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncStarted() {
|
||||
if (fxAccount == null) {
|
||||
return;
|
||||
}
|
||||
@ -263,7 +270,7 @@ public class FxAccountStatusFragment extends PreferenceFragment implements OnPre
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSyncFinished() {
|
||||
public void onSyncFinished() {
|
||||
if (fxAccount == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.mozilla.gecko.fxa.FirefoxAccounts;
|
||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
@ -17,10 +18,6 @@ import android.content.SyncStatusObserver;
|
||||
* Abstract away some details of Android's SyncStatusObserver.
|
||||
* <p>
|
||||
* Provides a simplified sync started/sync finished delegate.
|
||||
* <p>
|
||||
* We would prefer to register multiple observers, but it's of limited value
|
||||
* right now, so we support only a single observer, and we are as tolerant as
|
||||
* possible of non-paired add/remove calls.
|
||||
*/
|
||||
public class FxAccountSyncStatusHelper implements SyncStatusObserver {
|
||||
@SuppressWarnings("unused")
|
||||
@ -35,27 +32,18 @@ public class FxAccountSyncStatusHelper implements SyncStatusObserver {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public interface Delegate {
|
||||
public AndroidFxAccount getAccount();
|
||||
public void handleSyncStarted();
|
||||
public void handleSyncFinished();
|
||||
}
|
||||
|
||||
// Used to unregister this as a listener.
|
||||
protected Object handle = null;
|
||||
|
||||
// Maps delegates to whether their underlying Android account was syncing the
|
||||
// last time we observed a status change.
|
||||
protected Map<Delegate, Boolean> delegates = new WeakHashMap<Delegate, Boolean>();
|
||||
protected Map<FirefoxAccounts.SyncStatusListener, Boolean> delegates = new WeakHashMap<FirefoxAccounts.SyncStatusListener, Boolean>();
|
||||
|
||||
@Override
|
||||
public synchronized void onStatusChanged(int which) {
|
||||
for (Entry<Delegate, Boolean> entry : delegates.entrySet()) {
|
||||
final Delegate delegate = entry.getKey();
|
||||
final AndroidFxAccount fxAccount = delegate.getAccount();
|
||||
if (fxAccount == null) {
|
||||
continue;
|
||||
}
|
||||
for (Entry<FirefoxAccounts.SyncStatusListener, Boolean> entry : delegates.entrySet()) {
|
||||
final FirefoxAccounts.SyncStatusListener delegate = entry.getKey();
|
||||
final AndroidFxAccount fxAccount = new AndroidFxAccount(delegate.getContext(), delegate.getAccount());
|
||||
final boolean active = fxAccount.isCurrentlySyncing();
|
||||
// Remember for later.
|
||||
boolean wasActiveLastTime = entry.getValue();
|
||||
@ -64,11 +52,11 @@ public class FxAccountSyncStatusHelper implements SyncStatusObserver {
|
||||
|
||||
if (active && !wasActiveLastTime) {
|
||||
// We've started a sync.
|
||||
delegate.handleSyncStarted();
|
||||
delegate.onSyncStarted();
|
||||
}
|
||||
if (!active && wasActiveLastTime) {
|
||||
// We've finished a sync.
|
||||
delegate.handleSyncFinished();
|
||||
delegate.onSyncFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,7 +77,7 @@ public class FxAccountSyncStatusHelper implements SyncStatusObserver {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void startObserving(Delegate delegate) {
|
||||
public synchronized void startObserving(FirefoxAccounts.SyncStatusListener delegate) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalArgumentException("delegate must not be null");
|
||||
}
|
||||
@ -103,7 +91,7 @@ public class FxAccountSyncStatusHelper implements SyncStatusObserver {
|
||||
delegates.put(delegate, Boolean.FALSE);
|
||||
}
|
||||
|
||||
public synchronized void stopObserving(Delegate delegate) {
|
||||
public synchronized void stopObserving(FirefoxAccounts.SyncStatusListener delegate) {
|
||||
delegates.remove(delegate);
|
||||
// If we are the last delegate leaving the party, stop listening.
|
||||
if (delegates.isEmpty()) {
|
||||
|
@ -410,7 +410,7 @@ nsAutoCompleteController::HandleKeyNavigation(uint32_t aKey, bool *_retval)
|
||||
if (selectedIndex >= 0) {
|
||||
// A result is selected, so fill in its value
|
||||
nsAutoString value;
|
||||
if (NS_SUCCEEDED(GetResultValueAt(selectedIndex, true, value))) {
|
||||
if (NS_SUCCEEDED(GetResultValueAt(selectedIndex, false, value))) {
|
||||
input->SetTextValue(value);
|
||||
input->SelectTextRange(value.Length(), value.Length());
|
||||
}
|
||||
@ -481,7 +481,7 @@ nsAutoCompleteController::HandleKeyNavigation(uint32_t aKey, bool *_retval)
|
||||
if (selectedIndex >= 0) {
|
||||
// The pop-up is open and has a selection, take its value
|
||||
nsAutoString value;
|
||||
if (NS_SUCCEEDED(GetResultValueAt(selectedIndex, true, value))) {
|
||||
if (NS_SUCCEEDED(GetResultValueAt(selectedIndex, false, value))) {
|
||||
input->SetTextValue(value);
|
||||
input->SelectTextRange(value.Length(), value.Length());
|
||||
}
|
||||
@ -579,7 +579,7 @@ nsAutoCompleteController::HandleDelete(bool *_retval)
|
||||
input->GetCompleteDefaultIndex(&shouldComplete);
|
||||
if (shouldComplete) {
|
||||
nsAutoString value;
|
||||
if (NS_SUCCEEDED(GetResultValueAt(index, true, value))) {
|
||||
if (NS_SUCCEEDED(GetResultValueAt(index, false, value))) {
|
||||
CompleteValue(value);
|
||||
}
|
||||
}
|
||||
@ -616,7 +616,7 @@ nsAutoCompleteController::GetResultAt(int32_t aIndex, nsIAutoCompleteResult** aR
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::GetValueAt(int32_t aIndex, nsAString & _retval)
|
||||
{
|
||||
GetResultLabelAt(aIndex, false, _retval);
|
||||
GetResultLabelAt(aIndex, _retval);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -624,7 +624,7 @@ nsAutoCompleteController::GetValueAt(int32_t aIndex, nsAString & _retval)
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::GetLabelAt(int32_t aIndex, nsAString & _retval)
|
||||
{
|
||||
GetResultLabelAt(aIndex, false, _retval);
|
||||
GetResultLabelAt(aIndex, _retval);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -662,6 +662,18 @@ nsAutoCompleteController::GetImageAt(int32_t aIndex, nsAString & _retval)
|
||||
return result->GetImageAt(rowIndex, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::GetFinalCompleteValueAt(int32_t aIndex,
|
||||
nsAString & _retval)
|
||||
{
|
||||
int32_t rowIndex;
|
||||
nsIAutoCompleteResult* result;
|
||||
nsresult rv = GetResultAt(aIndex, &result, &rowIndex);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return result->GetFinalCompleteValueAt(rowIndex, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::SetSearchString(const nsAString &aSearchString)
|
||||
{
|
||||
@ -1181,9 +1193,14 @@ nsAutoCompleteController::EnterMatch(bool aIsPopupSelection)
|
||||
// enter it into the textbox. If completeselectedindex is true, or
|
||||
// EnterMatch was called via other means, for instance pressing Enter,
|
||||
// don't fill in the value as it will have already been filled in as
|
||||
// needed.
|
||||
if (!completeSelection || aIsPopupSelection)
|
||||
GetResultValueAt(selectedIndex, true, value);
|
||||
// needed, unless the final complete value differs.
|
||||
nsAutoString finalValue, inputValue;
|
||||
GetResultValueAt(selectedIndex, true, finalValue);
|
||||
input->GetTextValue(inputValue);
|
||||
if (!completeSelection || aIsPopupSelection ||
|
||||
!finalValue.Equals(inputValue)) {
|
||||
value = finalValue;
|
||||
}
|
||||
}
|
||||
else if (shouldComplete) {
|
||||
// We usually try to preserve the casing of what user has typed, but
|
||||
@ -1206,7 +1223,7 @@ nsAutoCompleteController::EnterMatch(bool aIsPopupSelection)
|
||||
int32_t defaultIndex;
|
||||
result->GetDefaultIndex(&defaultIndex);
|
||||
if (defaultIndex >= 0) {
|
||||
result->GetValueAt(defaultIndex, value);
|
||||
result->GetFinalCompleteValueAt(defaultIndex, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1549,18 +1566,10 @@ nsAutoCompleteController::GetFinalDefaultCompleteValue(nsAString &_retval)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Hack: For typeAheadResults allow the comment to be used as the final
|
||||
// defaultComplete value if provided, otherwise fall back to the usual
|
||||
// value. This allows to provide a different complete text when the user
|
||||
// confirms the match. Don't rely on this for production code, since it's a
|
||||
// temporary solution that needs a dedicated API (bug 754265).
|
||||
bool isTypeAheadResult = false;
|
||||
nsAutoString commentValue;
|
||||
if (NS_SUCCEEDED(result->GetTypeAheadResult(&isTypeAheadResult)) &&
|
||||
isTypeAheadResult &&
|
||||
NS_SUCCEEDED(result->GetCommentAt(defaultIndex, commentValue)) &&
|
||||
!commentValue.IsEmpty()) {
|
||||
_retval = commentValue;
|
||||
nsAutoString finalCompleteValue;
|
||||
rv = result->GetFinalCompleteValueAt(defaultIndex, finalCompleteValue);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
_retval = finalCompleteValue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(FindInReadable(inputValue, _retval, nsCaseInsensitiveStringComparator()),
|
||||
@ -1625,20 +1634,23 @@ nsAutoCompleteController::CompleteValue(nsString &aValue)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAutoCompleteController::GetResultLabelAt(int32_t aIndex, bool aValueOnly, nsAString & _retval)
|
||||
nsAutoCompleteController::GetResultLabelAt(int32_t aIndex, nsAString & _retval)
|
||||
{
|
||||
return GetResultValueLabelAt(aIndex, aValueOnly, false, _retval);
|
||||
return GetResultValueLabelAt(aIndex, false, false, _retval);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAutoCompleteController::GetResultValueAt(int32_t aIndex, bool aValueOnly, nsAString & _retval)
|
||||
nsAutoCompleteController::GetResultValueAt(int32_t aIndex, bool aGetFinalValue,
|
||||
nsAString & _retval)
|
||||
{
|
||||
return GetResultValueLabelAt(aIndex, aValueOnly, true, _retval);
|
||||
return GetResultValueLabelAt(aIndex, aGetFinalValue, true, _retval);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAutoCompleteController::GetResultValueLabelAt(int32_t aIndex, bool aValueOnly,
|
||||
bool aGetValue, nsAString & _retval)
|
||||
nsAutoCompleteController::GetResultValueLabelAt(int32_t aIndex,
|
||||
bool aGetFinalValue,
|
||||
bool aGetValue,
|
||||
nsAString & _retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(aIndex >= 0 && (uint32_t) aIndex < mRowCount, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
@ -1651,12 +1663,14 @@ nsAutoCompleteController::GetResultValueLabelAt(int32_t aIndex, bool aValueOnly,
|
||||
result->GetSearchResult(&searchResult);
|
||||
|
||||
if (searchResult == nsIAutoCompleteResult::RESULT_FAILURE) {
|
||||
if (aValueOnly)
|
||||
if (aGetValue)
|
||||
return NS_ERROR_FAILURE;
|
||||
result->GetErrorDescription(_retval);
|
||||
} else if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
|
||||
searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
|
||||
if (aGetValue)
|
||||
if (aGetFinalValue)
|
||||
result->GetFinalCompleteValueAt(rowIndex, _retval);
|
||||
else if (aGetValue)
|
||||
result->GetValueAt(rowIndex, _retval);
|
||||
else
|
||||
result->GetLabelAt(rowIndex, _retval);
|
||||
|
@ -59,12 +59,11 @@ protected:
|
||||
|
||||
nsresult GetResultAt(int32_t aIndex, nsIAutoCompleteResult** aResult,
|
||||
int32_t* aRowIndex);
|
||||
nsresult GetResultValueAt(int32_t aIndex, bool aValueOnly,
|
||||
nsAString & _retval);
|
||||
nsresult GetResultLabelAt(int32_t aIndex, bool aValueOnly,
|
||||
nsresult GetResultValueAt(int32_t aIndex, bool aGetFinalValue,
|
||||
nsAString & _retval);
|
||||
nsresult GetResultLabelAt(int32_t aIndex, nsAString & _retval);
|
||||
private:
|
||||
nsresult GetResultValueLabelAt(int32_t aIndex, bool aValueOnly,
|
||||
nsresult GetResultValueLabelAt(int32_t aIndex, bool aGetFinalValue,
|
||||
bool aGetValue, nsAString & _retval);
|
||||
protected:
|
||||
|
||||
|
@ -90,7 +90,8 @@ NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::AppendMatch(const nsAString& aValue,
|
||||
const nsAString& aComment,
|
||||
const nsAString& aImage,
|
||||
const nsAString& aStyle)
|
||||
const nsAString& aStyle,
|
||||
const nsAString& aFinalCompleteValue)
|
||||
{
|
||||
CheckInvariants();
|
||||
|
||||
@ -111,6 +112,13 @@ nsAutoCompleteSimpleResult::AppendMatch(const nsAString& aValue,
|
||||
mImages.RemoveElementAt(mImages.Length() - 1);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (!mFinalCompleteValues.AppendElement(aFinalCompleteValue)) {
|
||||
mValues.RemoveElementAt(mValues.Length() - 1);
|
||||
mComments.RemoveElementAt(mComments.Length() - 1);
|
||||
mImages.RemoveElementAt(mImages.Length() - 1);
|
||||
mStyles.RemoveElementAt(mStyles.Length() - 1);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -170,6 +178,19 @@ nsAutoCompleteSimpleResult::GetStyleAt(int32_t aIndex, nsAString& _retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetFinalCompleteValueAt(int32_t aIndex,
|
||||
nsAString& _retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < int32_t(mFinalCompleteValues.Length()),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
CheckInvariants();
|
||||
_retval = mFinalCompleteValues[aIndex];
|
||||
if (_retval.Length() == 0)
|
||||
_retval = mValues[aIndex];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::SetListener(nsIAutoCompleteSimpleResultListener* aListener)
|
||||
{
|
||||
@ -189,6 +210,7 @@ nsAutoCompleteSimpleResult::RemoveValueAt(int32_t aRowIndex,
|
||||
mComments.RemoveElementAt(aRowIndex);
|
||||
mImages.RemoveElementAt(aRowIndex);
|
||||
mStyles.RemoveElementAt(aRowIndex);
|
||||
mFinalCompleteValues.RemoveElementAt(aRowIndex);
|
||||
|
||||
if (mListener)
|
||||
mListener->OnValueRemoved(this, removedValue, aRemoveFromDb);
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
NS_ASSERTION(mValues.Length() == mComments.Length(), "Arrays out of sync");
|
||||
NS_ASSERTION(mValues.Length() == mImages.Length(), "Arrays out of sync");
|
||||
NS_ASSERTION(mValues.Length() == mStyles.Length(), "Arrays out of sync");
|
||||
NS_ASSERTION(mValues.Length() == mFinalCompleteValues.Length(), "Arrays out of sync");
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -39,6 +40,7 @@ protected:
|
||||
nsTArray<nsString> mComments;
|
||||
nsTArray<nsString> mImages;
|
||||
nsTArray<nsString> mStyles;
|
||||
nsTArray<nsString> mFinalCompleteValues;
|
||||
|
||||
nsString mSearchString;
|
||||
nsString mErrorDescription;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
interface nsIAutoCompleteInput;
|
||||
|
||||
[scriptable, uuid(dd2c4489-e4bd-4702-86bc-e1691744e556)]
|
||||
[scriptable, uuid(ff9f8465-204a-47a6-b3c9-0628b3856684)]
|
||||
interface nsIAutoCompleteController : nsISupports
|
||||
{
|
||||
/*
|
||||
@ -134,6 +134,12 @@ interface nsIAutoCompleteController : nsISupports
|
||||
*/
|
||||
AString getImageAt(in long index);
|
||||
|
||||
/*
|
||||
* For the last completed search, get the final value that should be completed
|
||||
* when the user confirms the match at the given index
|
||||
*/
|
||||
AString getFinalCompleteValueAt(in long index);
|
||||
|
||||
/*
|
||||
* Get / set the current search string. Note, setting will not start searching
|
||||
*/
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(7b43fad1-c735-4b45-9383-c3f057fed20d)]
|
||||
[scriptable, uuid(9203c031-c4e7-4537-a4ec-81443d623d5a)]
|
||||
interface nsIAutoCompleteResult : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -81,6 +81,12 @@ interface nsIAutoCompleteResult : nsISupports
|
||||
*/
|
||||
AString getImageAt(in long index);
|
||||
|
||||
/**
|
||||
* Get the final value that should be completed when the user confirms
|
||||
* the match at the given index.
|
||||
*/
|
||||
AString getFinalCompleteValueAt(in long index);
|
||||
|
||||
/**
|
||||
* Remove the value at the given index from the autocomplete results.
|
||||
* If removeFromDb is set to true, the value should be removed from
|
||||
|
@ -14,7 +14,7 @@ interface nsIAutoCompleteSimpleResultListener;
|
||||
* an array.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(c738dc26-aa71-4561-a3fd-b5a0e4aa80d2)]
|
||||
[scriptable, uuid(fe8802f9-c2b7-4141-8e5b-280df3f62251)]
|
||||
interface nsIAutoCompleteSimpleResult : nsIAutoCompleteResult
|
||||
{
|
||||
/**
|
||||
@ -48,12 +48,25 @@ interface nsIAutoCompleteSimpleResult : nsIAutoCompleteResult
|
||||
void setTypeAheadResult(in boolean aHidden);
|
||||
|
||||
/**
|
||||
* Appends a result item consisting of the given value, comment, image and style.
|
||||
* This is how you add results. Note: image and style are optional.
|
||||
* Appends a match consisting of the given value, comment, image, style and
|
||||
* the value to use for defaultIndex completion.
|
||||
* @param aValue
|
||||
* The value to autocomplete to
|
||||
* @param aComment
|
||||
* Comment shown in the autocomplete widget to describe this match
|
||||
* @param aImage
|
||||
* Image shown in the autocomplete widget for this match.
|
||||
* @param aStyle
|
||||
* Describes how to style the match in the autocomplete widget
|
||||
* @param aFinalCompleteValue
|
||||
* Value used when the user confirms selecting this match. If not
|
||||
* provided, aValue will be used.
|
||||
*/
|
||||
void appendMatch(in AString aValue, in AString aComment,
|
||||
[optional] in AString aImage,
|
||||
[optional] in AString aStyle);
|
||||
void appendMatch(in AString aValue,
|
||||
in AString aComment,
|
||||
[optional] in AString aImage,
|
||||
[optional] in AString aStyle,
|
||||
[optional] in AString aFinalCompleteValue);
|
||||
|
||||
/**
|
||||
* Sets a listener for changes in the result.
|
||||
|
@ -78,7 +78,8 @@ AutoCompleteResultBase.prototype = {
|
||||
_values: null,
|
||||
_comments: [],
|
||||
_styles: [],
|
||||
|
||||
_finalCompleteValues: [],
|
||||
|
||||
searchString: "",
|
||||
searchResult: null,
|
||||
|
||||
@ -113,6 +114,10 @@ AutoCompleteResultBase.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this._finalCompleteValues[aIndex] || this._values[aIndex];
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
|
@ -123,6 +123,10 @@ AutoCompleteResult.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
|
@ -122,6 +122,10 @@ AutoCompleteResult.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
|
@ -121,6 +121,10 @@ AutoCompleteResult.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
|
@ -110,6 +110,10 @@ AutoCompleteResult.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
|
@ -0,0 +1,54 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function AutoCompleteResult(aValues, aFinalCompleteValues) {
|
||||
this._values = aValues;
|
||||
this._finalCompleteValues = aFinalCompleteValues;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popup.selectedIndex = 0;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_handleEnter() {
|
||||
doSearch("moz", "mozilla.com", "http://www.mozilla.com", function(aController) {
|
||||
do_check_eq(aController.input.textValue, "moz");
|
||||
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
aController.handleEnter(false);
|
||||
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResultValue, aFinalCompleteValue, aOnCompleteCallback) {
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult([ aResultValue ], [ aFinalCompleteValue ])
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput([ search.name ]);
|
||||
input.textValue = aSearchString;
|
||||
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function AutoCompleteResult(aValues, aFinalCompleteValues) {
|
||||
this._values = aValues;
|
||||
this._finalCompleteValues = aFinalCompleteValues;
|
||||
this.defaultIndex = 0;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popup.selectedIndex = -1;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_handleEnter() {
|
||||
doSearch("", "mozilla.com", "http://www.mozilla.com", function(aController) {
|
||||
do_check_eq(aController.input.textValue, "");
|
||||
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
aController.input.forceComplete = true;
|
||||
aController.handleEnter(false);
|
||||
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResultValue, aFinalCompleteValue, aOnCompleteCallback) {
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult([ aResultValue ], [ aFinalCompleteValue ])
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput([ search.name ]);
|
||||
input.textValue = aSearchString;
|
||||
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
@ -2,11 +2,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function AutoCompleteResult(aValues, aComments) {
|
||||
function AutoCompleteResult(aValues, aFinalCompleteValues) {
|
||||
this._values = aValues;
|
||||
this._comments = aComments;
|
||||
this._finalCompleteValues = aFinalCompleteValues;
|
||||
this.defaultIndex = 0;
|
||||
this._typeAheadResult = true;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
@ -37,10 +36,10 @@ add_test(function test_handleEnter() {
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResultValue, aCommentValue, aOnCompleteCallback) {
|
||||
function doSearch(aSearchString, aResultValue, aFinalCompleteValue, aOnCompleteCallback) {
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult([ aResultValue ], [ aCommentValue ], 0)
|
||||
new AutoCompleteResult([ aResultValue ], [ aFinalCompleteValue ])
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
|
@ -2,17 +2,16 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function AutoCompleteTypeAheadResult(aValues, aComments) {
|
||||
function AutoCompleteTypeAheadResult(aValues, aFinalCompleteValues) {
|
||||
this._values = aValues;
|
||||
this._comments = aComments;
|
||||
this._finalCompleteValues = aFinalCompleteValues;
|
||||
this.defaultIndex = 0;
|
||||
this._typeAheadResult = true;
|
||||
}
|
||||
AutoCompleteTypeAheadResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteResult(aValues, aComments) {
|
||||
function AutoCompleteResult(aValues) {
|
||||
this._values = aValues;
|
||||
this._comments = aComments;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
@ -45,7 +44,7 @@ function doSearch(aSearchString, aOnCompleteCallback) {
|
||||
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult([ "mozilla.org" ], [ "http://www.mozilla.org" ])
|
||||
new AutoCompleteResult([ "mozilla.org" ])
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
|
@ -121,6 +121,10 @@ AutoCompleteResult.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
|
@ -11,6 +11,8 @@ tail =
|
||||
[test_autocomplete_multiple.js]
|
||||
[test_badDefaultIndex.js]
|
||||
[test_completeDefaultIndex_casing.js]
|
||||
[test_finalCompleteValue.js]
|
||||
[test_finalCompleteValue_forceComplete.js]
|
||||
[test_finalDefaultCompleteValue.js]
|
||||
[test_hiddenResult.js]
|
||||
[test_immediate_search.js]
|
||||
|
@ -172,6 +172,11 @@ NS_IMETHODIMP nsFileResult::GetImageAt(int32_t index, nsAString & aImage)
|
||||
aImage.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsFileResult::GetFinalCompleteValueAt(int32_t index,
|
||||
nsAString & aValue)
|
||||
{
|
||||
return GetValueAt(index, aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFileResult::RemoveValueAt(int32_t rowIndex, bool removeFromDb)
|
||||
{
|
||||
|
@ -611,6 +611,10 @@ UserAutoCompleteResult.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt : function (index) {
|
||||
return this.getValueAt(index);
|
||||
},
|
||||
|
||||
removeValueAt : function (index, removeFromDB) {
|
||||
if (index < 0 || index >= this.logins.length)
|
||||
throw "Index out of range.";
|
||||
|
@ -156,9 +156,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node is a Bookmark folder, false otherwise
|
||||
*/
|
||||
nodeIsFolder: function PU_nodeIsFolder(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
return (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
|
||||
aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT);
|
||||
},
|
||||
@ -170,9 +167,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node represents a bookmarked URI, false otherwise
|
||||
*/
|
||||
nodeIsBookmark: function PU_nodeIsBookmark(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_URI &&
|
||||
aNode.itemId != -1;
|
||||
},
|
||||
@ -184,9 +178,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node is a Bookmark separator, false otherwise
|
||||
*/
|
||||
nodeIsSeparator: function PU_nodeIsSeparator(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR;
|
||||
},
|
||||
|
||||
@ -197,9 +188,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node is a URL item, false otherwise
|
||||
*/
|
||||
nodeIsURI: function PU_nodeIsURI(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_URI;
|
||||
},
|
||||
|
||||
@ -210,9 +198,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node is a Query item, false otherwise
|
||||
*/
|
||||
nodeIsQuery: function PU_nodeIsQuery(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY;
|
||||
},
|
||||
|
||||
@ -372,9 +357,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node is readonly, false otherwise
|
||||
*/
|
||||
nodeIsReadOnly: function PU_nodeIsReadOnly(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
let itemId = aNode.itemId;
|
||||
if (itemId != -1) {
|
||||
return this._readOnly.indexOf(itemId) != -1;
|
||||
@ -394,9 +376,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node is a host container, false otherwise
|
||||
*/
|
||||
nodeIsHost: function PU_nodeIsHost(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
|
||||
aNode.parent &&
|
||||
asQuery(aNode.parent).queryOptions.resultType ==
|
||||
@ -410,9 +389,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node is a day container, false otherwise
|
||||
*/
|
||||
nodeIsDay: function PU_nodeIsDay(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
var resultType;
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
|
||||
aNode.parent &&
|
||||
@ -428,9 +404,6 @@ this.PlacesUtils = {
|
||||
* @returns true if the node is a tag container, false otherwise
|
||||
*/
|
||||
nodeIsTagQuery: function PU_nodeIsTagQuery(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
|
||||
asQuery(aNode).queryOptions.resultType ==
|
||||
Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_CONTENTS;
|
||||
@ -446,9 +419,6 @@ this.PlacesUtils = {
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT,
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY],
|
||||
nodeIsContainer: function PU_nodeIsContainer(aNode) {
|
||||
if (!(aNode instanceof Ci.nsINavHistoryResultNode)) {
|
||||
throw new Error("Invalid Places node");
|
||||
}
|
||||
return this.containerTypes.indexOf(aNode.type) != -1;
|
||||
},
|
||||
|
||||
|
@ -1404,9 +1404,7 @@ urlInlineComplete.prototype = {
|
||||
untrimmedHost = null;
|
||||
}
|
||||
|
||||
// TODO (bug 754265): this is a temporary solution introduced while
|
||||
// waiting for a propert dedicated API.
|
||||
ac._result.appendMatch(ac._strippedPrefix + trimmedHost, untrimmedHost);
|
||||
ac._result.appendMatch(ac._strippedPrefix + trimmedHost, "", "", "", untrimmedHost);
|
||||
|
||||
// handleCompletion() will cause the result listener to be called, and
|
||||
// will display the result in the UI.
|
||||
@ -1480,9 +1478,7 @@ urlInlineComplete.prototype = {
|
||||
untrimmedURL = null;
|
||||
}
|
||||
|
||||
// TODO (bug 754265): this is a temporary solution introduced while
|
||||
// waiting for a propert dedicated API.
|
||||
ac._result.appendMatch(ac._strippedPrefix + url, untrimmedURL);
|
||||
ac._result.appendMatch(ac._strippedPrefix + url, "", "", "", untrimmedURL);
|
||||
|
||||
// handleCompletion() will cause the result listener to be called, and
|
||||
// will display the result in the UI.
|
||||
|
@ -542,6 +542,13 @@ TagAutoCompleteResult.prototype = {
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the image for the result at the given index
|
||||
*/
|
||||
getFinalCompleteValueAt: function PTACR_getFinalCompleteValueAt(index) {
|
||||
return this.getValueAt(index);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the value at the given index from the autocomplete results.
|
||||
* If removeFromDb is set to true, the value should be removed from
|
||||
|
@ -1,24 +0,0 @@
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function run_test() {
|
||||
let nodeIsMethods = [
|
||||
"nodeIsFolder",
|
||||
"nodeIsBookmark",
|
||||
"nodeIsSeparator",
|
||||
"nodeIsURI",
|
||||
"nodeIsQuery",
|
||||
"nodeIsReadOnly",
|
||||
"nodeIsHost",
|
||||
"nodeIsDay",
|
||||
"nodeIsTagQuery",
|
||||
"nodeIsContainer",
|
||||
"nodeIsHistoryContainer",
|
||||
"nodeIsQuery"
|
||||
];
|
||||
for (let methodName of nodeIsMethods) {
|
||||
Assert.throws(() => PlacesUtils[methodName](true), /Invalid Places node/);
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,6 @@ skip-if = true
|
||||
[test_placeURIs.js]
|
||||
[test_PlacesUtils_asyncGetBookmarkIds.js]
|
||||
[test_PlacesUtils_lazyobservers.js]
|
||||
[test_PlacesUtils_nodeIsXXX_invalidArg.js]
|
||||
[test_placesTxn.js]
|
||||
[test_preventive_maintenance.js]
|
||||
# Bug 676989: test hangs consistently on Android
|
||||
|
@ -476,6 +476,10 @@ FormAutoCompleteResult.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt : function (index) {
|
||||
return this.getValueAt(index);
|
||||
},
|
||||
|
||||
removeValueAt : function (index, removeFromDB) {
|
||||
this._checkIndexBounds(index);
|
||||
|
||||
|
@ -151,6 +151,15 @@ FormAutoCompleteResult.prototype = {
|
||||
return "";
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves a result
|
||||
* @param index the index of the result requested
|
||||
* @return the result at the specified index
|
||||
*/
|
||||
getFinalCompleteValueAt: function(index) {
|
||||
return this.getValueAt(index);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a result from the resultset
|
||||
* @param index the index of the result to remove
|
||||
|
@ -44,6 +44,7 @@ nsAutoCompleteSimpleResult.prototype = {
|
||||
getCommentAt: function() { return null; },
|
||||
getStyleAt: function() { return null; },
|
||||
getImageAt: function() { return null; },
|
||||
getFinalCompleteValueAt: function() { return this.getValueAt(); },
|
||||
getLabelAt: function() { return null; },
|
||||
removeValueAt: function() {}
|
||||
};
|
||||
|
@ -44,6 +44,7 @@ nsAutoCompleteSimpleResult.prototype = {
|
||||
getCommentAt: function() { return null; },
|
||||
getStyleAt: function() { return null; },
|
||||
getImageAt: function() { return null; },
|
||||
getFinalCompleteValueAt: function() { return this.getValueAt(); },
|
||||
getLabelAt: function() { return null; },
|
||||
removeValueAt: function() {}
|
||||
};
|
||||
|
@ -46,6 +46,7 @@ nsAutoCompleteSimpleResult.prototype = {
|
||||
getCommentAt: function() { return null; },
|
||||
getStyleAt: function() { return null; },
|
||||
getImageAt: function() { return null; },
|
||||
getFinalCompleteValueAt: function() { return this.getValueAt(); },
|
||||
getLabelAt: function() { return null; },
|
||||
removeValueAt: function() {}
|
||||
};
|
||||
|
@ -42,6 +42,7 @@ nsAutoCompleteSimpleResult.prototype = {
|
||||
getCommentAt: function() { return null; },
|
||||
getStyleAt: function() { return null; },
|
||||
getImageAt: function() { return null; },
|
||||
getFinalCompleteValueAt: function() { return this.getValueAt(); },
|
||||
getLabelAt: function() { return null; },
|
||||
removeValueAt: function() {}
|
||||
};
|
||||
|
@ -42,6 +42,7 @@ autoCompleteSimpleResult.prototype = {
|
||||
getCommentAt: function() { return null; },
|
||||
getStyleAt: function() { return null; },
|
||||
getImageAt: function() { return null; },
|
||||
getFinalCompleteValueAt: function() { return this.getValueAt(); },
|
||||
getLabelAt: function() { return null; },
|
||||
removeValueAt: function() {}
|
||||
};
|
||||
|
@ -57,6 +57,7 @@ nsAutoCompleteSimpleResult.prototype = {
|
||||
getCommentAt: function() { return null; },
|
||||
getStyleAt: function() { return null; },
|
||||
getImageAt: function() { return null; },
|
||||
getFinalCompleteValueAt: function(aIndex) { return this.getValueAt(aIndex); },
|
||||
getLabelAt: function() { return null; },
|
||||
removeValueAt: function() {}
|
||||
};
|
||||
|
@ -34,6 +34,10 @@
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
.controlsOverlay[scaled] {
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
/* CSS Transitions
|
||||
*
|
||||
* These are overriden by the default theme; the rules here just
|
||||
|
@ -325,6 +325,7 @@
|
||||
controlsSpacer : null,
|
||||
clickToPlay : null,
|
||||
stats : {},
|
||||
controlsOverlay : null,
|
||||
fullscreenButton : null,
|
||||
|
||||
randomID : 0,
|
||||
@ -1390,10 +1391,36 @@
|
||||
let videoHeight = isAudioOnly ? minHeightForControlBar : this.video.clientHeight;
|
||||
let videoWidth = isAudioOnly ? minWidthAllControls : this.video.clientWidth;
|
||||
|
||||
if ((this._overlayPlayButtonHeight + this._controlBarHeight) > videoHeight || this._overlayPlayButtonWidth > videoWidth)
|
||||
// Adapt the size of the controls to the size of the video
|
||||
if (this.video.readyState >= this.video.HAVE_METADATA) {
|
||||
if (!this.isAudioOnly && this.video.videoWidth && this.video.videoHeight) {
|
||||
var rect = this.video.getBoundingClientRect();
|
||||
var widthRatio = rect.width / this.video.videoWidth;
|
||||
var heightRatio = rect.height / this.video.videoHeight;
|
||||
var width = this.video.videoWidth * Math.min(widthRatio, heightRatio);
|
||||
|
||||
this.controlsOverlay.setAttribute("scaled", true);
|
||||
this.controlsOverlay.style.width = width + "px";
|
||||
this.controlsSpacer.style.width = width + "px";
|
||||
this.controlBar.style.width = width + "px";
|
||||
} else {
|
||||
this.controlsOverlay.removeAttribute("scaled");
|
||||
this.controlsOverlay.style.width = "";
|
||||
this.controlsSpacer.style.width = "";
|
||||
this.controlBar.style.width = "";
|
||||
}
|
||||
}
|
||||
|
||||
if ((this._overlayPlayButtonHeight + this._controlBarHeight) > videoHeight ||
|
||||
this._overlayPlayButtonWidth > videoWidth) {
|
||||
this.clickToPlay.hidden = true;
|
||||
else if (this.clickToPlay.hidden && !this.video.played.length)
|
||||
} else if (this.clickToPlay.hidden &&
|
||||
!this.video.played.length &&
|
||||
this.video.paused) {
|
||||
// Check this.video.paused to handle when a video is
|
||||
// playing but hasn't processed any frames yet
|
||||
this.clickToPlay.hidden = false;
|
||||
}
|
||||
|
||||
let size = "normal";
|
||||
if (videoHeight < minHeightForControlBar)
|
||||
@ -1422,6 +1449,7 @@
|
||||
this.positionLabel = document.getAnonymousElementByAttribute(binding, "class", "positionLabel");
|
||||
this.statusOverlay = document.getAnonymousElementByAttribute(binding, "class", "statusOverlay");
|
||||
this.statsOverlay = document.getAnonymousElementByAttribute(binding, "class", "statsOverlay");
|
||||
this.controlsOverlay = document.getAnonymousElementByAttribute(binding, "class", "controlsOverlay");
|
||||
this.controlsSpacer = document.getAnonymousElementByAttribute(binding, "class", "controlsSpacer");
|
||||
this.clickToPlay = document.getAnonymousElementByAttribute(binding, "class", "clickToPlay");
|
||||
this.fullscreenButton = document.getAnonymousElementByAttribute(binding, "class", "fullscreenButton");
|
||||
|
@ -942,9 +942,15 @@ TabActor.prototype = {
|
||||
* True if the window.console object is native, or false otherwise.
|
||||
*/
|
||||
hasNativeConsoleAPI: function BTA_hasNativeConsoleAPI(aWindow) {
|
||||
// Do not expose WebConsoleActor function directly as it is always
|
||||
// loaded after the BrowserTabActor
|
||||
return WebConsoleActor.prototype.hasNativeConsoleAPI(aWindow);
|
||||
let isNative = false;
|
||||
try {
|
||||
// We are very explicitly examining the "console" property of
|
||||
// the non-Xrayed object here.
|
||||
let console = aWindow.wrappedJSObject.console;
|
||||
isNative = console instanceof aWindow.Console;
|
||||
}
|
||||
catch (ex) { }
|
||||
return isNative;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -6,28 +6,34 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
let {Cc, Ci, Cu} = require("chrome");
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
|
||||
let { DebuggerServer, ActorPool } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||
// Symbols from script.js
|
||||
let { ThreadActor, EnvironmentActor, ObjectActor, LongStringActor } = DebuggerServer;
|
||||
|
||||
Cu.import("resource://gre/modules/jsdebugger.jsm");
|
||||
addDebuggerToGlobal(this);
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyGetter(this, "NetworkMonitor", () => {
|
||||
return devtools.require("devtools/toolkit/webconsole/network-monitor")
|
||||
return require("devtools/toolkit/webconsole/network-monitor")
|
||||
.NetworkMonitor;
|
||||
});
|
||||
XPCOMUtils.defineLazyGetter(this, "NetworkMonitorChild", () => {
|
||||
return devtools.require("devtools/toolkit/webconsole/network-monitor")
|
||||
return require("devtools/toolkit/webconsole/network-monitor")
|
||||
.NetworkMonitorChild;
|
||||
});
|
||||
XPCOMUtils.defineLazyGetter(this, "ConsoleProgressListener", () => {
|
||||
return devtools.require("devtools/toolkit/webconsole/network-monitor")
|
||||
return require("devtools/toolkit/webconsole/network-monitor")
|
||||
.ConsoleProgressListener;
|
||||
});
|
||||
XPCOMUtils.defineLazyGetter(this, "events", () => {
|
||||
return require("sdk/event/core");
|
||||
});
|
||||
|
||||
for (let name of ["WebConsoleUtils", "ConsoleServiceListener",
|
||||
"ConsoleAPIListener", "JSTermHelpers", "JSPropertyProvider",
|
||||
@ -37,7 +43,7 @@ for (let name of ["WebConsoleUtils", "ConsoleServiceListener",
|
||||
if (prop == "WebConsoleUtils") {
|
||||
prop = "Utils";
|
||||
}
|
||||
return devtools.require("devtools/toolkit/webconsole/utils")[prop];
|
||||
return require("devtools/toolkit/webconsole/utils")[prop];
|
||||
}.bind(null, name),
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
@ -1828,6 +1834,12 @@ NetworkEventActor.prototype.requestTypes =
|
||||
"getEventTimings": NetworkEventActor.prototype.onGetEventTimings,
|
||||
};
|
||||
|
||||
DebuggerServer.addTabActor(WebConsoleActor, "consoleActor");
|
||||
DebuggerServer.addGlobalActor(WebConsoleActor, "consoleActor");
|
||||
exports.register = function(handle) {
|
||||
handle.addGlobalActor(WebConsoleActor, "consoleActor");
|
||||
handle.addTabActor(WebConsoleActor, "consoleActor");
|
||||
};
|
||||
|
||||
exports.unregister = function(handle) {
|
||||
handle.removeGlobalActor(WebConsoleActor, "consoleActor");
|
||||
handle.removeTabActor(WebConsoleActor, "consoleActor");
|
||||
};
|
||||
|
@ -360,7 +360,7 @@ var DebuggerServer = {
|
||||
// In case of apps being loaded in parent process, DebuggerServer is already
|
||||
// initialized and browser actors are already loaded,
|
||||
// but childtab.js hasn't been loaded yet.
|
||||
if (!("WebConsoleActor" in this)) {
|
||||
if (!DebuggerServer.tabActorFactories.hasOwnProperty("consoleActor")) {
|
||||
this.addTabActors();
|
||||
}
|
||||
// But webbrowser.js and childtab.js aren't loaded from shell.js.
|
||||
@ -377,7 +377,7 @@ var DebuggerServer = {
|
||||
*/
|
||||
addTabActors: function() {
|
||||
this.addActors("resource://gre/modules/devtools/server/actors/script.js");
|
||||
this.addActors("resource://gre/modules/devtools/server/actors/webconsole.js");
|
||||
this.registerModule("devtools/server/actors/webconsole");
|
||||
this.registerModule("devtools/server/actors/inspector");
|
||||
this.registerModule("devtools/server/actors/call-watcher");
|
||||
this.registerModule("devtools/server/actors/canvas");
|
||||
|
Loading…
Reference in New Issue
Block a user