mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
6f58c47a0d
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
@ -138,7 +138,7 @@
|
||||
<project name="platform/system/core" path="system/core" revision="53d584d4a4b4316e4de9ee5f210d662f89b44e7e"/>
|
||||
<project name="u-boot" path="u-boot" revision="f1502910977ac88f43da7bf9277c3523ad4b0b2f"/>
|
||||
<project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="6974f8e771d4d8e910357a6739ab124768891e8f"/>
|
||||
<project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="c985699a5140b6dd5c7a43295e4d4397ce9b1267"/>
|
||||
<project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="39b3ad41158f71d41b549b31e30a8a63518f7362"/>
|
||||
<project name="vendor/sprd/partner" path="vendor/sprd/partner" revision="8649c7145972251af11b0639997edfecabfc7c2e"/>
|
||||
<project name="vendor/sprd/proprietories" path="vendor/sprd/proprietories" revision="d2466593022f7078aaaf69026adf3367c2adb7bb"/>
|
||||
</manifest>
|
||||
|
@ -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="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a1ddea3133e0807350326cee5dcf0d06fad00c08"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -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="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a1ddea3133e0807350326cee5dcf0d06fad00c08"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"git": {
|
||||
"git_revision": "c8ed1085a67490a1ecd7f275e5de9487e1b93b1d",
|
||||
"git_revision": "4352d56f8c79a51eb44e43658472236a38d6f1d8",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "45fe49a5560cdaa07920739af65722a63b2de4f9",
|
||||
"revision": "a414e3396742a2e623feda0ba9ed654f6cd525d5",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a1ddea3133e0807350326cee5dcf0d06fad00c08"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c8ed1085a67490a1ecd7f275e5de9487e1b93b1d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4352d56f8c79a51eb44e43658472236a38d6f1d8"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -343,5 +343,63 @@ XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame", "resource:///modules/Panel
|
||||
|
||||
this.activeSound.addEventListener("ended", () => this.activeSound = undefined, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a listener for browser sharing. It will inform the listener straight
|
||||
* away for the current windowId, and then on every tab change.
|
||||
*
|
||||
* Listener parameters:
|
||||
* - {Object} err If there is a error this will be defined, null otherwise.
|
||||
* - {Integer} windowId The new windowId for the browser.
|
||||
*
|
||||
* @param {Function} listener The listener to receive information on when the
|
||||
* windowId changes.
|
||||
*/
|
||||
addBrowserSharingListener: function(listener) {
|
||||
if (!this._tabChangeListeners) {
|
||||
this._tabChangeListeners = new Set();
|
||||
gBrowser.addEventListener("select", this);
|
||||
}
|
||||
|
||||
this._tabChangeListeners.add(listener);
|
||||
|
||||
// Get the first window Id for the listener.
|
||||
listener(null, gBrowser.selectedTab.linkedBrowser.outerWindowID);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a listener from browser sharing.
|
||||
*
|
||||
* @param {Function} listener The listener to remove from the list.
|
||||
*/
|
||||
removeBrowserSharingListener: function(listener) {
|
||||
if (!this._tabChangeListeners) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._tabChangeListeners.has(listener)) {
|
||||
this._tabChangeListeners.delete(listener);
|
||||
}
|
||||
|
||||
if (!this._tabChangeListeners.size) {
|
||||
gBrowser.removeEventListener("select", this);
|
||||
delete this._tabChangeListeners;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles events from gBrowser.
|
||||
*/
|
||||
handleEvent: function(event) {
|
||||
// We only should get "select" events.
|
||||
if (event.type != "select") {
|
||||
return;
|
||||
}
|
||||
|
||||
// We've changed the tab, so get the new window id.
|
||||
for (let listener of this._tabChangeListeners) {
|
||||
listener(null, gBrowser.selectedTab.linkedBrowser.outerWindowID);
|
||||
};
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
@ -461,11 +461,14 @@ function findChildShell(aDocument, aDocShell, aSoughtURI) {
|
||||
var gPopupBlockerObserver = {
|
||||
_reportButton: null,
|
||||
|
||||
onReportButtonClick: function (aEvent)
|
||||
onReportButtonEvent: function (aEvent)
|
||||
{
|
||||
if (aEvent.button != 0 || aEvent.target != this._reportButton)
|
||||
return;
|
||||
|
||||
if ((aEvent.type == "click" && aEvent.button != 0) ||
|
||||
(aEvent.target != this._reportButton) ||
|
||||
(aEvent.type == "keypress" && aEvent.charCode != Ci.nsIDOMKeyEvent.DOM_VK_SPACE &&
|
||||
aEvent.keyCode != Ci.nsIDOMKeyEvent.DOM_VK_RETURN)) {
|
||||
return; // We're only interested in left click and space and enter keypresses
|
||||
}
|
||||
document.getElementById("blockedPopupOptions")
|
||||
.openPopup(this._reportButton, "after_end", 0, 2, false, false, aEvent);
|
||||
},
|
||||
|
@ -822,11 +822,12 @@
|
||||
<label class="urlbar-display urlbar-display-switchtab" value="&urlbar.switchToTab.label;"/>
|
||||
</box>
|
||||
<hbox id="urlbar-icons">
|
||||
<image id="page-report-button"
|
||||
class="urlbar-icon"
|
||||
hidden="true"
|
||||
tooltiptext="&pageReportIcon.tooltip;"
|
||||
onclick="gPopupBlockerObserver.onReportButtonClick(event);"/>
|
||||
<toolbarbutton id="page-report-button"
|
||||
class="tabbable urlbar-icon"
|
||||
hidden="true"
|
||||
tooltiptext="&pageReportIcon.tooltip;"
|
||||
onclick="gPopupBlockerObserver.onReportButtonEvent(event);"
|
||||
onkeypress="gPopupBlockerObserver.onReportButtonEvent(event);"/>
|
||||
<toolbarbutton id="reader-mode-button"
|
||||
class="tabbable"
|
||||
hidden="true"
|
||||
|
@ -1204,14 +1204,10 @@
|
||||
while (list.firstChild)
|
||||
list.firstChild.remove();
|
||||
|
||||
let hiddenList;
|
||||
try {
|
||||
let pref =
|
||||
Services.prefs.getCharPref("browser.search.hiddenOneOffs");
|
||||
hiddenList = pref ? pref.split(",") : [];
|
||||
} catch(e) {
|
||||
hiddenList = [];
|
||||
}
|
||||
let Preferences =
|
||||
Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
|
||||
let pref = Preferences.get("browser.search.hiddenOneOffs");
|
||||
let hiddenList = pref ? pref.split(",") : [];
|
||||
|
||||
let currentEngineName = Services.search.currentEngine.name;
|
||||
let engines = Services.search.getVisibleEngines()
|
||||
|
@ -196,6 +196,7 @@ function injectLoopAPI(targetWindow) {
|
||||
let contactsAPI;
|
||||
let roomsAPI;
|
||||
let callsAPI;
|
||||
let savedWindowListeners = new Map();
|
||||
|
||||
let api = {
|
||||
/**
|
||||
@ -266,10 +267,21 @@ function injectLoopAPI(targetWindow) {
|
||||
}
|
||||
},
|
||||
|
||||
getActiveTabWindowId: {
|
||||
/**
|
||||
* Adds a listener to the most recent window for browser/tab sharing. The
|
||||
* listener will be notified straight away of the current tab id, then every
|
||||
* time there is a change of tab.
|
||||
*
|
||||
* Listener parameters:
|
||||
* - {Object} err If there is a error this will be defined, null otherwise.
|
||||
* - {Number} windowId The new windowId after a change of tab.
|
||||
*
|
||||
* @param {Function} listener The listener to handle the windowId changes.
|
||||
*/
|
||||
addBrowserSharingListener: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function(callback) {
|
||||
value: function(listener) {
|
||||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let browser = win && win.gBrowser.selectedTab.linkedBrowser;
|
||||
if (!win || !browser) {
|
||||
@ -277,16 +289,39 @@ function injectLoopAPI(targetWindow) {
|
||||
// window left.
|
||||
let err = new Error("No tabs available to share.");
|
||||
MozLoopService.log.error(err);
|
||||
callback(cloneValueInto(err, targetWindow));
|
||||
listener(cloneValueInto(err, targetWindow));
|
||||
return;
|
||||
}
|
||||
win.LoopUI.addBrowserSharingListener(listener);
|
||||
|
||||
savedWindowListeners.set(listener, Cu.getWeakReference(win));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a listener that was previously added.
|
||||
*
|
||||
* @param {Function} listener The listener to handle the windowId changes.
|
||||
*/
|
||||
removeBrowserSharingListener: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function(listener) {
|
||||
if (!savedWindowListeners.has(listener)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mm = browser.messageManager;
|
||||
mm.addMessageListener("webrtc:response:StartBrowserSharing", function listener(message) {
|
||||
mm.removeMessageListener("webrtc:response:StartBrowserSharing", listener);
|
||||
callback(null, message.data.windowID);
|
||||
});
|
||||
mm.sendAsyncMessage("webrtc:StartBrowserSharing");
|
||||
let win = savedWindowListeners.get(listener).get();
|
||||
|
||||
// Remove the element, regardless of if the window exists or not so
|
||||
// that we clean the map.
|
||||
savedWindowListeners.delete(listener);
|
||||
|
||||
if (!win) {
|
||||
return;
|
||||
}
|
||||
|
||||
win.LoopUI.removeBrowserSharingListener(listener);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -395,6 +395,38 @@ loop.store.ActiveRoomStore = (function() {
|
||||
this.setStoreState({receivingScreenShare: actionData.receiving});
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles switching browser (aka tab) sharing to a new window. Should
|
||||
* only be used for browser sharing.
|
||||
*
|
||||
* @param {Number} windowId The new windowId to start sharing.
|
||||
*/
|
||||
_handleSwitchBrowserShare: function(err, windowId) {
|
||||
if (err) {
|
||||
console.error("Error getting the windowId: " + err);
|
||||
return;
|
||||
}
|
||||
|
||||
var screenSharingState = this.getStoreState().screenSharingState;
|
||||
|
||||
if (screenSharingState === SCREEN_SHARE_STATES.INACTIVE) {
|
||||
// Screen sharing is still pending, so assume that we need to kick it off.
|
||||
var options = {
|
||||
videoSource: "browser",
|
||||
constraints: {
|
||||
browserWindow: windowId,
|
||||
scrollWithPage: true
|
||||
},
|
||||
};
|
||||
this._sdkDriver.startScreenShare(options);
|
||||
} else if (screenSharingState === SCREEN_SHARE_STATES.ACTIVE) {
|
||||
// Just update the current share.
|
||||
this._sdkDriver.switchAcquiredWindow(windowId);
|
||||
} else {
|
||||
console.error("Unexpectedly received windowId for browser sharing when pending");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initiates a screen sharing publisher.
|
||||
*
|
||||
@ -409,19 +441,12 @@ loop.store.ActiveRoomStore = (function() {
|
||||
videoSource: actionData.type
|
||||
};
|
||||
if (options.videoSource === "browser") {
|
||||
this._mozLoop.getActiveTabWindowId(function(err, windowId) {
|
||||
if (err || !windowId) {
|
||||
this.dispatchAction(new sharedActions.ScreenSharingState({
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
return;
|
||||
}
|
||||
options.constraints = {
|
||||
browserWindow: windowId,
|
||||
scrollWithPage: true
|
||||
};
|
||||
this._sdkDriver.startScreenShare(options);
|
||||
}.bind(this));
|
||||
this._browserSharingListener = this._handleSwitchBrowserShare.bind(this);
|
||||
|
||||
// Set up a listener for watching screen shares. This will get notified
|
||||
// with the first windowId when it is added, so we start off the sharing
|
||||
// from within the listener.
|
||||
this._mozLoop.addBrowserSharingListener(this._browserSharingListener);
|
||||
} else {
|
||||
this._sdkDriver.startScreenShare(options);
|
||||
}
|
||||
@ -431,6 +456,12 @@ loop.store.ActiveRoomStore = (function() {
|
||||
* Ends an active screenshare session.
|
||||
*/
|
||||
endScreenShare: function() {
|
||||
if (this._browserSharingListener) {
|
||||
// Remove the browser sharing listener as we don't need it now.
|
||||
this._mozLoop.removeBrowserSharingListener(this._browserSharingListener);
|
||||
this._browserSharingListener = null;
|
||||
}
|
||||
|
||||
if (this._sdkDriver.endScreenShare()) {
|
||||
this.dispatchAction(new sharedActions.ScreenSharingState({
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
|
@ -100,6 +100,12 @@ loop.OTSdkDriver = (function() {
|
||||
* @param {Object} options Hash containing options for the SDK
|
||||
*/
|
||||
startScreenShare: function(options) {
|
||||
// For browser sharing, we store the window Id so that we can avoid unnecessary
|
||||
// re-triggers.
|
||||
if (options.videoSource === "browser") {
|
||||
this._windowId = options.constraints.browserWindow;
|
||||
}
|
||||
|
||||
var config = _.extend(this._getCopyPublisherConfig(), options);
|
||||
|
||||
this.screenshare = this.sdk.initPublisher(this.getScreenShareElementFunc(),
|
||||
@ -108,6 +114,20 @@ loop.OTSdkDriver = (function() {
|
||||
this.screenshare.on("accessDenied", this._onScreenShareDenied.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Initiates switching the browser window that is being shared.
|
||||
*
|
||||
* @param {Integer} windowId The windowId of the browser.
|
||||
*/
|
||||
switchAcquiredWindow: function(windowId) {
|
||||
if (windowId === this._windowId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._windowId = windowId;
|
||||
this.screenshare._.switchAcquiredWindow(windowId);
|
||||
},
|
||||
|
||||
/**
|
||||
* Ends an active screenshare session. Return `true` when an active screen-
|
||||
* sharing session was ended or `false` when no session is active.
|
||||
@ -123,6 +143,7 @@ loop.OTSdkDriver = (function() {
|
||||
this.screenshare.off("accessAllowed accessDenied");
|
||||
this.screenshare.destroy();
|
||||
delete this.screenshare;
|
||||
delete this._windowId;
|
||||
return true;
|
||||
},
|
||||
|
||||
|
@ -19,8 +19,9 @@ skip-if = e10s
|
||||
[browser_mozLoop_prefs.js]
|
||||
[browser_mozLoop_doNotDisturb.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_toolbarbutton.js]
|
||||
[browser_mozLoop_pluralStrings.js]
|
||||
[browser_mozLoop_tabSharing.js]
|
||||
[browser_mozLoop_sharingListeners.js]
|
||||
skip-if = e10s
|
||||
[browser_mozLoop_telemetry.js]
|
||||
skip-if = e10s
|
||||
[browser_toolbarbutton.js]
|
||||
|
@ -0,0 +1,125 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* This file contains tests for the window.LoopUI active tab trackers.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const {injectLoopAPI} = Cu.import("resource:///modules/loop/MozLoopAPI.jsm");
|
||||
gMozLoopAPI = injectLoopAPI({});
|
||||
|
||||
let handlers = [
|
||||
{
|
||||
resolve: null,
|
||||
windowId: null,
|
||||
listener: function(err, windowId) {
|
||||
handlers[0].windowId = windowId;
|
||||
handlers[0].resolve();
|
||||
}
|
||||
},
|
||||
{
|
||||
resolve: null,
|
||||
windowId: null,
|
||||
listener: function(err, windowId) {
|
||||
handlers[1].windowId = windowId;
|
||||
handlers[1].resolve();
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function promiseWindowIdReceivedOnAdd(handler) {
|
||||
return new Promise(resolve => {
|
||||
handler.resolve = resolve;
|
||||
gMozLoopAPI.addBrowserSharingListener(handler.listener);
|
||||
});
|
||||
};
|
||||
|
||||
let createdTabs = [];
|
||||
|
||||
function promiseWindowIdReceivedNewTab(handlers) {
|
||||
let promiseHandlers = [];
|
||||
|
||||
handlers.forEach(handler => {
|
||||
promiseHandlers.push(new Promise(resolve => {
|
||||
handler.resolve = resolve;
|
||||
}));
|
||||
});
|
||||
|
||||
let createdTab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
createdTabs.push(createdTab);
|
||||
|
||||
promiseHandlers.push(promiseTabLoadEvent(createdTab, "about:mozilla"));
|
||||
|
||||
return Promise.all(promiseHandlers);
|
||||
};
|
||||
|
||||
function removeTabs() {
|
||||
for (let createdTab of createdTabs) {
|
||||
gBrowser.removeTab(createdTab);
|
||||
}
|
||||
|
||||
createdTabs = [];
|
||||
}
|
||||
|
||||
add_task(function* test_singleListener() {
|
||||
yield promiseWindowIdReceivedOnAdd(handlers[0]);
|
||||
|
||||
let initialWindowId = handlers[0].windowId;
|
||||
|
||||
Assert.notEqual(initialWindowId, null, "window id should be valid");
|
||||
|
||||
// Check that a new tab updates the window id.
|
||||
yield promiseWindowIdReceivedNewTab([handlers[0]]);
|
||||
|
||||
let newWindowId = handlers[0].windowId;
|
||||
|
||||
Assert.notEqual(initialWindowId, newWindowId, "Tab contentWindow IDs shouldn't be the same");
|
||||
|
||||
// Now remove the listener.
|
||||
gMozLoopAPI.removeBrowserSharingListener(handlers[0].listener);
|
||||
|
||||
removeTabs();
|
||||
});
|
||||
|
||||
add_task(function* test_multipleListener() {
|
||||
yield promiseWindowIdReceivedOnAdd(handlers[0]);
|
||||
|
||||
let initialWindowId0 = handlers[0].windowId;
|
||||
|
||||
Assert.notEqual(initialWindowId0, null, "window id should be valid");
|
||||
|
||||
yield promiseWindowIdReceivedOnAdd(handlers[1]);
|
||||
|
||||
let initialWindowId1 = handlers[1].windowId;
|
||||
|
||||
Assert.notEqual(initialWindowId1, null, "window id should be valid");
|
||||
Assert.equal(initialWindowId0, initialWindowId1, "window ids should be the same");
|
||||
|
||||
// Check that a new tab updates the window id.
|
||||
yield promiseWindowIdReceivedNewTab(handlers);
|
||||
|
||||
let newWindowId0 = handlers[0].windowId;
|
||||
let newWindowId1 = handlers[1].windowId;
|
||||
|
||||
Assert.equal(newWindowId0, newWindowId1, "Listeners should have the same windowId");
|
||||
Assert.notEqual(initialWindowId0, newWindowId0, "Tab contentWindow IDs shouldn't be the same");
|
||||
|
||||
// Now remove the first listener.
|
||||
gMozLoopAPI.removeBrowserSharingListener(handlers[0].listener);
|
||||
|
||||
// Check that a new tab updates the window id.
|
||||
yield promiseWindowIdReceivedNewTab([handlers[1]]);
|
||||
|
||||
let nextWindowId0 = handlers[0].windowId;
|
||||
let nextWindowId1 = handlers[1].windowId;
|
||||
|
||||
Assert.equal(newWindowId0, nextWindowId0, "First listener shouldn't have updated");
|
||||
Assert.notEqual(newWindowId1, nextWindowId1, "Second listener should have updated");
|
||||
|
||||
// Cleanup.
|
||||
gMozLoopAPI.removeBrowserSharingListener(handlers[1].listener);
|
||||
|
||||
removeTabs();
|
||||
});
|
||||
|
@ -1,41 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This is an integration test to make sure that passing window IDs is working as
|
||||
* expected, with or without e10s enabled - rather than just testing MozLoopAPI
|
||||
* alone.
|
||||
*/
|
||||
|
||||
const {injectLoopAPI} = Cu.import("resource:///modules/loop/MozLoopAPI.jsm");
|
||||
gMozLoopAPI = injectLoopAPI({});
|
||||
|
||||
let promiseTabWindowId = function() {
|
||||
return new Promise(resolve => {
|
||||
gMozLoopAPI.getActiveTabWindowId((err, windowId) => {
|
||||
Assert.equal(null, err, "No error should've occurred.");
|
||||
Assert.equal(typeof windowId, "number", "We should have a window ID");
|
||||
resolve(windowId);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
add_task(function* test_windowIdFetch_simple() {
|
||||
Assert.ok(gMozLoopAPI, "mozLoop should exist");
|
||||
|
||||
yield promiseTabWindowId();
|
||||
});
|
||||
|
||||
add_task(function* test_windowIdFetch_multipleTabs() {
|
||||
let previousTab = gBrowser.selectedTab;
|
||||
let previousTabId = yield promiseTabWindowId();
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
yield promiseTabLoadEvent(tab, "about:mozilla");
|
||||
let tabId = yield promiseTabWindowId();
|
||||
Assert.ok(tabId !== previousTabId, "Tab contentWindow IDs shouldn't be the same");
|
||||
gBrowser.removeTab(tab);
|
||||
|
||||
tabId = yield promiseTabWindowId();
|
||||
Assert.equal(previousTabId, tabId, "Window IDs should be back to what they were");
|
||||
});
|
@ -21,8 +21,10 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
sandbox.stub(dispatcher, "dispatch");
|
||||
|
||||
fakeMozLoop = {
|
||||
setLoopPref: sandbox.stub(),
|
||||
addConversationContext: sandbox.stub(),
|
||||
setLoopPref: sinon.stub(),
|
||||
addConversationContext: sinon.stub(),
|
||||
addBrowserSharingListener: sinon.stub(),
|
||||
removeBrowserSharingListener: sinon.stub(),
|
||||
rooms: {
|
||||
get: sinon.stub(),
|
||||
join: sinon.stub(),
|
||||
@ -36,11 +38,12 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
};
|
||||
|
||||
fakeSdkDriver = {
|
||||
connectSession: sandbox.stub(),
|
||||
disconnectSession: sandbox.stub(),
|
||||
forceDisconnectAll: sandbox.stub().callsArg(0),
|
||||
startScreenShare: sandbox.stub(),
|
||||
endScreenShare: sandbox.stub().returns(true)
|
||||
connectSession: sinon.stub(),
|
||||
disconnectSession: sinon.stub(),
|
||||
forceDisconnectAll: sinon.stub().callsArg(0),
|
||||
startScreenShare: sinon.stub(),
|
||||
switchAcquiredWindow: sinon.stub(),
|
||||
endScreenShare: sinon.stub().returns(true)
|
||||
};
|
||||
|
||||
fakeMultiplexGum = {
|
||||
@ -717,12 +720,20 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
});
|
||||
});
|
||||
|
||||
it("should invoke the SDK driver with the correct options for tab sharing", function() {
|
||||
it("should add a browser sharing listener for tab sharing", function() {
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
|
||||
sinon.assert.calledOnce(fakeMozLoop.getActiveTabWindowId);
|
||||
sinon.assert.calledOnce(fakeMozLoop.addBrowserSharingListener);
|
||||
});
|
||||
|
||||
it("should invoke the SDK driver with the correct options for tab sharing", function() {
|
||||
fakeMozLoop.addBrowserSharingListener.callsArgWith(0, null, 42);
|
||||
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
|
||||
sinon.assert.calledOnce(fakeSdkDriver.startScreenShare);
|
||||
sinon.assert.calledWith(fakeSdkDriver.startScreenShare, {
|
||||
@ -732,7 +743,31 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
scrollWithPage: true
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe("Screen share Events", function() {
|
||||
var listener;
|
||||
|
||||
beforeEach(function() {
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
|
||||
// Listener is the first argument of the first call.
|
||||
listener = fakeMozLoop.addBrowserSharingListener.args[0][0];
|
||||
|
||||
store.setStoreState({
|
||||
screenSharingState: SCREEN_SHARE_STATES.ACTIVE
|
||||
});
|
||||
});
|
||||
|
||||
it("should update the SDK driver when a new window id is received", function() {
|
||||
listener(null, 72);
|
||||
|
||||
sinon.assert.calledOnce(fakeSdkDriver.switchAcquiredWindow);
|
||||
sinon.assert.calledWithExactly(fakeSdkDriver.switchAcquiredWindow, 72);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#endScreenShare", function() {
|
||||
@ -745,6 +780,18 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
});
|
||||
|
||||
it("should remove the sharing listener", function() {
|
||||
// Setup the listener.
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
|
||||
// Now stop the screen share.
|
||||
store.endScreenShare();
|
||||
|
||||
sinon.assert.calledOnce(fakeMozLoop.removeBrowserSharingListener);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#remotePeerConnected", function() {
|
||||
|
@ -46,7 +46,10 @@ describe("loop.OTSdkDriver", function () {
|
||||
publisher = _.extend({
|
||||
destroy: sinon.stub(),
|
||||
publishAudio: sinon.stub(),
|
||||
publishVideo: sinon.stub()
|
||||
publishVideo: sinon.stub(),
|
||||
_: {
|
||||
switchAcquiredWindow: sinon.stub()
|
||||
}
|
||||
}, Backbone.Events);
|
||||
|
||||
sdk = {
|
||||
@ -143,8 +146,10 @@ describe("loop.OTSdkDriver", function () {
|
||||
// has multiple options.
|
||||
var options = {
|
||||
videoSource: "browser",
|
||||
browserWindow: 42,
|
||||
scrollWithPage: true
|
||||
constraints: {
|
||||
browserWindow: 42,
|
||||
scrollWithPage: true
|
||||
}
|
||||
};
|
||||
driver.startScreenShare(options);
|
||||
|
||||
@ -153,6 +158,37 @@ describe("loop.OTSdkDriver", function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#switchAcquiredWindow", function() {
|
||||
beforeEach(function() {
|
||||
var options = {
|
||||
videoSource: "browser",
|
||||
constraints: {
|
||||
browserWindow: 42,
|
||||
scrollWithPage: true
|
||||
}
|
||||
};
|
||||
driver.getScreenShareElementFunc = function() {
|
||||
return fakeScreenElement;
|
||||
};
|
||||
sandbox.stub(dispatcher, "dispatch");
|
||||
|
||||
driver.startScreenShare(options);
|
||||
});
|
||||
|
||||
it("should switch to the acquired window", function() {
|
||||
driver.switchAcquiredWindow(72);
|
||||
|
||||
sinon.assert.calledOnce(publisher._.switchAcquiredWindow);
|
||||
sinon.assert.calledWithExactly(publisher._.switchAcquiredWindow, 72);
|
||||
});
|
||||
|
||||
it("should not switch if the window is the same as the currently selected one", function() {
|
||||
driver.switchAcquiredWindow(42);
|
||||
|
||||
sinon.assert.notCalled(publisher._.switchAcquiredWindow);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#endScreenShare", function() {
|
||||
beforeEach(function() {
|
||||
driver.getScreenShareElementFunc = function() {};
|
||||
|
@ -433,12 +433,13 @@ BrowserGlue.prototype = {
|
||||
// an engine, and that newly added engines are visible.
|
||||
if (data == "engine-added" || data == "engine-removed") {
|
||||
let engineName = subject.QueryInterface(Ci.nsISearchEngine).name;
|
||||
let hiddenPref =
|
||||
Services.prefs.getCharPref("browser.search.hiddenOneOffs");
|
||||
let hiddenEngines = hiddenPref ? hiddenPref.split(",") : [];
|
||||
hiddenEngines = hiddenEngines.filter(x => x !== engineName);
|
||||
Services.prefs.setCharPref("browser.search.hiddenOneOffs",
|
||||
hiddenEngines.join(","));
|
||||
let Preferences =
|
||||
Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
|
||||
let pref = Preferences.get("browser.search.hiddenOneOffs");
|
||||
let hiddenList = pref ? pref.split(",") : [];
|
||||
hiddenList = hiddenList.filter(x => x !== engineName);
|
||||
Preferences.set("browser.search.hiddenOneOffs",
|
||||
hiddenList.join(","));
|
||||
}
|
||||
|
||||
if (data != "engine-default" && data != "engine-current") {
|
||||
|
@ -8,7 +8,7 @@
|
||||
<!-- One off providers -->
|
||||
<preference id="browser.search.hiddenOneOffs"
|
||||
name="browser.search.hiddenOneOffs"
|
||||
type="string"/>
|
||||
type="unichar"/>
|
||||
|
||||
</preferences>
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
<!-- One off providers -->
|
||||
<preference id="browser.search.hiddenOneOffs"
|
||||
name="browser.search.hiddenOneOffs"
|
||||
type="string"/>
|
||||
type="unichar"/>
|
||||
|
||||
</preferences>
|
||||
|
||||
|
@ -9,6 +9,7 @@ support-files =
|
||||
test.html
|
||||
testEngine.src
|
||||
testEngine.xml
|
||||
testEngine_diacritics.xml
|
||||
testEngine_dupe.xml
|
||||
testEngine_mozsearch.xml
|
||||
webapi.html
|
||||
@ -34,6 +35,7 @@ skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Err
|
||||
skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]
|
||||
[browser_healthreport.js]
|
||||
[browser_hiddenOneOffs_cleanup.js]
|
||||
[browser_hiddenOneOffs_diacritics.js]
|
||||
[browser_private_search_perwindowpb.js]
|
||||
skip-if = e10s # Bug ?????? - Test uses load event and checks event.target.
|
||||
[browser_yahoo.js]
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* 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/. */
|
||||
const cachedPref = Services.prefs.getCharPref("browser.search.hiddenOneOffs");
|
||||
const testPref = "Foo,FooDupe";
|
||||
|
||||
function promiseNewEngine(basename) {
|
||||
@ -67,10 +66,34 @@ add_task(function* test_add() {
|
||||
"Adding an engine does not remove engines from hidden list.");
|
||||
});
|
||||
|
||||
add_task(function* test_diacritics() {
|
||||
const diacritic_engine = "Foo \u2661";
|
||||
let Preferences =
|
||||
Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
|
||||
|
||||
Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
|
||||
yield promiseNewEngine("testEngine_diacritics.xml");
|
||||
|
||||
let hiddenOneOffs =
|
||||
Preferences.get("browser.search.hiddenOneOffs").split(",");
|
||||
is(hiddenOneOffs.some(x => x == diacritic_engine), false,
|
||||
"Observer cleans up added hidden engines that include a diacritic.");
|
||||
|
||||
Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
|
||||
|
||||
info("Removing testEngine_diacritics.xml");
|
||||
Services.search.removeEngine(Services.search.getEngineByName(diacritic_engine));
|
||||
|
||||
hiddenOneOffs =
|
||||
Preferences.get("browser.search.hiddenOneOffs").split(",");
|
||||
is(hiddenOneOffs.some(x => x == diacritic_engine), false,
|
||||
"Observer cleans up removed hidden engines that include a diacritic.");
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
info("Removing testEngine.xml");
|
||||
Services.search.removeEngine(Services.search.getEngineByName("Foo"));
|
||||
info("Removing testEngine_dupe.xml");
|
||||
Services.search.removeEngine(Services.search.getEngineByName("FooDupe"));
|
||||
Services.prefs.setCharPref("browser.search.hiddenOneOffs", cachedPref);
|
||||
Services.prefs.clearUserPref("browser.search.hiddenOneOffs");
|
||||
});
|
||||
|
@ -0,0 +1,74 @@
|
||||
/* 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/. */
|
||||
// Tests that keyboard navigation in the search panel works as designed.
|
||||
|
||||
const searchbar = document.getElementById("searchbar");
|
||||
const textbox = searchbar._textbox;
|
||||
const searchPopup = document.getElementById("PopupSearchAutoComplete");
|
||||
const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
|
||||
"searchbar-search-button");
|
||||
|
||||
const diacritic_engine = "Foo \u2661";
|
||||
|
||||
let Preferences =
|
||||
Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
|
||||
|
||||
// Get an array of the one-off buttons.
|
||||
function getOneOffs() {
|
||||
let oneOffs = [];
|
||||
let oneOff =
|
||||
document.getAnonymousElementByAttribute(searchPopup, "anonid",
|
||||
"search-panel-one-offs");
|
||||
for (oneOff = oneOff.firstChild; oneOff; oneOff = oneOff.nextSibling) {
|
||||
if (oneOff.classList.contains("dummy"))
|
||||
break;
|
||||
oneOffs.push(oneOff);
|
||||
}
|
||||
|
||||
return oneOffs;
|
||||
}
|
||||
|
||||
add_task(function* init() {
|
||||
let currentEngine = Services.search.currentEngine;
|
||||
yield promiseNewEngine("testEngine_diacritics.xml", {setAsCurrent: false});
|
||||
registerCleanupFunction(() => {
|
||||
Services.search.currentEngine = currentEngine;
|
||||
Services.prefs.clearUserPref("browser.search.hiddenOneOffs");
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* test_hidden() {
|
||||
Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
|
||||
|
||||
let promise = promiseEvent(searchPopup, "popupshown");
|
||||
info("Opening search panel");
|
||||
EventUtils.synthesizeMouseAtCenter(searchIcon, {});
|
||||
yield promise;
|
||||
|
||||
ok(!getOneOffs().some(x => x.getAttribute("tooltiptext") == diacritic_engine),
|
||||
"Search engines with diacritics are hidden when added to hiddenOneOffs preference.");
|
||||
|
||||
promise = promiseEvent(searchPopup, "popuphidden");
|
||||
info("Closing search panel");
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* test_shown() {
|
||||
Preferences.set("browser.search.hiddenOneOffs", "");
|
||||
|
||||
let promise = promiseEvent(searchPopup, "popupshown");
|
||||
info("Opening search panel");
|
||||
SimpleTest.executeSoon(() => {
|
||||
EventUtils.synthesizeMouseAtCenter(searchIcon, {});
|
||||
});
|
||||
yield promise;
|
||||
|
||||
ok(getOneOffs().some(x => x.getAttribute("tooltiptext") == diacritic_engine),
|
||||
"Search engines with diacritics are shown when removed from hiddenOneOffs preference.");
|
||||
|
||||
promise = promiseEvent(searchPopup, "popuphidden");
|
||||
searchPopup.hidePopup();
|
||||
yield promise;
|
||||
});
|
@ -136,8 +136,11 @@ function* promiseOnLoad() {
|
||||
});
|
||||
}
|
||||
|
||||
function promiseNewEngine(basename) {
|
||||
function promiseNewEngine(basename, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
//Default the setAsCurrent option to true.
|
||||
let setAsCurrent =
|
||||
options.setAsCurrent == undefined ? true : options.setAsCurrent;
|
||||
info("Waiting for engine to be added: " + basename);
|
||||
Services.search.init({
|
||||
onInitComplete: function() {
|
||||
@ -146,9 +149,13 @@ function promiseNewEngine(basename) {
|
||||
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
|
||||
onSuccess: function (engine) {
|
||||
info("Search engine added: " + basename);
|
||||
Services.search.currentEngine = engine;
|
||||
if (setAsCurrent) {
|
||||
Services.search.currentEngine = engine;
|
||||
}
|
||||
registerCleanupFunction(() => {
|
||||
Services.search.currentEngine = current;
|
||||
if (setAsCurrent) {
|
||||
Services.search.currentEngine = current;
|
||||
}
|
||||
Services.search.removeEngine(engine);
|
||||
info("Search engine removed: " + basename);
|
||||
});
|
||||
|
12
browser/components/search/test/testEngine_diacritics.xml
Normal file
12
browser/components/search/test/testEngine_diacritics.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
|
||||
xmlns:moz="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>Foo ♡</ShortName>
|
||||
<Description>Engine whose ShortName contains non-BMP Unicode characters</Description>
|
||||
<InputEncoding>utf-8</InputEncoding>
|
||||
<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
|
||||
<Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
|
||||
<Param name="test" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<moz:SearchForm>http://mochi.test:8888/browser/browser/components/search/test/</moz:SearchForm>
|
||||
<moz:Alias>diacriticalias</moz:Alias>
|
||||
</OpenSearchDescription>
|
@ -1,6 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
readerView.enter=Enter Reader View
|
||||
readerView.exit=Exit Reader View
|
@ -139,7 +139,6 @@
|
||||
locale/browser/preferences/tabs.dtd (%chrome/browser/preferences/tabs.dtd)
|
||||
locale/browser/preferences/search.dtd (%chrome/browser/preferences/search.dtd)
|
||||
locale/browser/preferences/translation.dtd (%chrome/browser/preferences/translation.dtd)
|
||||
locale/browser/readerMode.properties (%chrome/browser/readerMode.properties)
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
locale/browser/syncBrand.dtd (%chrome/browser/syncBrand.dtd)
|
||||
locale/browser/syncSetup.dtd (%chrome/browser/syncSetup.dtd)
|
||||
|
@ -15,7 +15,7 @@ Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode", "resource://gre/modules/ReaderMode.jsm");
|
||||
|
||||
const gStringBundle = Services.strings.createBundle("chrome://browser/locale/readerMode.properties");
|
||||
const gStringBundle = Services.strings.createBundle("chrome://global/locale/aboutReader.properties");
|
||||
|
||||
let ReaderParent = {
|
||||
|
||||
@ -107,7 +107,7 @@ let ReaderParent = {
|
||||
if (browser.currentURI.spec.startsWith("about:reader")) {
|
||||
button.setAttribute("readeractive", true);
|
||||
button.hidden = false;
|
||||
button.setAttribute("tooltiptext", gStringBundle.GetStringFromName("readerView.exit"));
|
||||
button.setAttribute("tooltiptext", gStringBundle.GetStringFromName("readerView.close"));
|
||||
} else {
|
||||
button.removeAttribute("readeractive");
|
||||
button.setAttribute("tooltiptext", gStringBundle.GetStringFromName("readerView.enter"));
|
||||
|
@ -1616,9 +1616,15 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
|
||||
/* Popup blocker button */
|
||||
#page-report-button {
|
||||
-moz-appearance: none;
|
||||
padding: 0;
|
||||
list-style-image: url("chrome://browser/skin/Info.png");
|
||||
}
|
||||
|
||||
#page-report-button:focus {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
/* Reader mode button */
|
||||
|
||||
#reader-mode-button {
|
||||
|
@ -2501,10 +2501,21 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-
|
||||
|
||||
/* POPUP BLOCKER BUTTON */
|
||||
#page-report-button {
|
||||
-moz-appearance: none;
|
||||
padding: 0;
|
||||
border-width: 0;
|
||||
list-style-image: url("chrome://browser/skin/urlbar-popup-blocked.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
#page-report-button > .toolbarbutton-icon {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
#page-report-button:focus {
|
||||
@hudButtonFocused@
|
||||
}
|
||||
|
||||
#page-report-button:hover:active,
|
||||
#page-report-button[open="true"] {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
@ -2514,7 +2525,6 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-
|
||||
#page-report-button {
|
||||
list-style-image: url("chrome://browser/skin/urlbar-popup-blocked@2x.png");
|
||||
-moz-image-region: rect(0, 32px, 32px, 0);
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
#page-report-button:hover:active,
|
||||
|
@ -1563,10 +1563,14 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||
/* popup blocker button */
|
||||
|
||||
#page-report-button {
|
||||
-moz-appearance: none;
|
||||
padding: 0;
|
||||
border-width: 0;
|
||||
list-style-image: url("chrome://browser/skin/urlbar-popup-blocked.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
#page-report-button:focus,
|
||||
#page-report-button:hover {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
}
|
||||
|
178
build/docs/files-metadata.rst
Normal file
178
build/docs/files-metadata.rst
Normal file
@ -0,0 +1,178 @@
|
||||
.. _mozbuild_files_metadata:
|
||||
|
||||
==============
|
||||
Files Metadata
|
||||
==============
|
||||
|
||||
:ref:`mozbuild-files` provide a mechanism for attaching metadata to
|
||||
files. Essentially, you define some flags to set on a file or file
|
||||
pattern. Later, some tool or process queries for metadata attached to a
|
||||
file of interest and it does something intelligent with that data.
|
||||
|
||||
Defining Metadata
|
||||
=================
|
||||
|
||||
Files metadata is defined by using the
|
||||
:ref:`Files Sub-Context <mozbuild_subcontext_Files>` in ``moz.build``
|
||||
files. e.g.::
|
||||
|
||||
with Files('**/Makefile.in'):
|
||||
BUG_COMPONENT = ('Core', 'Build Config')
|
||||
|
||||
This working example says, *for all Makefile.in files in all directories
|
||||
in this one and underneath it, set the Bugzilla component to
|
||||
Core :: Build Config*.
|
||||
|
||||
For more info, read the
|
||||
:ref:`docs on Files <mozbuild_subcontext_Files>`.
|
||||
|
||||
How Metadata is Read
|
||||
====================
|
||||
|
||||
``Files`` metadata is extracted in :ref:`mozbuild_fs_reading_mode`.
|
||||
|
||||
Reading starts by specifying a set of files whose metadata you are
|
||||
interested in. For each file, the filesystem is walked to the root
|
||||
of the source directory. Any ``moz.build`` encountered during this
|
||||
walking are marked as relevant to the file.
|
||||
|
||||
Let's say you have the following filesystem content::
|
||||
|
||||
/moz.build
|
||||
/root_file
|
||||
/dir1/moz.build
|
||||
/dir1/foo
|
||||
/dir1/subdir1/foo
|
||||
/dir2/foo
|
||||
|
||||
For ``/root_file``, the relevant ``moz.build`` files are just
|
||||
``/moz.build``.
|
||||
|
||||
For ``/dir1/foo`` and ``/dir1/subdir1/foo``, the relevant files are
|
||||
``/moz.build`` and ``/dir1/moz.build``.
|
||||
|
||||
For ``/dir2``, the relevant file is just ``/moz.build``.
|
||||
|
||||
Once the list of relevant ``moz.build`` files is obtained, each
|
||||
``moz.build`` file is evaluated. Root ``moz.build`` file first,
|
||||
leaf-most files last. This follows the rules of
|
||||
:ref:`mozbuild_fs_reading_mode`, with the set of evaluated ``moz.build``
|
||||
files being controlled by filesystem content, not ``DIRS`` variables.
|
||||
|
||||
The file whose metadata is being resolved maps to a set of ``moz.build``
|
||||
files which in turn evaluates to a list of contexts. For file metadata,
|
||||
we only care about one of these contexts:
|
||||
:ref:`Files <mozbuild_subcontext_Files>`.
|
||||
|
||||
We start with an empty ``Files`` instance to represent the file. As
|
||||
we encounter a *files sub-context*, we see if it is appropriate to
|
||||
this file. If it is, we apply its values. This process is repeated
|
||||
until all *files sub-contexts* have been applied or skipped. The final
|
||||
state of the ``Files`` instance is used to represent the metadata for
|
||||
this particular file.
|
||||
|
||||
It may help to visualize this. Say we have 2 ``moz.build`` files::
|
||||
|
||||
# /moz.build
|
||||
with Files('*.cpp'):
|
||||
BUG_COMPONENT = ('Core', 'XPCOM')
|
||||
|
||||
with Files('**/*.js'):
|
||||
BUG_COMPONENT = ('Firefox', 'General')
|
||||
|
||||
# /foo/moz.build
|
||||
with Files('*.js'):
|
||||
BUG_COMPONENT = ('Another', 'Component')
|
||||
|
||||
Querying for metadata for the file ``/foo/test.js`` will reveal 3
|
||||
relevant ``Files`` sub-contexts. They are evaluated as follows:
|
||||
|
||||
1. ``/moz.build - Files('*.cpp')``. Does ``/*.cpp`` match
|
||||
``/foo/test.js``? **No**. Ignore this context.
|
||||
2. ``/moz.build - Files('**/*.js')``. Does ``/**/*.js`` match
|
||||
``/foo/test.js``? **Yes**. Apply ``BUG_COMPONENT = ('Firefox', 'General')``
|
||||
to us.
|
||||
3. ``/foo/moz.build - Files('*.js')``. Does ``/foo/*.js`` match
|
||||
``/foo/test.js``? **Yes**. Apply
|
||||
``BUG_COMPONENT = ('Another', 'Component')``.
|
||||
|
||||
At the end of execution, we have
|
||||
``BUG_COMPONENT = ('Another', 'Component')`` as the metadata for
|
||||
``/foo/test.js``.
|
||||
|
||||
One way to look at file metadata is as a stack of data structures.
|
||||
Each ``Files`` sub-context relevant to a given file is applied on top
|
||||
of the previous state, starting from an empty state. The final state
|
||||
wins.
|
||||
|
||||
.. _mozbuild_files_metadata_finalizing:
|
||||
|
||||
Finalizing Values
|
||||
=================
|
||||
|
||||
The default behavior of ``Files`` sub-context evaluation is to apply new
|
||||
values on top of old. In most circumstances, this results in desired
|
||||
behavior. However, there are circumstances where this may not be
|
||||
desired. There is thus a mechanism to *finalize* or *freeze* values.
|
||||
|
||||
Finalizing values is useful for scenarios where you want to prevent
|
||||
wildcard matches from overwriting previously-set values. This is useful
|
||||
for one-off files.
|
||||
|
||||
Let's take ``Makefile.in`` files as an example. The build system module
|
||||
policy dictates that ``Makefile.in`` files are part of the ``Build
|
||||
Config`` module and should be reviewed by peers of that module. However,
|
||||
there exist ``Makefile.in`` files in many directories in the source
|
||||
tree. Without finalization, a ``*`` or ``**`` wildcard matching rule
|
||||
would match ``Makefile.in`` files and overwrite their metadata.
|
||||
|
||||
Finalizing of values is performed by setting the ``FINAL`` variable
|
||||
on ``Files`` sub-contexts. See the
|
||||
:ref:`Files documentation <mozbuild_subcontext_Files>` for more.
|
||||
|
||||
Here is an example with ``Makefile.in`` files, showing how it is
|
||||
possible to finalize the ``BUG_COMPONENT`` value.::
|
||||
|
||||
# /moz.build
|
||||
with Files('**/Makefile.in'):
|
||||
BUG_COMPONENT = ('Core', 'Build Config')
|
||||
FINAL = True
|
||||
|
||||
# /foo/moz.build
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Another', 'Component')
|
||||
|
||||
If we query for metadata of ``/foo/Makefile.in``, both ``Files``
|
||||
sub-contexts match the file pattern. However, since ``BUG_COMPONENT`` is
|
||||
marked as finalized by ``/moz.build``, the assignment from
|
||||
``/foo/moz.build`` is ignored. The final value for ``BUG_COMPONENT``
|
||||
is ``('Core', 'Build Config')``.
|
||||
|
||||
Here is another example::
|
||||
|
||||
with Files('*.cpp'):
|
||||
BUG_COMPONENT = ('One-Off', 'For C++')
|
||||
FINAL = True
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Regular', 'Component')
|
||||
|
||||
For every files except ``foo.cpp``, the bug component will be resolved
|
||||
as ``Regular :: Component``. However, ``foo.cpp`` has its value of
|
||||
``One-Off :: For C++`` preserved because it is finalized.
|
||||
|
||||
.. important::
|
||||
|
||||
``FINAL`` only applied to variables defined in a context.
|
||||
|
||||
If you want to mark one variable as finalized but want to leave
|
||||
another mutable, you'll need to use 2 ``Files`` contexts.
|
||||
|
||||
Guidelines for Defining Metadata
|
||||
================================
|
||||
|
||||
In general, values defined towards the root of the source tree are
|
||||
generic and become more specific towards the leaves. For example,
|
||||
the ``BUG_COMPONENT`` for ``/browser`` might be ``Firefox :: General``
|
||||
whereas ``/browser/components/preferences`` would list
|
||||
``Firefox :: Preferences``.
|
@ -13,6 +13,7 @@ Important Concepts
|
||||
Mozconfig Files <mozconfigs>
|
||||
mozbuild-files
|
||||
mozbuild-symbols
|
||||
files-metadata
|
||||
Profile Guided Optimization <pgo>
|
||||
slow
|
||||
environment-variables
|
||||
|
@ -30,6 +30,8 @@ The following properties make execution of ``moz.build`` files special:
|
||||
1. The execution environment exposes a limited subset of Python.
|
||||
2. There is a special set of global symbols and an enforced naming
|
||||
convention of symbols.
|
||||
3. Some symbols are inherited from previously-executed ``moz.build``
|
||||
files.
|
||||
|
||||
The limited subset of Python is actually an extremely limited subset.
|
||||
Only a few symbols from ``__builtins__`` are exposed. These include
|
||||
@ -68,16 +70,77 @@ sneak into the sandbox without being explicitly defined and documented.
|
||||
Reading and Traversing moz.build Files
|
||||
======================================
|
||||
|
||||
The process responsible for reading ``moz.build`` files simply starts at
|
||||
a root ``moz.build`` file, processes it, emits the globals namespace to
|
||||
a consumer, and then proceeds to process additional referenced
|
||||
``moz.build`` files from the original file. The consumer then examines
|
||||
the globals/``UPPERCASE`` variables set as part of execution and then
|
||||
converts the data therein to Python class instances.
|
||||
The process for reading ``moz.build`` files roughly consists of:
|
||||
|
||||
The executed Python sandbox is essentially represented as a dictionary
|
||||
of all the special ``UPPERCASE`` variables populated during its
|
||||
execution.
|
||||
1. Start at the root ``moz.build`` (``<topsrcdir>/moz.build``).
|
||||
2. Evaluate the ``moz.build`` file in a new sandbox.
|
||||
3. Emit the main *context* and any *sub-contexts* from the executed
|
||||
sandbox.
|
||||
4. Extract a set of ``moz.build`` files to execute next.
|
||||
5. For each additional ``moz.build`` file, goto #2 and repeat until all
|
||||
referenced files have executed.
|
||||
|
||||
From the perspective of the consumer, the output of reading is a stream
|
||||
of :py:class:`mozbuild.frontend.reader.context.Context` instances. Each
|
||||
``Context`` defines a particular aspect of data. Consumers iterate over
|
||||
these objects and do something with the data inside. Each object is
|
||||
essentially a dictionary of all the ``UPPERCASE`` variables populated
|
||||
during its execution.
|
||||
|
||||
.. note::
|
||||
|
||||
Historically, there was only one ``context`` per ``moz.build`` file.
|
||||
As the number of things tracked by ``moz.build`` files grew and more
|
||||
and more complex processing was desired, it was necessary to split these
|
||||
contexts into multiple logical parts. It is now common to emit
|
||||
multiple contexts per ``moz.build`` file.
|
||||
|
||||
Build System Reading Mode
|
||||
-------------------------
|
||||
|
||||
The traditional mode of evaluation of ``moz.build`` files is what's
|
||||
called *build system traversal mode.* In this mode, the ``CONFIG``
|
||||
variable in each ``moz.build`` sandbox is populated from data coming
|
||||
from ``config.status``, which is produced by ``configure``.
|
||||
|
||||
During evaluation, ``moz.build`` files often make decisions conditional
|
||||
on the state of the build configuration. e.g. *only compile foo.cpp if
|
||||
feature X is enabled*.
|
||||
|
||||
In this mode, traversal of ``moz.build`` files is governed by variables
|
||||
like ``DIRS`` and ``TEST_DIRS``. For example, to execute a child
|
||||
directory, ``foo``, you would add ``DIRS += ['foo']`` to a ``moz.build``
|
||||
file and ``foo/moz.build`` would be evaluated.
|
||||
|
||||
.. _mozbuild_fs_reading_mode:
|
||||
|
||||
Filesystem Reading Mode
|
||||
-----------------------
|
||||
|
||||
There is an alternative reading mode that doesn't involve the build
|
||||
system and doesn't use ``DIRS`` variables to control traversal into
|
||||
child directories. This mode is called *filesystem reading mode*.
|
||||
|
||||
In this reading mode, the ``CONFIG`` variable is a dummy, mostly empty
|
||||
object. Accessing all but a few special variables will return an empty
|
||||
value. This means that nearly all ``if CONFIG['FOO']:`` branches will
|
||||
not be taken.
|
||||
|
||||
Instead of using content from within the evaluated ``moz.build``
|
||||
file to drive traversal into subsequent ``moz.build`` files, the set
|
||||
of files to evaluate is controlled by the thing doing the reading.
|
||||
|
||||
A single ``moz.build`` file is not guaranteed to be executable in
|
||||
isolation. Instead, we must evaluate all *parent* ``moz.build`` files
|
||||
first. For example, in order to evaluate ``/foo/moz.build``, one must
|
||||
execute ``/moz.build`` and have its state influence the execution of
|
||||
``/foo/moz.build``.
|
||||
|
||||
Filesystem reading mode is utilized to power the
|
||||
:ref:`mozbuild_files_metadata` feature.
|
||||
|
||||
Technical Details
|
||||
-----------------
|
||||
|
||||
The code for reading ``moz.build`` files lives in
|
||||
:py:mod:`mozbuild.frontend.reader`. The Python sandboxes evaluation results
|
||||
@ -100,9 +163,6 @@ verification step. There are multiple downstream consumers of the
|
||||
``moz.build``-derived data and many will perform the same actions. This
|
||||
logic can be complicated, so we have a component dedicated to it.
|
||||
|
||||
Other Notes
|
||||
===========
|
||||
|
||||
:py:class:`mozbuild.frontend.reader.BuildReader`` and
|
||||
:py:class:`mozbuild.frontend.reader.TreeMetadataEmitter`` have a
|
||||
stream-based API courtesy of generators. When you hook them up properly,
|
||||
|
@ -95,7 +95,7 @@ flavors = {
|
||||
'NetBSD': 'netbsd',
|
||||
'OpenBSD': 'openbsd',
|
||||
}
|
||||
gyp_vars['OS'] = flavors[os]
|
||||
gyp_vars['OS'] = flavors.get(os)
|
||||
|
||||
arches = {
|
||||
'x86_64': 'x64',
|
||||
|
@ -4,6 +4,9 @@
|
||||
# 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/.
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Core', 'Build Config')
|
||||
|
||||
# This cannot be named "build" because of bug 922191.
|
||||
SPHINX_TREES['buildsystem'] = 'docs'
|
||||
|
||||
|
@ -4,6 +4,9 @@
|
||||
# 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/.
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Core', 'Build Config')
|
||||
|
||||
NO_DIST_INSTALL = True
|
||||
# For sanity's sake, we compile nsinstall without the wrapped system
|
||||
# headers, so that we can use it to set up the wrapped system headers.
|
||||
@ -30,6 +33,7 @@ if CONFIG['MOZ_SHARED_ICU']:
|
||||
DEFINES['MOZ_SHARED_ICU'] = True
|
||||
|
||||
PYTHON_UNIT_TESTS += [
|
||||
'tests/test_mozbuild_reading.py',
|
||||
'tests/unit-expandlibs.py',
|
||||
'tests/unit-mozunit.py',
|
||||
'tests/unit-nsinstall.py',
|
||||
|
70
config/tests/test_mozbuild_reading.py
Normal file
70
config/tests/test_mozbuild_reading.py
Normal file
@ -0,0 +1,70 @@
|
||||
# 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/.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mozunit import main
|
||||
|
||||
from mozbuild.base import MozbuildObject
|
||||
from mozbuild.frontend.reader import (
|
||||
BuildReader,
|
||||
EmptyConfig,
|
||||
)
|
||||
|
||||
|
||||
class TestMozbuildReading(unittest.TestCase):
|
||||
# This hack is needed to appease running in automation.
|
||||
def setUp(self):
|
||||
self._old_env = dict(os.environ)
|
||||
os.environ.pop('MOZCONFIG', None)
|
||||
os.environ.pop('MOZ_OBJDIR', None)
|
||||
|
||||
def tearDown(self):
|
||||
os.environ.clear()
|
||||
os.environ.update(self._old_env)
|
||||
|
||||
def _mozbuilds(self, reader):
|
||||
if not hasattr(self, '_mozbuild_paths'):
|
||||
self._mozbuild_paths = set(reader.all_mozbuild_paths())
|
||||
|
||||
return self._mozbuild_paths
|
||||
|
||||
@unittest.skip('failing in SpiderMonkey builds')
|
||||
def test_filesystem_traversal_reading(self):
|
||||
"""Reading moz.build according to filesystem traversal works.
|
||||
|
||||
We attempt to read every known moz.build file via filesystem traversal.
|
||||
|
||||
If this test fails, it means that metadata extraction will fail.
|
||||
"""
|
||||
mb = MozbuildObject.from_environment(detect_virtualenv_mozinfo=False)
|
||||
config = mb.config_environment
|
||||
reader = BuildReader(config)
|
||||
all_paths = self._mozbuilds(reader)
|
||||
paths, contexts = reader.read_relevant_mozbuilds(all_paths)
|
||||
self.assertEqual(set(paths), all_paths)
|
||||
self.assertGreaterEqual(len(contexts), len(paths))
|
||||
|
||||
def test_filesystem_traversal_no_config(self):
|
||||
"""Reading moz.build files via filesystem traversal mode with no build config.
|
||||
|
||||
This is similar to the above test except no build config is applied.
|
||||
This will likely fail in more scenarios than the above test because a
|
||||
lot of moz.build files assumes certain variables are present.
|
||||
"""
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
root = os.path.normpath(os.path.join(here, '..', '..'))
|
||||
config = EmptyConfig(root)
|
||||
reader = BuildReader(config)
|
||||
all_paths = self._mozbuilds(reader)
|
||||
paths, contexts = reader.read_relevant_mozbuilds(all_paths)
|
||||
self.assertEqual(set(paths.keys()), all_paths)
|
||||
self.assertGreaterEqual(len(contexts), len(paths))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -23,7 +23,7 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"500": '["FK","00",,,,,"\\d{5}","[2-7]\\d{4}",]',
|
||||
"261": '["MG","00","0",,,"$NP$FG","\\d{7,9}","[23]\\d{8}",[["([23]\\d)(\\d{2})(\\d{3})(\\d{2})","$1 $2 $3 $4",,,]]]',
|
||||
"92": '["PK","00","0",,,"($NP$FG)","\\d{6,12}","1\\d{8}|[2-8]\\d{5,11}|9(?:[013-9]\\d{4,9}|2\\d(?:111\\d{6}|\\d{3,7}))",[["(\\d{2})(111)(\\d{3})(\\d{3})","$1 $2 $3 $4","(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)1",,],["(\\d{3})(111)(\\d{3})(\\d{3})","$1 $2 $3 $4","2[349]|45|54|60|72|8[2-5]|9[2-9]",,],["(\\d{2})(\\d{7,8})","$1 $2","(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)[2-9]",,],["(\\d{3})(\\d{6,7})","$1 $2","2[349]|45|54|60|72|8[2-5]|9[2-9]",,],["(3\\d{2})(\\d{7})","$1 $2","3","$NP$FG",],["([15]\\d{3})(\\d{5,6})","$1 $2","58[12]|1",,],["(586\\d{2})(\\d{5})","$1 $2","586",,],["([89]00)(\\d{3})(\\d{2})","$1 $2 $3","[89]00","$NP$FG",]]]',
|
||||
"234": '["NG","009","0",,,"$NP$FG","\\d{5,14}","[1-6]\\d{5,8}|9\\d{5,9}|[78]\\d{5,13}",[["([129])(\\d{3})(\\d{3,4})","$1 $2 $3","[129]",,],["(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3","[3-6]|7(?:[1-79]|0[1-9])|8[2-9]",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","70|8[01]|90[239]",,],["([78]00)(\\d{4})(\\d{4,5})","$1 $2 $3","[78]00",,],["([78]00)(\\d{5})(\\d{5,6})","$1 $2 $3","[78]00",,],["(78)(\\d{2})(\\d{3})","$1 $2 $3","78",,]]]',
|
||||
"234": '["NG","009","0",,,"$NP$FG","\\d{5,14}","[1-6]\\d{5,8}|9\\d{5,9}|[78]\\d{5,13}",[["([129])(\\d{3})(\\d{3,4})","$1 $2 $3","[129]",,],["(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3","[3-6]|7(?:[1-79]|0[1-9])|8[2-9]",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","70|8[01]|90[2359]",,],["([78]00)(\\d{4})(\\d{4,5})","$1 $2 $3","[78]00",,],["([78]00)(\\d{5})(\\d{5,6})","$1 $2 $3","[78]00",,],["(78)(\\d{2})(\\d{3})","$1 $2 $3","78",,]]]',
|
||||
"350": '["GI","00",,,,,"\\d{8}","[2568]\\d{7}",[["(\\d{3})(\\d{5})","$1 $2","2",,]]]',
|
||||
"45": '["DK","00",,,,,"\\d{8}","[2-9]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
|
||||
"963": '["SY","00","0",,,"$NP$FG","\\d{6,9}","[1-59]\\d{7,8}",[["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","[1-5]",,],["(9\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","9",,]]]',
|
||||
@ -31,7 +31,7 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"974": '["QA","00",,,,,"\\d{7,8}","[2-8]\\d{6,7}",[["([28]\\d{2})(\\d{4})","$1 $2","[28]",,],["([3-7]\\d{3})(\\d{4})","$1 $2","[3-7]",,]]]',
|
||||
"218": '["LY","00","0",,,"$NP$FG","\\d{7,9}","[25679]\\d{8}",[["([25679]\\d)(\\d{7})","$1-$2",,,]]]',
|
||||
"51": '["PE","19(?:1[124]|77|90)00","0",,,"($NP$FG)","\\d{6,9}","[14-9]\\d{7,8}",[["(1)(\\d{7})","$1 $2","1",,],["([4-8]\\d)(\\d{6})","$1 $2","[4-7]|8[2-4]",,],["(\\d{3})(\\d{5})","$1 $2","80",,],["(9\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","9","$FG",]]]',
|
||||
"62": '["ID","0(?:0[1789]|10(?:00|1[67]))","0",,,"$NP$FG","\\d{5,11}","[1-9]\\d{6,10}",[["(\\d{2})(\\d{5,8})","$1 $2","2[124]|[36]1","($NP$FG)",],["(\\d{3})(\\d{5,7})","$1 $2","[4579]|2[035-9]|[36][02-9]","($NP$FG)",],["(8\\d{2})(\\d{3,4})(\\d{3,4})","$1-$2-$3","8[1-35-9]",,],["(177)(\\d{6,8})","$1 $2","1",,],["(800)(\\d{5,7})","$1 $2","800",,],["(80\\d)(\\d)(\\d{3})(\\d{3})","$1 $2 $3 $4","80[79]",,]]]',
|
||||
"62": '["ID","0(?:0[1789]|10(?:00|1[67]))","0",,,"$NP$FG","\\d{5,11}","[1-9]\\d{6,10}",[["(\\d{2})(\\d{5,8})","$1 $2","2[124]|[36]1","($NP$FG)",],["(\\d{3})(\\d{5,8})","$1 $2","[4579]|2[035-9]|[36][02-9]","($NP$FG)",],["(8\\d{2})(\\d{3,4})(\\d{3,4})","$1-$2-$3","8[1-35-9]",,],["(177)(\\d{6,8})","$1 $2","1",,],["(800)(\\d{5,7})","$1 $2","800",,],["(80\\d)(\\d)(\\d{3})(\\d{3})","$1 $2 $3 $4","80[79]",,]]]',
|
||||
"298": '["FO","00",,"(10(?:01|[12]0|88))",,,"\\d{6}","[2-9]\\d{5}",[["(\\d{6})","$1",,,]]]',
|
||||
"381": '["RS","00","0",,,"$NP$FG","\\d{5,12}","[126-9]\\d{4,11}|3(?:[0-79]\\d{3,10}|8[2-9]\\d{2,9})",[["([23]\\d{2})(\\d{4,9})","$1 $2","(?:2[389]|39)0",,],["([1-3]\\d)(\\d{5,10})","$1 $2","1|2(?:[0-24-7]|[389][1-9])|3(?:[0-8]|9[1-9])",,],["(6\\d)(\\d{6,8})","$1 $2","6",,],["([89]\\d{2})(\\d{3,9})","$1 $2","[89]",,],["(7[26])(\\d{4,9})","$1 $2","7[26]",,],["(7[08]\\d)(\\d{4,9})","$1 $2","7[08]",,]]]',
|
||||
"975": '["BT","00",,,,,"\\d{6,8}","[1-8]\\d{6,7}",[["([17]7)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","1|77",,],["([2-8])(\\d{3})(\\d{3})","$1 $2 $3","[2-68]|7[246]",,]]]',
|
||||
@ -52,7 +52,7 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"692": '["MH","011","1",,,,"\\d{7}","[2-6]\\d{6}",[["(\\d{3})(\\d{4})","$1-$2",,,]]]',
|
||||
"250": '["RW","00","0",,,,"\\d{8,9}","[027-9]\\d{7,8}",[["(2\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","2","$FG",],["([7-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[7-9]","$NP$FG",],["(0\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","0",,]]]',
|
||||
"81": '["JP","010","0",,,"$NP$FG","\\d{8,17}","[1-9]\\d{8,9}|00(?:[36]\\d{7,14}|7\\d{5,7}|8\\d{7})",[["(\\d{3})(\\d{3})(\\d{3})","$1-$2-$3","(?:12|57|99)0",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","800",,],["(\\d{4})(\\d{4})","$1-$2","0077","$FG","NA"],["(\\d{4})(\\d{2})(\\d{3,4})","$1-$2-$3","0077","$FG","NA"],["(\\d{4})(\\d{2})(\\d{4})","$1-$2-$3","0088","$FG","NA"],["(\\d{4})(\\d{3})(\\d{3,4})","$1-$2-$3","00(?:37|66)","$FG","NA"],["(\\d{4})(\\d{4})(\\d{4,5})","$1-$2-$3","00(?:37|66)","$FG","NA"],["(\\d{4})(\\d{5})(\\d{5,6})","$1-$2-$3","00(?:37|66)","$FG","NA"],["(\\d{4})(\\d{6})(\\d{6,7})","$1-$2-$3","00(?:37|66)","$FG","NA"],["(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3","[2579]0|80[1-9]",,],["(\\d{4})(\\d)(\\d{4})","$1-$2-$3","1(?:26|3[79]|4[56]|5[4-68]|6[3-5])|5(?:76|97)|499|746|8(?:3[89]|63|47|51)|9(?:49|80|9[16])",,],["(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3","1(?:2[3-6]|3[3-9]|4[2-6]|5[2-8]|[68][2-7]|7[2-689]|9[1-578])|2(?:2[03-689]|3[3-58]|4[0-468]|5[04-8]|6[013-8]|7[06-9]|8[02-57-9]|9[13])|4(?:2[28]|3[689]|6[035-7]|7[05689]|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9[4-9])|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9[014-9])|8(?:2[49]|3[3-8]|4[5-8]|5[2-9]|6[35-9]|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9[3-7])",,],["(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","1|2(?:2[37]|5[5-9]|64|78|8[39]|91)|4(?:2[2689]|64|7[347])|5(?:[2-589]|39)|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93)",,],["(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3","2(?:9[14-79]|74|[34]7|[56]9)|82|993",,],["(\\d)(\\d{4})(\\d{4})","$1-$2-$3","3|4(?:2[09]|7[01])|6[1-9]",,],["(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","[2479][1-9]",,]]]',
|
||||
"237": '["CM","00",,,,,"\\d{8}","[2357-9]\\d{7}",[["([2357-9]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[23579]|88",,],["(800)(\\d{2})(\\d{3})","$1 $2 $3","80",,]]]',
|
||||
"237": '["CM","00",,,,,"\\d{8,9}","[235-9]\\d{7,8}",[["([26])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5","[26]",,],["([2357-9]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[23579]|88",,],["(800)(\\d{2})(\\d{3})","$1 $2 $3","80",,]]]',
|
||||
"351": '["PT","00",,,,,"\\d{9}","[2-46-9]\\d{8}",[["(2\\d)(\\d{3})(\\d{4})","$1 $2 $3","2[12]",,],["([2-46-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","2[3-9]|[346-9]",,]]]',
|
||||
"246": '["IO","00",,,,,"\\d{7}","3\\d{6}",[["(\\d{3})(\\d{4})","$1 $2",,,]]]',
|
||||
"227": '["NE","00",,,,,"\\d{8}","[0289]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[289]|09",,],["(08)(\\d{3})(\\d{3})","$1 $2 $3","08",,]]]',
|
||||
@ -73,8 +73,8 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"357": '["CY","00",,,,,"\\d{8}","[257-9]\\d{7}",[["(\\d{2})(\\d{6})","$1 $2",,,]]]',
|
||||
"240": '["GQ","00",,,,,"\\d{9}","[23589]\\d{8}",[["(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","[235]",,],["(\\d{3})(\\d{6})","$1 $2","[89]",,]]]',
|
||||
"506": '["CR","00",,"(19(?:0[012468]|1[09]|20|66|77|99))",,,"\\d{8,10}","[24-9]\\d{7,9}",[["(\\d{4})(\\d{4})","$1 $2","[24-7]|8[3-9]",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","[89]0",,]]]',
|
||||
"86": '["CN","(1[1279]\\d{3})?00","0","(1[1279]\\d{3})|0",,,"\\d{4,12}","[1-7]\\d{6,11}|8[0-357-9]\\d{6,9}|9\\d{7,9}",[["(80\\d{2})(\\d{4})","$1 $2","80[2678]","$NP$FG",],["([48]00)(\\d{3})(\\d{4})","$1 $2 $3","[48]00",,],["(\\d{5,6})","$1","100|95",,"NA"],["(\\d{2})(\\d{5,6})","$1 $2","(?:10|2\\d)[19]","$NP$FG",],["(\\d{3})(\\d{5,6})","$1 $2","[3-9]","$NP$FG",],["(\\d{3,4})(\\d{4})","$1 $2","[2-9]",,"NA"],["(21)(\\d{4})(\\d{4,6})","$1 $2 $3","21","$NP$FG",],["([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3","10[1-9]|2[02-9]","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","3(?:11|7[179])|4(?:[15]1|3[12])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:71|98)","$NP$FG",],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","1[3-578]",,],["(10800)(\\d{3})(\\d{4})","$1 $2 $3","108",,]]]',
|
||||
"257": '["BI","00",,,,,"\\d{8}","[27]\\d{7}",[["([27]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
|
||||
"86": '["CN","(1(?:[129]\\d{3}|79\\d{2}))?00","0","(1(?:[129]\\d{3}|79\\d{2}))|0",,,"\\d{4,12}","[1-7]\\d{6,11}|8[0-357-9]\\d{6,9}|9\\d{7,10}",[["(80\\d{2})(\\d{4})","$1 $2","80[2678]","$NP$FG",],["([48]00)(\\d{3})(\\d{4})","$1 $2 $3","[48]00",,],["(\\d{5,6})","$1","100|95",,"NA"],["(\\d{2})(\\d{5,6})","$1 $2","(?:10|2\\d)[19]","$NP$FG",],["(\\d{3})(\\d{5,6})","$1 $2","[3-9]","$NP$FG",],["(\\d{3,4})(\\d{4})","$1 $2","[2-9]",,"NA"],["(21)(\\d{4})(\\d{4,6})","$1 $2 $3","21","$NP$FG",],["([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3","10[1-9]|2[02-9]","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","3(?:11|7[179])|4(?:[15]1|3[12])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:[57]1|98)","$NP$FG",],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[4-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","1[3-578]",,],["(10800)(\\d{3})(\\d{4})","$1 $2 $3","108",,],["(\\d{3})(\\d{7,8})","$1 $2","950",,]]]',
|
||||
"257": '["BI","00",,,,,"\\d{8}","[267]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
|
||||
"683": '["NU","00",,,,,"\\d{4}","[1-5]\\d{3}",]',
|
||||
"43": '["AT","00","0",,,"$NP$FG","\\d{3,13}","[1-9]\\d{3,12}",[["(1)(\\d{3,12})","$1 $2","1",,],["(5\\d)(\\d{3,5})","$1 $2","5[079]",,],["(5\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","5[079]",,],["(5\\d)(\\d{4})(\\d{4,7})","$1 $2 $3","5[079]",,],["(\\d{3})(\\d{3,10})","$1 $2","316|46|51|732|6(?:44|5[0-3579]|[6-9])|7(?:1|[28]0)|[89]",,],["(\\d{4})(\\d{3,9})","$1 $2","2|3(?:1[1-578]|[3-8])|4[2378]|5[2-6]|6(?:[12]|4[1-35-9]|5[468])|7(?:2[1-8]|35|4[1-8]|[5-79])",,]]]',
|
||||
"247": '["AC","00",,,,,"\\d{4,6}","[2-7]\\d{3,5}",]',
|
||||
@ -84,7 +84,7 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"236": '["CF","00",,,,,"\\d{8}","[278]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
|
||||
"590": ['["GP","00","0",,,"$NP$FG","\\d{9}","[56]\\d{8}",[["([56]90)(\\d{2})(\\d{4})","$1 $2-$3",,,]]]','["BL","00","0",,,,"\\d{9}","[56]\\d{8}",]','["MF","00","0",,,,"\\d{9}","[56]\\d{8}",]'],
|
||||
"53": '["CU","119","0",,,"($NP$FG)","\\d{4,8}","[2-57]\\d{5,7}",[["(\\d)(\\d{6,7})","$1 $2","7",,],["(\\d{2})(\\d{4,6})","$1 $2","[2-4]",,],["(\\d)(\\d{7})","$1 $2","5","$NP$FG",]]]',
|
||||
"64": '["NZ","0(?:0|161)","0",,,"$NP$FG","\\d{7,11}","6[235-9]\\d{6}|[2-57-9]\\d{7,10}",[["([34679])(\\d{3})(\\d{4})","$1-$2 $3","[3467]|9[1-9]",,],["(24099)(\\d{3})","$1 $2","240",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","21",,],["(\\d{2})(\\d{3})(\\d{3,5})","$1 $2 $3","2(?:1[1-9]|[69]|7[0-35-9])|86",,],["(2\\d)(\\d{3,4})(\\d{4})","$1 $2 $3","2[028]",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","2(?:10|74)|5|[89]0",,]]]',
|
||||
"64": '["NZ","0(?:0|161)","0",,,"$NP$FG","\\d{7,11}","6[235-9]\\d{6}|[2-57-9]\\d{7,10}",[["([34679])(\\d{3})(\\d{4})","$1-$2 $3","[346]|7[2-57-9]|9[1-9]",,],["(24099)(\\d{3})","$1 $2","240",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","21",,],["(\\d{2})(\\d{3})(\\d{3,5})","$1 $2 $3","2(?:1[1-9]|[69]|7[0-35-9])|70|86",,],["(2\\d)(\\d{3,4})(\\d{4})","$1 $2 $3","2[028]",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","2(?:10|74)|5|[89]0",,]]]',
|
||||
"965": '["KW","00",,,,,"\\d{7,8}","[12569]\\d{6,7}",[["(\\d{4})(\\d{3,4})","$1 $2","[1269]",,],["(5[015]\\d)(\\d{5})","$1 $2","5",,]]]',
|
||||
"224": '["GN","00",,,,,"\\d{8,9}","[367]\\d{7,8}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","3",,],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[67]",,]]]',
|
||||
"973": '["BH","00",,,,,"\\d{8}","[136-9]\\d{7}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
|
||||
@ -105,7 +105,7 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"256": '["UG","00[057]","0",,,"$NP$FG","\\d{5,9}","\\d{9}",[["(\\d{3})(\\d{6})","$1 $2","[7-9]|20(?:[013-8]|2[5-9])|4(?:6[45]|[7-9])",,],["(\\d{2})(\\d{7})","$1 $2","3|4(?:[1-5]|6[0-36-9])",,],["(2024)(\\d{5})","$1 $2","2024",,]]]',
|
||||
"677": '["SB","0[01]",,,,,"\\d{5,7}","[1-9]\\d{4,6}",[["(\\d{2})(\\d{5})","$1 $2","[7-9]",,]]]',
|
||||
"377": '["MC","00","0",,,"$NP$FG","\\d{8,9}","[4689]\\d{7,8}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","9","$FG",],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","4",,],["(6)(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5","6",,],["(\\d{3})(\\d{3})(\\d{2})","$1 $2 $3","8","$FG",]]]',
|
||||
"382": '["ME","00","0",,,"$NP$FG","\\d{6,9}","[2-9]\\d{7,8}",[["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[2-57-9]|6[3789]",,],["(67)(9)(\\d{3})(\\d{3})","$1 $2 $3 $4","679",,]]]',
|
||||
"382": '["ME","00","0",,,"$NP$FG","\\d{6,9}","[2-9]\\d{7,8}",[["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[2-57-9]|6[036-9]",,],["(67)(9)(\\d{3})(\\d{3})","$1 $2 $3 $4","679",,]]]',
|
||||
"231": '["LR","00","0",,,"$NP$FG","\\d{7,9}","2\\d{7}|[37-9]\\d{8}|[45]\\d{6}",[["(2\\d)(\\d{3})(\\d{3})","$1 $2 $3","2",,],["([79]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[79]",,],["([4-6])(\\d{3})(\\d{3})","$1 $2 $3","[4-6]",,],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[38]",,]]]',
|
||||
"591": '["BO","00(1\\d)?","0","0(1\\d)?",,,"\\d{7,8}","[23467]\\d{7}",[["([234])(\\d{7})","$1 $2","[234]",,],["([67]\\d{7})","$1","[67]",,]]]',
|
||||
"808": '["001",,,,,,"\\d{8}","\\d{8}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
|
||||
@ -126,7 +126,7 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"213": '["DZ","00","0",,,"$NP$FG","\\d{8,9}","(?:[1-4]|[5-9]\\d)\\d{7}",[["([1-4]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[1-4]",,],["([5-8]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[5-8]",,],["(9\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","9",,]]]',
|
||||
"371": '["LV","00",,,,,"\\d{8}","[2689]\\d{7}",[["([2689]\\d)(\\d{3})(\\d{3})","$1 $2 $3",,,]]]',
|
||||
"503": '["SV","00",,,,,"\\d{7,8}|\\d{11}","[267]\\d{7}|[89]\\d{6}(?:\\d{4})?",[["(\\d{4})(\\d{4})","$1 $2","[267]",,],["(\\d{3})(\\d{4})","$1 $2","[89]",,],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","[89]",,]]]',
|
||||
"685": '["WS","0",,,,,"\\d{5,7}","[2-8]\\d{4,6}",[["(8\\d{2})(\\d{3,4})","$1 $2","8",,],["(7\\d)(\\d{5})","$1 $2","7",,]]]',
|
||||
"685": '["WS","0",,,,,"\\d{5,7}","[2-8]\\d{4,6}",[["(8\\d{2})(\\d{3,4})","$1 $2","8",,],["(7\\d)(\\d{5})","$1 $2","7",,],["(\\d{5})","$1","[2-6]",,]]]',
|
||||
"880": '["BD","00[12]?","0",,,"$NP$FG","\\d{6,10}","[2-79]\\d{5,9}|1\\d{9}|8[0-7]\\d{4,8}",[["(2)(\\d{7})","$1-$2","2",,],["(\\d{2})(\\d{4,6})","$1-$2","[3-79]1",,],["(\\d{4})(\\d{3,6})","$1-$2","1|3(?:0|[2-58]2)|4(?:0|[25]2|3[23]|[4689][25])|5(?:[02-578]2|6[25])|6(?:[0347-9]2|[26][25])|7[02-9]2|8(?:[023][23]|[4-7]2)|9(?:[02][23]|[458]2|6[016])",,],["(\\d{3})(\\d{3,7})","$1-$2","[3-79][2-9]|8",,]]]',
|
||||
"265": '["MW","00","0",,,"$NP$FG","\\d{7,9}","(?:1(?:\\d{2})?|[2789]\\d{2})\\d{6}",[["(\\d)(\\d{3})(\\d{3})","$1 $2 $3","1",,],["(2\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","2",,],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[1789]",,]]]',
|
||||
"65": '["SG","0[0-3]\\d",,,,,"\\d{8,11}","[36]\\d{7}|[17-9]\\d{7,10}",[["([3689]\\d{3})(\\d{4})","$1 $2","[369]|8[1-9]",,],["(1[89]00)(\\d{3})(\\d{4})","$1 $2 $3","1[89]",,],["(7000)(\\d{4})(\\d{3})","$1 $2 $3","70",,],["(800)(\\d{3})(\\d{4})","$1 $2 $3","80",,]]]',
|
||||
@ -144,7 +144,7 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"353": '["IE","00","0",,,"($NP$FG)","\\d{5,10}","[124-9]\\d{6,9}",[["(1)(\\d{3,4})(\\d{4})","$1 $2 $3","1",,],["(\\d{2})(\\d{5})","$1 $2","2[24-9]|47|58|6[237-9]|9[35-9]",,],["(\\d{3})(\\d{5})","$1 $2","40[24]|50[45]",,],["(48)(\\d{4})(\\d{4})","$1 $2 $3","48",,],["(818)(\\d{3})(\\d{3})","$1 $2 $3","81",,],["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","[24-69]|7[14]",,],["([78]\\d)(\\d{3,4})(\\d{4})","$1 $2 $3","76|8[35-9]","$NP$FG",],["(700)(\\d{3})(\\d{3})","$1 $2 $3","70","$NP$FG",],["(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:8[059]|5)","$FG",]]]',
|
||||
"966": '["SA","00","0",,,"$NP$FG","\\d{7,10}","1\\d{7,8}|(?:[2-467]|92)\\d{7}|5\\d{8}|8\\d{9}",[["([1-467])(\\d{3})(\\d{4})","$1 $2 $3","[1-467]",,],["(1\\d)(\\d{3})(\\d{4})","$1 $2 $3","1[1-467]",,],["(5\\d)(\\d{3})(\\d{4})","$1 $2 $3","5",,],["(92\\d{2})(\\d{5})","$1 $2","92","$FG",],["(800)(\\d{3})(\\d{4})","$1 $2 $3","80","$FG",],["(811)(\\d{3})(\\d{3,4})","$1 $2 $3","81",,]]]',
|
||||
"380": '["UA","00","0",,,"$NP$FG","\\d{5,9}","[3-689]\\d{8}",[["([3-689]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[38]9|4(?:[45][0-5]|87)|5(?:0|6[37]|7[37])|6[36-8]|9[1-9]",,],["([3-689]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","3[1-8]2|4[13678]2|5(?:[12457]2|6[24])|6(?:[49]2|[12][29]|5[24])|8[0-8]|90",,],["([3-6]\\d{3})(\\d{5})","$1 $2","3(?:5[013-9]|[1-46-8])|4(?:[137][013-9]|6|[45][6-9]|8[4-6])|5(?:[1245][013-9]|6[0135-9]|3|7[4-6])|6(?:[49][013-9]|5[0135-9]|[12][13-8])",,]]]',
|
||||
"98": '["IR","00","0",,,"$NP$FG","\\d{4,10}","[14-8]\\d{6,9}|[23]\\d{4,9}|9(?:[0-4]\\d{8}|9\\d{2,8})",[["(21)(\\d{3,5})","$1 $2","21",,],["(2[15])(\\d{3})(\\d{3,4})","$1 $2 $3","2(?:1|5[0-47-9])",,],["(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","2[156]|31|51|71|86",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","[13-9]|2[02-47-9]",,],["(\\d{3})(\\d{2})(\\d{2,3})","$1 $2 $3","[13-9]|2[02-47-9]",,],["(\\d{3})(\\d{3})","$1 $2","[13-9]|2[02-47-9]",,]]]',
|
||||
"98": '["IR","00","0",,,"$NP$FG","\\d{4,10}","[1-8]\\d{9}|9(?:[0-4]\\d{8}|9\\d{2,8})",[["(21)(\\d{3,5})","$1 $2","21",,],["(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","[1-8]",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","9",,],["(\\d{3})(\\d{2})(\\d{2,3})","$1 $2 $3","9",,],["(\\d{3})(\\d{3})","$1 $2","9",,]]]',
|
||||
"971": '["AE","00","0",,,"$NP$FG","\\d{5,12}","[2-79]\\d{7,8}|800\\d{2,9}",[["([2-4679])(\\d{3})(\\d{4})","$1 $2 $3","[2-4679][2-8]",,],["(5[0256])(\\d{3})(\\d{4})","$1 $2 $3","5",,],["([479]00)(\\d)(\\d{5})","$1 $2 $3","[479]0","$FG",],["([68]00)(\\d{2,9})","$1 $2","60|8","$FG",]]]',
|
||||
"30": '["GR","00",,,,,"\\d{10}","[26-9]\\d{9}",[["([27]\\d)(\\d{4})(\\d{4})","$1 $2 $3","21|7",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","2[2-9]1|[689]",,],["(2\\d{3})(\\d{6})","$1 $2","2[2-9][02-9]",,]]]',
|
||||
"228": '["TG","00",,,,,"\\d{8}","[29]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
|
||||
@ -154,9 +154,9 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"372": '["EE","00",,,,,"\\d{4,10}","1\\d{3,4}|[3-9]\\d{6,7}|800\\d{6,7}",[["([3-79]\\d{2})(\\d{4})","$1 $2","[369]|4[3-8]|5(?:[0-2]|5[0-478]|6[45])|7[1-9]",,],["(70)(\\d{2})(\\d{4})","$1 $2 $3","70",,],["(8000)(\\d{3})(\\d{3})","$1 $2 $3","800",,],["([458]\\d{3})(\\d{3,4})","$1 $2","40|5|8(?:00|[1-5])",,]]]',
|
||||
"598": '["UY","0(?:1[3-9]\\d|0)","0",,,,"\\d{7,8}","[2489]\\d{6,7}",[["(\\d{4})(\\d{4})","$1 $2","[24]",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","9[1-9]","$NP$FG",],["(\\d{3})(\\d{4})","$1 $2","[89]0","$NP$FG",]]]',
|
||||
"502": '["GT","00",,,,,"\\d{8}(?:\\d{3})?","[2-7]\\d{7}|1[89]\\d{9}",[["(\\d{4})(\\d{4})","$1 $2","[2-7]",,],["(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3","1",,]]]',
|
||||
"82": '["KR","00(?:[124-68]|[37]\\d{2})","0","0(8[1-46-8]|85\\d{2})?",,"$NP$FG","\\d{4,10}","[1-7]\\d{3,9}|8\\d{8}",[["(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3","1(?:0|1[19]|[69]9|5[458])|[57]0",,],["(\\d{2})(\\d{3,4})(\\d{4})","$1-$2-$3","1(?:[169][2-8]|[78]|5[1-4])|[68]0|[3-6][1-9][1-9]",,],["(\\d{3})(\\d)(\\d{4})","$1-$2-$3","131",,],["(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3","131",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","13[2-9]",,],["(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4","30",,],["(\\d)(\\d{3,4})(\\d{4})","$1-$2-$3","2[1-9]",,],["(\\d)(\\d{3,4})","$1-$2","21[0-46-9]",,],["(\\d{2})(\\d{3,4})","$1-$2","[3-6][1-9]1",,],["(\\d{4})(\\d{4})","$1-$2","1(?:5[46-9]|6[04678])","$FG",]]]',
|
||||
"82": '["KR","00(?:[124-68]|[37]\\d{2})","0","0(8[1-46-8]|85\\d{2})?",,"$NP$FG","\\d{4,10}","[1-7]\\d{3,9}|8\\d{8}",[["(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3","1(?:0|1[19]|[69]9|5[458])|[57]0",,],["(\\d{2})(\\d{3,4})(\\d{4})","$1-$2-$3","1(?:[169][2-8]|[78]|5[1-4])|[68]0|[3-6][1-9][1-9]",,],["(\\d{3})(\\d)(\\d{4})","$1-$2-$3","131",,],["(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3","131",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","13[2-9]",,],["(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4","30",,],["(\\d)(\\d{3,4})(\\d{4})","$1-$2-$3","2[1-9]",,],["(\\d)(\\d{3,4})","$1-$2","21[0-46-9]",,],["(\\d{2})(\\d{3,4})","$1-$2","[3-6][1-9]1",,],["(\\d{4})(\\d{4})","$1-$2","1(?:5[46-9]|6[04678]|8[0579])","$FG",]]]',
|
||||
"253": '["DJ","00",,,,,"\\d{8}","[27]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
|
||||
"91": '["IN","00","0",,,"$NP$FG","\\d{6,13}","1\\d{7,12}|[2-9]\\d{9,10}",[["(\\d{5})(\\d{5})","$1 $2","7(?:0[2-9]|2[0579]|3[057-9]|4[0-389]|6[0-35-9]|[57]|8[0-79])|8(?:0[015689]|1[0-57-9]|2[2356-9]|3[0-57-9]|[45]|6[02457-9]|7[1-69]|8[0124-9]|9[02-9])|9",,],["(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","11|2[02]|33|4[04]|79|80[2-46]",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1(?:2[0-249]|3[0-25]|4[145]|[569][14]|7[1257]|8[1346]|[68][1-9])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:[136][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)",,],["(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:[23579]|[468][1-9])|[2-8]",,],["(1600)(\\d{2})(\\d{4})","$1 $2 $3","160","$FG",],["(1800)(\\d{4,5})","$1 $2","180","$FG",],["(18[06]0)(\\d{2,4})(\\d{4})","$1 $2 $3","18[06]","$FG",],["(140)(\\d{3})(\\d{4})","$1 $2 $3","140","$FG",],["(\\d{4})(\\d{3})(\\d{4})(\\d{2})","$1 $2 $3 $4","18[06]","$FG",]]]',
|
||||
"91": '["IN","00","0",,,"$NP$FG","\\d{6,13}","1\\d{7,12}|[2-9]\\d{9,10}",[["(\\d{5})(\\d{5})","$1 $2","7(?:0[2-9]|2[0579]|3[057-9]|4[0-389]|6[0-35-9]|[57]|8[0-79])|8(?:0[015689]|1[0-57-9]|2[2356-9]|3[0-57-9]|[45]|6[02457-9]|7[1-69]|8[0124-9]|9[02-9])|9",,],["(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","11|2[02]|33|4[04]|79|80[2-46]",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1(?:2[0-249]|3[0-25]|4[145]|[569][14]|7[1257]|8[1346]|[68][1-9])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[0-26-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:[136][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)",,],["(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:[23579]|[468][1-9])|[2-8]",,],["(1600)(\\d{2})(\\d{4})","$1 $2 $3","160","$FG",],["(1800)(\\d{4,5})","$1 $2","180","$FG",],["(18[06]0)(\\d{2,4})(\\d{4})","$1 $2 $3","18[06]","$FG",],["(140)(\\d{3})(\\d{4})","$1 $2 $3","140","$FG",],["(\\d{4})(\\d{3})(\\d{4})(\\d{2})","$1 $2 $3 $4","18[06]","$FG",]]]',
|
||||
"389": '["MK","00","0",,,"$NP$FG","\\d{8}","[2-578]\\d{7}",[["(2)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["([347]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[347]",,],["([58]\\d{2})(\\d)(\\d{2})(\\d{2})","$1 $2 $3 $4","[58]",,]]]',
|
||||
"1": ['["US","011","1",,,,"\\d{7}(?:\\d{3})?","[2-9]\\d{9}",[["(\\d{3})(\\d{4})","$1-$2",,,"NA"],["(\\d{3})(\\d{3})(\\d{4})","($1) $2-$3",,,"$1-$2-$3"]]]','["AI","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["AS","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["BB","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["BM","011","1",,,,"\\d{7}(?:\\d{3})?","[4589]\\d{9}",]','["BS","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["CA","011","1",,,,"\\d{7}(?:\\d{3})?","[2-9]\\d{9}|3\\d{6}",]','["DM","011","1",,,,"\\d{7}(?:\\d{3})?","[57-9]\\d{9}",]','["DO","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["GD","011","1",,,,"\\d{7}(?:\\d{3})?","[4589]\\d{9}",]','["GU","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["JM","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["KN","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["KY","011","1",,,,"\\d{7}(?:\\d{3})?","[3589]\\d{9}",]','["LC","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["MP","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["MS","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["PR","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["SX","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["TC","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["TT","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["AG","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["VC","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["VG","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["VI","011","1",,,,"\\d{7}(?:\\d{3})?","[3589]\\d{9}",]'],
|
||||
"60": '["MY","00","0",,,,"\\d{6,10}","[13-9]\\d{7,9}",[["([4-79])(\\d{3})(\\d{4})","$1-$2 $3","[4-79]","$NP$FG",],["(3)(\\d{4})(\\d{4})","$1-$2 $3","3","$NP$FG",],["([18]\\d)(\\d{3})(\\d{3,4})","$1-$2 $3","1[02-46-9][1-9]|8","$NP$FG",],["(1)([36-8]00)(\\d{2})(\\d{4})","$1-$2-$3-$4","1[36-8]0",,],["(11)(\\d{4})(\\d{4})","$1-$2 $3","11","$NP$FG",],["(15[49])(\\d{3})(\\d{4})","$1-$2 $3","15","$NP$FG",]]]',
|
||||
@ -166,14 +166,14 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"686": '["KI","00",,"0",,,"\\d{5,8}","[2458]\\d{4}|3\\d{4,7}|7\\d{7}",]',
|
||||
"994": '["AZ","00","0",,,"($NP$FG)","\\d{7,9}","[1-9]\\d{8}",[["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","(?:1[28]|2(?:[45]2|[0-36])|365)",,],["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[4-8]","$NP$FG",],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","9","$NP$FG",]]]',
|
||||
"979": '["001",,,,,,"\\d{9}","\\d{9}",[["(\\d)(\\d{4})(\\d{4})","$1 $2 $3",,,]]]',
|
||||
"66": '["TH","00","0",,,"$NP$FG","\\d{4}|\\d{8,10}","[2-9]\\d{7,8}|1\\d{3}(?:\\d{6})?",[["(2)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["([3-9]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","[3-9]",,],["(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3","1","$FG",]]]',
|
||||
"66": '["TH","00","0",,,"$NP$FG","\\d{4}|\\d{8,10}","[2-9]\\d{7,8}|1\\d{3}(?:\\d{5,6})?",[["(2)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["([13-9]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","14|[3-9]",,],["(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3","1","$FG",]]]',
|
||||
"233": '["GH","00","0",,,"$NP$FG","\\d{7,9}","[235]\\d{8}|8\\d{7}",[["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[235]",,],["(\\d{3})(\\d{5})","$1 $2","8",,]]]',
|
||||
"593": '["EC","00","0",,,"($NP$FG)","\\d{7,11}","1\\d{9,10}|[2-8]\\d{7}|9\\d{8}",[["(\\d)(\\d{3})(\\d{4})","$1 $2-$3","[247]|[356][2-8]",,"$1-$2-$3"],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","9","$NP$FG",],["(1800)(\\d{3})(\\d{3,4})","$1 $2 $3","1","$FG",]]]',
|
||||
"509": '["HT","00",,,,,"\\d{8}","[2-489]\\d{7}",[["(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",,,]]]',
|
||||
"54": '["AR","00","0","0?(?:(11|2(?:2(?:02?|[13]|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1267])|3(?:02?|1[467]|2[03-6]|3[13-8]|[49][2-6]|5[2-8]|[67])|4(?:7[3-578]|9)|6(?:[0136]|2[24-6]|4[6-8]?|5[15-8])|80|9(?:0[1-3]|[19]|2\\d|3[1-6]|4[02568]?|5[2-4]|6[2-46]|72?|8[23]?))|3(?:3(?:2[79]|6|8[2578])|4(?:0[124-9]|[12]|3[5-8]?|4[24-7]|5[4-68]?|6[02-9]|7[126]|8[2379]?|9[1-36-8])|5(?:1|2[1245]|3[237]?|4[1-46-9]|6[2-4]|7[1-6]|8[2-5]?)|6[24]|7(?:1[1568]|2[15]|3[145]|4[13]|5[14-8]|[069]|7[2-57]|8[126])|8(?:[01]|2[15-7]|3[2578]?|4[13-6]|5[4-8]?|6[1-357-9]|7[36-8]?|8[5-8]?|9[124])))?15)?","9$1","$NP$FG","\\d{6,11}","11\\d{8}|[2368]\\d{9}|9\\d{10}",[["([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","[68]",,],["(\\d{2})(\\d{4})","$1-$2","[2-9]","$FG","NA"],["(\\d{3})(\\d{4})","$1-$2","[2-9]","$FG","NA"],["(\\d{4})(\\d{4})","$1-$2","[2-9]","$FG","NA"],["(9)(11)(\\d{4})(\\d{4})","$2 15-$3-$4","911",,"$1 $2 $3-$4"],["(9)(\\d{3})(\\d{3})(\\d{4})","$2 15-$3-$4","9(?:2[234689]|3[3-8])",,"$1 $2 $3-$4"],["(9)(\\d{4})(\\d{2})(\\d{4})","$2 15-$3-$4","9[23]",,"$1 $2 $3-$4"],["(11)(\\d{4})(\\d{4})","$1 $2-$3","1",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3","2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[12358]|5[138]|6[24]|7[069]|8[013578])",,],["(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","[23]",,],["(\\d{3})","$1","1[012]|911","$FG","NA"]]]',
|
||||
"54": '["AR","00","0","0?(?:(11|2(?:2(?:02?|[13]|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1267])|3(?:02?|1[467]|2[03-6]|3[13-8]|[49][2-6]|5[2-8]|[67])|4(?:7[3-578]|9)|6(?:[0136]|2[24-6]|4[6-8]?|5[15-8])|80|9(?:0[1-3]|[19]|2\\d|3[1-6]|4[02568]?|5[2-4]|6[2-46]|72?|8[23]?))|3(?:3(?:2[79]|6|8[2578])|4(?:0[0-24-9]|[12]|3[5-8]?|4[24-7]|5[4-68]?|6[02-9]|7[126]|8[2379]?|9[1-36-8])|5(?:1|2[1245]|3[237]?|4[1-46-9]|6[2-4]|7[1-6]|8[2-5]?)|6[24]|7(?:[069]|1[1568]|2[15]|3[145]|4[13]|5[14-8]|7[2-57]|8[126])|8(?:[01]|2[15-7]|3[2578]?|4[13-6]|5[4-8]?|6[1-357-9]|7[36-8]?|8[5-8]?|9[124])))?15)?","9$1","$NP$FG","\\d{6,11}","11\\d{8}|[2368]\\d{9}|9\\d{10}",[["([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","[68]",,],["(\\d{2})(\\d{4})","$1-$2","[2-9]","$FG","NA"],["(\\d{3})(\\d{4})","$1-$2","[2-9]","$FG","NA"],["(\\d{4})(\\d{4})","$1-$2","[2-9]","$FG","NA"],["(9)(11)(\\d{4})(\\d{4})","$2 15-$3-$4","911",,"$1 $2 $3-$4"],["(9)(\\d{3})(\\d{3})(\\d{4})","$2 15-$3-$4","9(?:2[234689]|3[3-8])",,"$1 $2 $3-$4"],["(9)(\\d{4})(\\d{2})(\\d{4})","$2 15-$3-$4","9[23]",,"$1 $2 $3-$4"],["(11)(\\d{4})(\\d{4})","$1 $2-$3","1",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3","2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578])",,],["(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","[23]",,],["(\\d{3})","$1","1[012]|911","$FG","NA"]]]',
|
||||
"57": '["CO","00(?:4(?:[14]4|56)|[579])","0","0([3579]|4(?:44|56))?",,,"\\d{7,11}","(?:[13]\\d{0,3}|[24-8])\\d{7}",[["(\\d)(\\d{7})","$1 $2","1(?:8[2-9]|9[0-3]|[2-7])|[24-8]","($FG)",],["(\\d{3})(\\d{7})","$1 $2","3",,],["(1)(\\d{3})(\\d{7})","$1-$2-$3","1(?:80|9[04])","$NP$FG","$1 $2 $3"]]]',
|
||||
"597": '["SR","00",,,,,"\\d{6,7}","[2-8]\\d{5,6}",[["(\\d{3})(\\d{3})","$1-$2","[2-4]|5[2-58]",,],["(\\d{2})(\\d{2})(\\d{2})","$1-$2-$3","56",,],["(\\d{3})(\\d{4})","$1-$2","59|[6-8]",,]]]',
|
||||
"676": '["TO","00",,,,,"\\d{5,7}","[02-8]\\d{4,6}",[["(\\d{2})(\\d{3})","$1-$2","[1-6]|7[0-4]|8[05]",,],["(\\d{3})(\\d{4})","$1 $2","7[5-9]|8[7-9]",,],["(\\d{4})(\\d{3})","$1 $2","0",,]]]',
|
||||
"676": '["TO","00",,,,,"\\d{5,7}","[02-8]\\d{4,6}",[["(\\d{2})(\\d{3})","$1-$2","[1-6]|7[0-4]|8[05]",,],["(\\d{3})(\\d{4})","$1 $2","7[5-9]|8[47-9]",,],["(\\d{4})(\\d{3})","$1 $2","0",,]]]',
|
||||
"505": '["NI","00",,,,,"\\d{8}","[12578]\\d{7}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
|
||||
"850": '["KP","00|99","0",,,"$NP$FG","\\d{6,8}|\\d{10}","1\\d{9}|[28]\\d{7}",[["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1",,],["(\\d)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","8",,]]]',
|
||||
"7": ['["RU","810","8",,,"$NP ($FG)","\\d{10}","[3489]\\d{9}",[["(\\d{3})(\\d{2})(\\d{2})","$1-$2-$3","[1-79]","$FG","NA"],["([3489]\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4","[34689]",,],["(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","7",,]]]','["KZ","810","8",,,,"\\d{10}","(?:33\\d|7\\d{2}|80[09])\\d{7}",]'],
|
||||
@ -217,6 +217,6 @@ this.PHONE_NUMBER_META_DATA = {
|
||||
"960": '["MV","0(?:0|19)",,,,,"\\d{7,10}","[3467]\\d{6}|9(?:00\\d{7}|\\d{6})",[["(\\d{3})(\\d{4})","$1-$2","[3467]|9(?:[1-9]|0[1-9])",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","900",,]]]',
|
||||
"221": '["SN","00",,,,,"\\d{9}","[3789]\\d{8}",[["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[379]",,],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","8",,]]]',
|
||||
"595": '["PY","00","0",,,,"\\d{5,9}","5[0-5]\\d{4,7}|[2-46-9]\\d{5,8}",[["(\\d{2})(\\d{5,7})","$1 $2","(?:[26]1|3[289]|4[124678]|7[123]|8[1236])","($FG)",],["(\\d{3})(\\d{3,6})","$1 $2","[2-9]0","$NP$FG",],["(\\d{3})(\\d{6})","$1 $2","9[1-9]","$NP$FG",],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","8700",,],["(\\d{3})(\\d{4,6})","$1 $2","[2-8][1-9]","($FG)",]]]',
|
||||
"977": '["NP","00","0",,,"$NP$FG","\\d{6,10}","[1-8]\\d{7}|9(?:[1-69]\\d{6}|7[2-6]\\d{5,7}|8\\d{8})",[["(1)(\\d{7})","$1-$2","1[2-6]",,],["(\\d{2})(\\d{6})","$1-$2","1[01]|[2-8]|9(?:[1-69]|7[15-9])",,],["(9\\d{2})(\\d{7})","$1-$2","9(?:7[45]|8)",,]]]',
|
||||
"977": '["NP","00","0",,,"$NP$FG","\\d{6,10}","[1-8]\\d{7}|9(?:[1-69]\\d{6,8}|7[2-6]\\d{5,7}|8\\d{8})",[["(1)(\\d{7})","$1-$2","1[2-6]",,],["(\\d{2})(\\d{6})","$1-$2","1[01]|[2-8]|9(?:[1-69]|7[15-9])",,],["(9\\d{2})(\\d{7})","$1-$2","9(?:6[013]|7[245]|8)",,]]]',
|
||||
"36": '["HU","00","06",,,"($FG)","\\d{6,9}","[1-9]\\d{7,8}",[["(1)(\\d{3})(\\d{4})","$1 $2 $3","1",,],["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","[2-9]",,]]]',
|
||||
};
|
||||
|
@ -87,7 +87,7 @@ elif CONFIG['OS_ARCH'] in ('DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD'):
|
||||
UNIFIED_SOURCES += [
|
||||
'ProcessUtils_bsd.cpp'
|
||||
]
|
||||
elif CONFIG['OS_ARCH'] in ('Darwin'):
|
||||
elif CONFIG['OS_ARCH'] == 'Darwin':
|
||||
UNIFIED_SOURCES += [
|
||||
'ProcessUtils_mac.mm'
|
||||
]
|
||||
|
@ -19,6 +19,7 @@ public class AboutPages {
|
||||
public static final String FIREFOX = "about:firefox";
|
||||
public static final String HEALTHREPORT = "about:healthreport";
|
||||
public static final String HOME = "about:home";
|
||||
public static final String PASSWORDS = "about:passwords";
|
||||
public static final String PRIVATEBROWSING = "about:privatebrowsing";
|
||||
public static final String READER = "about:reader";
|
||||
public static final String UPDATER = "about:";
|
||||
|
@ -2939,6 +2939,7 @@ public class BrowserApp extends GeckoApp
|
||||
ClearOnShutdownPref.PREF,
|
||||
new HashSet<String>()).isEmpty();
|
||||
aMenu.findItem(R.id.quit).setVisible(visible);
|
||||
aMenu.findItem(R.id.logins).setVisible(AppConstants.NIGHTLY_BUILD);
|
||||
|
||||
if (tab == null || tab.getURL() == null) {
|
||||
bookmark.setEnabled(false);
|
||||
@ -3167,6 +3168,11 @@ public class BrowserApp extends GeckoApp
|
||||
return true;
|
||||
}
|
||||
|
||||
if (itemId == R.id.logins) {
|
||||
Tabs.getInstance().loadUrlInTab(AboutPages.PASSWORDS);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (itemId == R.id.apps) {
|
||||
Tabs.getInstance().loadUrlInTab(AboutPages.APPS);
|
||||
return true;
|
||||
|
@ -4,10 +4,6 @@
|
||||
|
||||
package org.mozilla.gecko.fxa.activities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
@ -43,6 +39,14 @@ import android.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* A fragment that displays the status of an AndroidFxAccount.
|
||||
* <p>
|
||||
@ -54,6 +58,15 @@ public class FxAccountStatusFragment
|
||||
implements OnPreferenceClickListener, OnPreferenceChangeListener {
|
||||
private static final String LOG_TAG = FxAccountStatusFragment.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* If a device claims to have synced before this date, we will assume it has never synced.
|
||||
*/
|
||||
private static final Date EARLIEST_VALID_SYNCED_DATE;
|
||||
static {
|
||||
final Calendar c = GregorianCalendar.getInstance();
|
||||
c.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
|
||||
EARLIEST_VALID_SYNCED_DATE = c.getTime();
|
||||
}
|
||||
// When a checkbox is toggled, wait 5 seconds (for other checkbox actions)
|
||||
// before trying to sync. Should we kill off the fragment before the sync
|
||||
// request happens, that's okay: the runnable will run if the UI thread is
|
||||
@ -529,6 +542,9 @@ public class FxAccountStatusFragment
|
||||
|
||||
// This is a helper function similar to TabsAccessor.getLastSyncedString() to calculate relative "Last synced" time span.
|
||||
private String getLastSyncedString(final long startTime) {
|
||||
if (new Date(startTime).before(EARLIEST_VALID_SYNCED_DATE)) {
|
||||
return getActivity().getString(R.string.fxaccount_status_never_synced);
|
||||
}
|
||||
final CharSequence relativeTimeSpanString = DateUtils.getRelativeTimeSpanString(startTime);
|
||||
return getActivity().getResources().getString(R.string.fxaccount_status_last_synced, relativeTimeSpanString);
|
||||
}
|
||||
|
@ -141,7 +141,9 @@
|
||||
<!ENTITY pref_category_devtools_summary "Remote debugging, paint flashing">
|
||||
<!ENTITY pref_developer_paint_flashing "Paint flashing">
|
||||
<!ENTITY pref_developer_remotedebugging "Remote debugging">
|
||||
<!ENTITY pref_category_logins "Logins">
|
||||
<!ENTITY pref_remember_signons "Remember passwords">
|
||||
<!ENTITY pref_manage_logins "Manage logins">
|
||||
|
||||
<!ENTITY pref_category_home "Home">
|
||||
<!ENTITY pref_category_home_summary "Customize your homepage">
|
||||
@ -287,6 +289,7 @@ size. -->
|
||||
<!ENTITY quit "Quit">
|
||||
|
||||
<!ENTITY addons "Add-ons">
|
||||
<!ENTITY logins "Logins">
|
||||
<!ENTITY downloads "Downloads">
|
||||
<!ENTITY apps "Apps">
|
||||
<!ENTITY char_encoding "Character Encoding">
|
||||
|
@ -115,6 +115,7 @@ OnSharedPreferenceChangeListener
|
||||
private static final String PREFS_CRASHREPORTER_ENABLED = "datareporting.crashreporter.submitEnabled";
|
||||
private static final String PREFS_MENU_CHAR_ENCODING = "browser.menu.showCharacterEncoding";
|
||||
private static final String PREFS_MP_ENABLED = "privacy.masterpassword.enabled";
|
||||
private static final String PREFS_LOGIN_MANAGE = NON_PREF_PREFIX + "signon.manage";
|
||||
private static final String PREFS_UPDATER_AUTODOWNLOAD = "app.update.autodownload";
|
||||
private static final String PREFS_UPDATER_URL = "app.update.url.android";
|
||||
private static final String PREFS_GEO_REPORTING = NON_PREF_PREFIX + "app.geo.reportdata";
|
||||
@ -674,6 +675,10 @@ OnSharedPreferenceChangeListener
|
||||
preferences.removePreference(pref);
|
||||
i--;
|
||||
continue;
|
||||
} else if (!AppConstants.NIGHTLY_BUILD &&
|
||||
PREFS_LOGIN_MANAGE.equals(key)) {
|
||||
preferences.removePreference(pref);
|
||||
i--;
|
||||
} else if (AppConstants.RELEASE_BUILD &&
|
||||
PREFS_DISPLAY_REFLOW_ON_ZOOM.equals(key)) {
|
||||
// Remove UI for reflow on release builds.
|
||||
|
@ -16,7 +16,8 @@
|
||||
<org.mozilla.gecko.widget.GeckoSwipeRefreshLayout
|
||||
android:id="@id/remote_tabs_refresh_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:enabled="false">
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -86,6 +86,9 @@
|
||||
android:icon="@drawable/ic_menu_addons"
|
||||
android:title="@string/addons"/>
|
||||
|
||||
<item android:id="@+id/logins"
|
||||
android:title="@string/logins"/>
|
||||
|
||||
<item android:id="@+id/apps"
|
||||
android:icon="@drawable/ic_menu_apps"
|
||||
android:title="@string/apps"/>
|
||||
|
@ -86,6 +86,9 @@
|
||||
android:icon="@drawable/ic_menu_addons"
|
||||
android:title="@string/addons"/>
|
||||
|
||||
<item android:id="@+id/logins"
|
||||
android:title="@string/logins"/>
|
||||
|
||||
<item android:id="@+id/apps"
|
||||
android:icon="@drawable/ic_menu_apps"
|
||||
android:title="@string/apps"/>
|
||||
|
@ -87,6 +87,9 @@
|
||||
android:icon="@drawable/ic_menu_addons"
|
||||
android:title="@string/addons"/>
|
||||
|
||||
<item android:id="@+id/logins"
|
||||
android:title="@string/logins"/>
|
||||
|
||||
<item android:id="@+id/apps"
|
||||
android:icon="@drawable/ic_menu_apps"
|
||||
android:title="@string/apps"/>
|
||||
|
@ -49,6 +49,9 @@
|
||||
<item android:id="@+id/downloads"
|
||||
android:title="@string/downloads"/>
|
||||
|
||||
<item android:id="@+id/logins"
|
||||
android:title="@string/logins"/>
|
||||
|
||||
<item android:id="@+id/apps"
|
||||
android:title="@string/apps"/>
|
||||
|
||||
|
@ -36,13 +36,21 @@
|
||||
android:entryValues="@array/pref_cookies_values"
|
||||
android:persistent="false" />
|
||||
|
||||
<CheckBoxPreference android:key="signon.rememberSignons"
|
||||
android:title="@string/pref_remember_signons"
|
||||
android:persistent="false" />
|
||||
<PreferenceCategory android:title="@string/pref_category_logins">
|
||||
|
||||
<CheckBoxPreference android:key="privacy.masterpassword.enabled"
|
||||
android:title="@string/pref_use_master_password"
|
||||
android:persistent="false" />
|
||||
<org.mozilla.gecko.preferences.LinkPreference android:key="android.not_a_preference.signon.manage"
|
||||
android:title="@string/pref_manage_logins"
|
||||
url="about:passwords"/>
|
||||
|
||||
<CheckBoxPreference android:key="signon.rememberSignons"
|
||||
android:title="@string/pref_remember_signons"
|
||||
android:persistent="false" />
|
||||
|
||||
<CheckBoxPreference android:key="privacy.masterpassword.enabled"
|
||||
android:title="@string/pref_use_master_password"
|
||||
android:persistent="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<!-- keys prefixed with "android.not_a_preference." are not synced with Gecko -->
|
||||
<PreferenceCategory android:title="@string/pref_clear_private_data_category">
|
||||
|
@ -174,7 +174,9 @@
|
||||
|
||||
<string name="pref_learn_more">&pref_learn_more;</string>
|
||||
|
||||
<string name="pref_category_logins">&pref_category_logins;</string>
|
||||
<string name="pref_remember_signons">&pref_remember_signons;</string>
|
||||
<string name="pref_manage_logins">&pref_manage_logins;</string>
|
||||
|
||||
<string name="pref_cookies_menu">&pref_cookies_menu;</string>
|
||||
<string name="pref_cookies_accept_all">&pref_cookies_accept_all;</string>
|
||||
@ -284,6 +286,7 @@
|
||||
<string name="one_tab">&one_tab;</string>
|
||||
<string name="num_tabs">&num_tabs2;</string>
|
||||
<string name="addons">&addons;</string>
|
||||
<string name="logins">&logins;</string>
|
||||
<string name="downloads">&downloads;</string>
|
||||
<string name="apps">&apps;</string>
|
||||
<string name="char_encoding">&char_encoding;</string>
|
||||
|
@ -34,6 +34,7 @@ public class StringHelper {
|
||||
public static final String ABOUT_DOWNLOADS_URL = "about:downloads";
|
||||
public static final String ABOUT_HOME_URL = "about:home";
|
||||
public static final String ABOUT_ADDONS_URL = "about:addons";
|
||||
public static final String ABOUT_PASSWORDS_URL = "about:passwords";
|
||||
public static final String ABOUT_APPS_URL = "about:apps";
|
||||
public static final String ABOUT_ABOUT_URL = "about:about";
|
||||
public static final String ABOUT_SCHEME = "about:";
|
||||
@ -184,6 +185,7 @@ public class StringHelper {
|
||||
public static final String DNT_LABEL = "Do not track";
|
||||
public static final String COOKIES_LABEL = "Cookies";
|
||||
public static final String REMEMBER_PASSWORDS_LABEL = "Remember passwords";
|
||||
public static final String MANAGE_LOGINS_LABEL = "Manage logins";
|
||||
public static final String MASTER_PASSWORD_LABEL = "Use master password";
|
||||
public static final String CLEAR_PRIVATE_DATA_LABEL = "Clear now";
|
||||
|
||||
@ -226,6 +228,7 @@ public class StringHelper {
|
||||
public static final String PDF_LABEL = "Save as PDF";
|
||||
public static final String DOWNLOADS_LABEL = "Downloads";
|
||||
public static final String ADDONS_LABEL = "Add-ons";
|
||||
public static final String LOGINS_LABEL = "Logins";
|
||||
public static final String APPS_LABEL = "Apps";
|
||||
public static final String SETTINGS_LABEL = "Settings";
|
||||
public static final String GUEST_MODE_LABEL = "New Guest Session";
|
||||
|
@ -59,11 +59,13 @@ public class testSettingsMenuItems extends PixelTest {
|
||||
// Privacy menu items.
|
||||
String[] PATH_PRIVACY = { StringHelper.PRIVACY_SECTION_LABEL };
|
||||
final String[] TRACKING_PROTECTION_LABEL_ARR = { StringHelper.TRACKING_PROTECTION_LABEL };
|
||||
final String[] MANAGE_LOGINS_ARR = { StringHelper.MANAGE_LOGINS_LABEL };
|
||||
String[][] OPTIONS_PRIVACY = {
|
||||
TRACKING_PROTECTION_LABEL_ARR,
|
||||
{ StringHelper.DNT_LABEL },
|
||||
{ StringHelper.COOKIES_LABEL, "Enabled", "Enabled, excluding 3rd party", "Disabled" },
|
||||
{ StringHelper.REMEMBER_PASSWORDS_LABEL },
|
||||
MANAGE_LOGINS_ARR,
|
||||
{ StringHelper.MASTER_PASSWORD_LABEL },
|
||||
{ StringHelper.CLEAR_PRIVATE_DATA_LABEL, "", "Browsing history", "Downloads", "Form & search history", "Cookies & active logins", "Saved passwords", "Cache", "Offline website data", "Site settings", "Clear data" },
|
||||
};
|
||||
@ -171,7 +173,9 @@ public class testSettingsMenuItems extends PixelTest {
|
||||
}
|
||||
|
||||
if (!AppConstants.NIGHTLY_BUILD) {
|
||||
settingsMap.get(PATH_PRIVACY).remove(TRACKING_PROTECTION_LABEL_ARR);
|
||||
final List<String[]> privacy = settingsMap.get(PATH_PRIVACY);
|
||||
privacy.remove(TRACKING_PROTECTION_LABEL_ARR);
|
||||
privacy.remove(MANAGE_LOGINS_ARR);
|
||||
}
|
||||
|
||||
// Automatic updates
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.mozilla.gecko.tests;
|
||||
|
||||
import org.mozilla.gecko.Actions;
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
|
||||
/** This patch tests the System Pages first by loading system pages from
|
||||
* the awesome bar and then from Firefox menu
|
||||
@ -13,13 +14,14 @@ public class testSystemPages extends PixelTest {
|
||||
blockForGeckoReady();
|
||||
|
||||
final String urls [] = { StringHelper.ABOUT_FIREFOX_URL, StringHelper.ABOUT_RIGHTS_URL,
|
||||
StringHelper.ABOUT_ADDONS_URL, StringHelper.ABOUT_DOWNLOADS_URL,
|
||||
StringHelper.ABOUT_ADDONS_URL, StringHelper.ABOUT_DOWNLOADS_URL, StringHelper.ABOUT_PASSWORDS_URL,
|
||||
StringHelper.ABOUT_BUILDCONFIG_URL, StringHelper.ABOUT_FEEDBACK_URL,
|
||||
StringHelper.ABOUT_HEALTHREPORT_URL, StringHelper.ABOUT_SCHEME
|
||||
};
|
||||
// Pages to be tested from the menu and their expected urls. This if of the form { {{ <path to item> }, { <expected url> }}* }
|
||||
String menuItems [][][] = {{{ StringHelper.APPS_LABEL }, { StringHelper.ABOUT_APPS_URL }},
|
||||
{{ StringHelper.DOWNLOADS_LABEL }, { StringHelper.ABOUT_DOWNLOADS_URL}},
|
||||
{{ StringHelper.LOGINS_LABEL}, { StringHelper.ABOUT_PASSWORDS_URL }},
|
||||
{{ StringHelper.ADDONS_LABEL }, { StringHelper.ABOUT_ADDONS_URL }},
|
||||
{{ StringHelper.SETTINGS_LABEL, StringHelper.MOZILLA_SECTION_LABEL, StringHelper.ABOUT_LABEL }, { StringHelper.ABOUT_SCHEME }},
|
||||
{{ StringHelper.SETTINGS_LABEL, StringHelper.MOZILLA_SECTION_LABEL, StringHelper.FEEDBACK_LABEL }, { StringHelper.ABOUT_FEEDBACK_URL }},
|
||||
@ -48,6 +50,9 @@ public class testSystemPages extends PixelTest {
|
||||
// Load from Url the about: pages,verify the Url and the tabs number
|
||||
public void checkUrl(String urls []) {
|
||||
for (String url:urls) {
|
||||
if (skipItemURL(url)) {
|
||||
continue;
|
||||
}
|
||||
loadAndPaint(url);
|
||||
verifyTabCount(mExpectedTabCount);
|
||||
verifyUrl(url);
|
||||
@ -64,6 +69,10 @@ public class testSystemPages extends PixelTest {
|
||||
String [] pathToItem = item[0];
|
||||
String expectedUrl = item[1][0];
|
||||
|
||||
if (skipItemURL(expectedUrl)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
expectedTabCount++;
|
||||
|
||||
// Set up listeners to catch the page load we're about to do
|
||||
@ -90,4 +99,11 @@ public class testSystemPages extends PixelTest {
|
||||
verifyTabCount(expectedTabCount);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean skipItemURL(String item) {
|
||||
if (StringHelper.ABOUT_PASSWORDS_URL.equals(item) && !AppConstants.NIGHTLY_BUILD) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -35,27 +35,6 @@ let Reader = {
|
||||
mm.broadcastAsyncMessage("Reader:Removed", { url: aData });
|
||||
break;
|
||||
}
|
||||
case "Gesture:DoubleTap": {
|
||||
// Ideally, we would just do this all with web APIs in AboutReader.jsm (bug 1118487)
|
||||
if (!BrowserApp.selectedBrowser.currentURI.spec.startsWith("about:reader")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let win = BrowserApp.selectedBrowser.contentWindow;
|
||||
let scrollBy;
|
||||
// Arbitrary choice of innerHeight (50) to give some context after scroll.
|
||||
if (JSON.parse(aData).y < (win.innerHeight / 2)) {
|
||||
scrollBy = - win.innerHeight + 50;
|
||||
} else {
|
||||
scrollBy = win.innerHeight - 50;
|
||||
}
|
||||
|
||||
let viewport = BrowserApp.selectedTab.getViewport();
|
||||
let newY = Math.min(Math.max(viewport.cssY + scrollBy, viewport.cssPageTop), viewport.cssPageBottom);
|
||||
let newRect = new Rect(viewport.cssX, newY, viewport.cssWidth, viewport.cssHeight);
|
||||
ZoomHelper.zoomToRect(newRect, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -171,7 +150,7 @@ let Reader = {
|
||||
let browser = tab.browser;
|
||||
if (browser.currentURI.spec.startsWith("about:reader")) {
|
||||
this.pageAction.id = PageActions.add({
|
||||
title: Strings.browser.GetStringFromName("readerView.exit"),
|
||||
title: Strings.reader.GetStringFromName("readerView.close"),
|
||||
icon: "drawable://reader_active",
|
||||
clickCallback: () => this.pageAction.readerModeCallback(tab.id),
|
||||
important: true
|
||||
@ -188,7 +167,7 @@ let Reader = {
|
||||
|
||||
if (browser.isArticle) {
|
||||
this.pageAction.id = PageActions.add({
|
||||
title: Strings.browser.GetStringFromName("readerView.enter"),
|
||||
title: Strings.reader.GetStringFromName("readerView.enter"),
|
||||
icon: "drawable://reader",
|
||||
clickCallback: () => this.pageAction.readerModeCallback(tab.id),
|
||||
longClickCallback: () => this.pageAction.readerModeActiveCallback(tab.id),
|
||||
|
@ -256,7 +256,7 @@ let Passwords = {
|
||||
},
|
||||
|
||||
_filter: function(event) {
|
||||
let value = event.target.value;
|
||||
let value = event.target.value.toLowerCase();
|
||||
let logins = this._logins.filter((login) => {
|
||||
if (login.hostname.toLowerCase().indexOf(value) != -1) {
|
||||
return true;
|
||||
|
@ -146,7 +146,7 @@ let lazilyLoadedObserverScripts = [
|
||||
["Feedback", ["Feedback:Show"], "chrome://browser/content/Feedback.js"],
|
||||
["SelectionHandler", ["TextSelection:Get"], "chrome://browser/content/SelectionHandler.js"],
|
||||
["EmbedRT", ["GeckoView:ImportScript"], "chrome://browser/content/EmbedRT.js"],
|
||||
["Reader", ["Reader:FetchContent", "Reader:Removed", "Gesture:DoubleTap"], "chrome://browser/content/Reader.js"],
|
||||
["Reader", ["Reader:FetchContent", "Reader:Removed"], "chrome://browser/content/Reader.js"],
|
||||
];
|
||||
if (AppConstants.MOZ_WEBRTC) {
|
||||
lazilyLoadedObserverScripts.push(
|
||||
@ -323,6 +323,7 @@ let Strings = {
|
||||
init: function () {
|
||||
XPCOMUtils.defineLazyGetter(Strings, "brand", () => Services.strings.createBundle("chrome://branding/locale/brand.properties"));
|
||||
XPCOMUtils.defineLazyGetter(Strings, "browser", () => Services.strings.createBundle("chrome://browser/locale/browser.properties"));
|
||||
XPCOMUtils.defineLazyGetter(Strings, "reader", () => Services.strings.createBundle("chrome://global/locale/aboutReader.properties"));
|
||||
},
|
||||
|
||||
flush: function () {
|
||||
|
@ -10,6 +10,16 @@ const Cr = Components.results;
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
/* Constants for password prompt telemetry.
|
||||
* Mirrored in nsLoginManagerPrompter.js */
|
||||
const PROMPT_DISPLAYED = 0;
|
||||
|
||||
const PROMPT_ADD = 1;
|
||||
const PROMPT_NOTNOW = 2;
|
||||
const PROMPT_NEVER = 3;
|
||||
|
||||
const PROMPT_UPDATE = 1;
|
||||
|
||||
/* ==================== LoginManagerPrompter ==================== */
|
||||
/*
|
||||
* LoginManagerPrompter
|
||||
@ -118,6 +128,7 @@ LoginManagerPrompter.prototype = {
|
||||
*/
|
||||
promptToSavePassword : function (aLogin) {
|
||||
this._showSaveLoginNotification(aLogin);
|
||||
Services.telemetry.getHistogramById("PWMGR_PROMPT_REMEMBER_ACTION").add(PROMPT_DISPLAYED);
|
||||
},
|
||||
|
||||
|
||||
@ -175,17 +186,20 @@ LoginManagerPrompter.prototype = {
|
||||
// in scope here; set one to |this._pwmgr| so we can get back to pwmgr
|
||||
// without a getService() call.
|
||||
var pwmgr = this._pwmgr;
|
||||
let promptHistogram = Services.telemetry.getHistogramById("PWMGR_PROMPT_REMEMBER_ACTION");
|
||||
|
||||
var buttons = [
|
||||
{
|
||||
label: this._getLocalizedString("saveButton"),
|
||||
callback: function() {
|
||||
pwmgr.addLogin(aLogin);
|
||||
promptHistogram.add(PROMPT_ADD);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: this._getLocalizedString("dontSaveButton"),
|
||||
callback: function() {
|
||||
promptHistogram.add(PROMPT_NOTNOW);
|
||||
// Don't set a permanent exception
|
||||
}
|
||||
}
|
||||
@ -204,6 +218,7 @@ LoginManagerPrompter.prototype = {
|
||||
*/
|
||||
promptToChangePassword : function (aOldLogin, aNewLogin) {
|
||||
this._showChangeLoginNotification(aOldLogin, aNewLogin.password);
|
||||
Services.telemetry.getHistogramById("PWMGR_PROMPT_UPDATE_ACTION").add(PROMPT_DISPLAYED);
|
||||
},
|
||||
|
||||
/*
|
||||
@ -225,17 +240,20 @@ LoginManagerPrompter.prototype = {
|
||||
// in scope here; set one to |this._pwmgr| so we can get back to pwmgr
|
||||
// without a getService() call.
|
||||
var self = this;
|
||||
let promptHistogram = Services.telemetry.getHistogramById("PWMGR_PROMPT_UPDATE_ACTION");
|
||||
|
||||
var buttons = [
|
||||
{
|
||||
label: this._getLocalizedString("updateButton"),
|
||||
callback: function() {
|
||||
self._updateLogin(aOldLogin, aNewPassword);
|
||||
promptHistogram.add(PROMPT_UPDATE);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: this._getLocalizedString("dontUpdateButton"),
|
||||
callback: function() {
|
||||
promptHistogram.add(PROMPT_NOTNOW);
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
@ -361,10 +361,6 @@ getUserMedia.sharingCamera.message2 = Camera is on
|
||||
getUserMedia.sharingMicrophone.message2 = Microphone is on
|
||||
getUserMedia.sharingCameraAndMicrophone.message2 = Camera and microphone are on
|
||||
|
||||
#Reader view
|
||||
readerView.enter = Enter Reader View
|
||||
readerView.exit = Exit Reader View
|
||||
|
||||
# LOCALIZATION NOTE (readerMode.toolbarTip):
|
||||
# Tip shown to users the first time we hide the reader mode toolbar.
|
||||
readerMode.toolbarTip=Tap the screen to show reader options
|
||||
|
@ -190,6 +190,7 @@
|
||||
<string name="fxaccount_status_sync_now">&fxaccount_status_sync_now;</string>
|
||||
<string name="fxaccount_status_syncing">&fxaccount_status_syncing2;</string>
|
||||
<string name="fxaccount_status_last_synced">&remote_tabs_last_synced;</string>
|
||||
<string name="fxaccount_status_never_synced">&remote_tabs_never_synced;</string>
|
||||
<string name="fxaccount_status_device_name">&fxaccount_status_device_name;</string>
|
||||
<string name="fxaccount_status_sync_server">&fxaccount_status_sync_server;</string>
|
||||
<string name="fxaccount_status_sync">&fxaccount_status_sync;</string>
|
||||
|
@ -4,6 +4,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/.
|
||||
|
||||
with Files('**/Makefile.in'):
|
||||
BUG_COMPONENT = ('Core', 'Build Config')
|
||||
FINAL = True
|
||||
|
||||
CONFIGURE_SUBST_FILES += [
|
||||
'config/autoconf.mk',
|
||||
'config/emptyvars.mk',
|
||||
@ -66,7 +70,7 @@ if CONFIG['COMPILE_ENVIRONMENT'] and not CONFIG['LIBXUL_SDK']:
|
||||
DIRS += ['config/external/icu']
|
||||
DIRS += ['js/src']
|
||||
|
||||
if not CONFIG['JS_STANDALONE']:
|
||||
if not CONFIG['JS_STANDALONE'] and CONFIG['MOZ_BUILD_APP']:
|
||||
# Bring in the configuration for the configured application.
|
||||
include('/' + CONFIG['MOZ_BUILD_APP'] + '/app.mozbuild')
|
||||
|
||||
|
@ -33,7 +33,8 @@ LOCAL_INCLUDES += [
|
||||
]
|
||||
|
||||
protocols = CONFIG['NECKO_PROTOCOLS'].copy()
|
||||
protocols.remove("about")
|
||||
if 'about' in protocols:
|
||||
protocols.remove('about')
|
||||
LOCAL_INCLUDES += sorted([
|
||||
'/netwerk/protocol/%s' % d for d in protocols
|
||||
])
|
||||
|
@ -4,6 +4,12 @@
|
||||
# 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/.
|
||||
|
||||
with Files('mach/**'):
|
||||
BUG_COMPONENT = ('Core', 'mach')
|
||||
|
||||
with Files('mozbuild/**'):
|
||||
BUG_COMPONENT = ('Core', 'Build Config')
|
||||
|
||||
SPHINX_PYTHON_PACKAGE_DIRS += [
|
||||
'mach',
|
||||
'mozbuild/mozbuild',
|
||||
|
@ -29,21 +29,41 @@ from mach.decorators import (
|
||||
class MachCommands(MachCommandBase):
|
||||
@Command('ide', category='devenv',
|
||||
description='Generate a project and launch an IDE.')
|
||||
@CommandArgument('ide', choices=['eclipse', 'visualstudio'])
|
||||
@CommandArgument('ide', choices=['eclipse', 'visualstudio', 'androidstudio', 'intellij'])
|
||||
@CommandArgument('args', nargs=argparse.REMAINDER)
|
||||
def eclipse(self, ide, args):
|
||||
if ide == 'eclipse':
|
||||
backend = 'CppEclipse'
|
||||
elif ide == 'visualstudio':
|
||||
backend = 'VisualStudio'
|
||||
elif ide == 'androidstudio' or ide == 'intellij':
|
||||
# The build backend for Android Studio and IntelliJ is just the regular one.
|
||||
backend = 'RecursiveMake'
|
||||
|
||||
if backend == 'CppEclipse':
|
||||
if ide == 'eclipse':
|
||||
try:
|
||||
which.which('eclipse')
|
||||
except which.WhichError:
|
||||
print('Eclipse CDT 8.4 or later must be installed in your PATH.')
|
||||
print('Download: http://www.eclipse.org/cdt/downloads.php')
|
||||
return 1
|
||||
elif ide == 'androidstudio' or ide =='intellij':
|
||||
studio = ['studio'] if ide == 'androidstudio' else ['idea']
|
||||
if sys.platform != 'darwin':
|
||||
try:
|
||||
which.which(studio[0])
|
||||
except:
|
||||
self.print_ide_error(ide)
|
||||
return 1
|
||||
else:
|
||||
# In order of preference!
|
||||
for d in self.get_mac_ide_preferences(ide):
|
||||
if os.path.isdir(d):
|
||||
studio = ['open', '-a', d]
|
||||
break
|
||||
else:
|
||||
print('Android Studio or IntelliJ IDEA 14 is not installed in /Applications.')
|
||||
return 1
|
||||
|
||||
# Here we refresh the whole build. 'build export' is sufficient here and is probably more
|
||||
# correct but it's also nice having a single target to get a fully built and indexed
|
||||
@ -52,20 +72,36 @@ class MachCommands(MachCommandBase):
|
||||
if res != 0:
|
||||
return 1
|
||||
|
||||
# Generate or refresh the eclipse workspace
|
||||
python = self.virtualenv_manager.python_path
|
||||
config_status = os.path.join(self.topobjdir, 'config.status')
|
||||
args = [python, config_status, '--backend=%s' % backend]
|
||||
res = self._run_command_in_objdir(args=args, pass_thru=True, ensure_exit_code=False)
|
||||
if res != 0:
|
||||
return 1
|
||||
if ide == 'androidstudio' or 'intellij':
|
||||
res = self._mach_context.commands.dispatch('package', self._mach_context)
|
||||
if res != 0:
|
||||
return 1
|
||||
res = self._mach_context.commands.dispatch('gradle-install', self._mach_context)
|
||||
if res != 0:
|
||||
return 1
|
||||
else:
|
||||
# Generate or refresh the IDE backend.
|
||||
python = self.virtualenv_manager.python_path
|
||||
config_status = os.path.join(self.topobjdir, 'config.status')
|
||||
args = [python, config_status, '--backend=%s' % backend]
|
||||
res = self._run_command_in_objdir(args=args, pass_thru=True, ensure_exit_code=False)
|
||||
if res != 0:
|
||||
return 1
|
||||
|
||||
if backend == 'CppEclipse':
|
||||
|
||||
if ide == 'eclipse':
|
||||
eclipse_workspace_dir = self.get_eclipse_workspace_path()
|
||||
process = subprocess.check_call(['eclipse', '-data', eclipse_workspace_dir])
|
||||
elif backend == 'VisualStudio':
|
||||
elif ide == 'visualstudio':
|
||||
visual_studio_workspace_dir = self.get_visualstudio_workspace_path()
|
||||
process = subprocess.check_call(['explorer.exe', visual_studio_workspace_dir])
|
||||
elif ide == 'androidstudio' or ide == 'intellij':
|
||||
gradle_dir = None
|
||||
if self.is_gradle_project_already_imported():
|
||||
gradle_dir = self.get_gradle_project_path()
|
||||
else:
|
||||
gradle_dir = self.get_gradle_import_path()
|
||||
process = subprocess.check_call(studio + [gradle_dir])
|
||||
|
||||
def get_eclipse_workspace_path(self):
|
||||
return CppEclipseBackend.get_workspace_path(self.topsrcdir, self.topobjdir)
|
||||
@ -73,3 +109,31 @@ class MachCommands(MachCommandBase):
|
||||
def get_visualstudio_workspace_path(self):
|
||||
return os.path.join(self.topobjdir, 'msvc', 'mozilla.sln')
|
||||
|
||||
def get_gradle_project_path(self):
|
||||
return os.path.join(self.topobjdir, 'mobile', 'android', 'gradle')
|
||||
|
||||
def get_gradle_import_path(self):
|
||||
return os.path.join(self.get_gradle_project_path(), 'build.gradle')
|
||||
|
||||
def is_gradle_project_already_imported(self):
|
||||
gradle_project_path = os.path.join(self.get_gradle_project_path(), '.idea')
|
||||
return os.path.exists(gradle_project_path)
|
||||
|
||||
def get_mac_ide_preferences(self, ide):
|
||||
if sys.platform == 'darwin':
|
||||
if ide == 'androidstudio':
|
||||
return ['/Applications/Android Studio.app']
|
||||
else:
|
||||
return [
|
||||
'/Applications/IntelliJ IDEA 14 EAP.app',
|
||||
'/Applications/IntelliJ IDEA 14.app',
|
||||
'/Applications/IntelliJ IDEA 14 CE EAP.app',
|
||||
'/Applications/IntelliJ IDEA 14 CE.app']
|
||||
|
||||
def print_ide_error(self, ide):
|
||||
if ide == 'androidstudio':
|
||||
print('Android Studio is not installed in your PATH.')
|
||||
print('You can generate a command-line launcher from Android Studio->Tools->Create Command-line launcher with script name \'studio\'')
|
||||
elif ide == 'intellij':
|
||||
print('IntelliJ is not installed in your PATH.')
|
||||
print('You can generate a command-line launcher from IntelliJ IDEA->Tools->Create Command-line launcher with script name \'idea\'')
|
||||
|
@ -19,7 +19,6 @@ from __future__ import unicode_literals
|
||||
import os
|
||||
|
||||
from collections import OrderedDict
|
||||
from contextlib import contextmanager
|
||||
from mozbuild.util import (
|
||||
HierarchicalStringList,
|
||||
HierarchicalStringListWithFlagsFactory,
|
||||
@ -31,6 +30,7 @@ from mozbuild.util import (
|
||||
StrictOrderingOnAppendList,
|
||||
StrictOrderingOnAppendListWithFlagsFactory,
|
||||
TypedList,
|
||||
TypedNamedTuple,
|
||||
)
|
||||
import mozpack.path as mozpath
|
||||
from types import FunctionType
|
||||
@ -167,7 +167,6 @@ class Context(KeyedDefaultDict):
|
||||
|
||||
def _factory(self, key):
|
||||
"""Function called when requesting a missing key."""
|
||||
|
||||
defaults = self._allowed_variables.get(key)
|
||||
if not defaults:
|
||||
raise KeyError('global_ns', 'get_unknown', key)
|
||||
@ -396,6 +395,108 @@ def ContextDerivedTypedList(type, base_class=List):
|
||||
return _TypedList
|
||||
|
||||
|
||||
BugzillaComponent = TypedNamedTuple('BugzillaComponent',
|
||||
[('product', unicode), ('component', unicode)])
|
||||
|
||||
|
||||
class Files(SubContext):
|
||||
"""Metadata attached to files.
|
||||
|
||||
It is common to want to annotate files with metadata, such as which
|
||||
Bugzilla component tracks issues with certain files. This sub-context is
|
||||
where we stick that metadata.
|
||||
|
||||
The argument to this sub-context is a file matching pattern that is applied
|
||||
against the host file's directory. If the pattern matches a file whose info
|
||||
is currently being sought, the metadata attached to this instance will be
|
||||
applied to that file.
|
||||
|
||||
Patterns are collections of filename characters with ``/`` used as the
|
||||
directory separate (UNIX-style paths) and ``*`` and ``**`` used to denote
|
||||
wildcard matching.
|
||||
|
||||
Patterns without the ``*`` character are literal matches and will match at
|
||||
most one entity.
|
||||
|
||||
Patterns with ``*`` or ``**`` are wildcard matches. ``*`` matches files
|
||||
within a single directory. ``**`` matches files across several directories.
|
||||
Here are some examples:
|
||||
|
||||
``foo.html``
|
||||
Will match only the ``foo.html`` file in the current directory.
|
||||
``*.jsm``
|
||||
Will match all ``.jsm`` files in the current directory.
|
||||
``**/*.cpp``
|
||||
Will match all ``.cpp`` files in this and all child directories.
|
||||
``foo/*.css``
|
||||
Will match all ``.css`` files in the ``foo/`` directory.
|
||||
``bar/*``
|
||||
Will match all files in the ``bar/`` directory but not any files in
|
||||
child directories of ``bar/``, such as ``bar/dir1/baz``.
|
||||
``baz/**``
|
||||
Will match all files in the ``baz/`` directory and all directories
|
||||
underneath.
|
||||
"""
|
||||
|
||||
VARIABLES = {
|
||||
'BUG_COMPONENT': (BugzillaComponent, tuple,
|
||||
"""The bug component that tracks changes to these files.
|
||||
|
||||
Values are a 2-tuple of unicode describing the Bugzilla product and
|
||||
component. e.g. ``('Core', 'Build Config')``.
|
||||
""", None),
|
||||
|
||||
'FINAL': (bool, bool,
|
||||
"""Mark variable assignments as finalized.
|
||||
|
||||
During normal processing, values from newer Files contexts
|
||||
overwrite previously set values. Last write wins. This behavior is
|
||||
not always desired. ``FINAL`` provides a mechanism to prevent
|
||||
further updates to a variable.
|
||||
|
||||
When ``FINAL`` is set, the value of all variables defined in this
|
||||
context are marked as frozen and all subsequent writes to them
|
||||
are ignored during metadata reading.
|
||||
|
||||
See :ref:`mozbuild_files_metadata_finalizing` for more info.
|
||||
""", None),
|
||||
}
|
||||
|
||||
def __init__(self, parent, pattern=None):
|
||||
super(Files, self).__init__(parent)
|
||||
self.pattern = pattern
|
||||
self.finalized = set()
|
||||
|
||||
def __iadd__(self, other):
|
||||
assert isinstance(other, Files)
|
||||
|
||||
for k, v in other.items():
|
||||
# Ignore updates to finalized flags.
|
||||
if k in self.finalized:
|
||||
continue
|
||||
|
||||
# Only finalize variables defined in this instance.
|
||||
if k == 'FINAL':
|
||||
self.finalized |= set(other) - {'FINAL'}
|
||||
continue
|
||||
|
||||
self[k] = v
|
||||
|
||||
return self
|
||||
|
||||
def asdict(self):
|
||||
"""Return this instance as a dict with built-in data structures.
|
||||
|
||||
Call this to obtain an object suitable for serializing.
|
||||
"""
|
||||
d = {}
|
||||
if 'BUG_COMPONENT' in self:
|
||||
bc = self['BUG_COMPONENT']
|
||||
d['bug_component'] = (bc.product, bc.component)
|
||||
|
||||
return d
|
||||
|
||||
|
||||
# This defines functions that create sub-contexts.
|
||||
#
|
||||
# Values are classes that are SubContexts. The class name will be turned into
|
||||
@ -405,6 +506,7 @@ def ContextDerivedTypedList(type, base_class=List):
|
||||
# argument is always the parent context. It is up to each class to perform
|
||||
# argument validation.
|
||||
SUBCONTEXTS = [
|
||||
Files,
|
||||
]
|
||||
|
||||
for cls in SUBCONTEXTS:
|
||||
|
@ -74,7 +74,10 @@ from .data import (
|
||||
|
||||
from .reader import SandboxValidationError
|
||||
|
||||
from .context import Context
|
||||
from .context import (
|
||||
Context,
|
||||
SubContext,
|
||||
)
|
||||
|
||||
|
||||
class TreeMetadataEmitter(LoggingMixin):
|
||||
@ -135,6 +138,11 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
raise Exception('Unhandled object of type %s' % type(o))
|
||||
|
||||
for out in output:
|
||||
# Nothing in sub-contexts is currently of interest to us. Filter
|
||||
# them all out.
|
||||
if isinstance(out, SubContext):
|
||||
continue
|
||||
|
||||
if isinstance(out, Context):
|
||||
# Keep all contexts around, we will need them later.
|
||||
contexts[out.objdir] = out
|
||||
|
@ -4,13 +4,17 @@
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from mach.decorators import (
|
||||
CommandArgument,
|
||||
CommandProvider,
|
||||
Command
|
||||
Command,
|
||||
SubCommand,
|
||||
)
|
||||
|
||||
from mozbuild.base import MachCommandBase
|
||||
import mozpack.path as mozpath
|
||||
|
||||
|
||||
@CommandProvider
|
||||
@ -72,3 +76,49 @@ class MozbuildFileCommands(MachCommandBase):
|
||||
print(line)
|
||||
|
||||
return 0
|
||||
|
||||
@Command('file-info', category='build-dev',
|
||||
description='Query for metadata about files.')
|
||||
def file_info(self):
|
||||
pass
|
||||
|
||||
@SubCommand('file-info', 'bugzilla-component',
|
||||
'Show Bugzilla component info for files listed.')
|
||||
@CommandArgument('paths', nargs='+',
|
||||
help='Paths whose data to query')
|
||||
def file_info_bugzilla(self, paths):
|
||||
components = defaultdict(set)
|
||||
for p, m in self._get_files_info(paths).items():
|
||||
components[m.get('BUG_COMPONENT')].add(p)
|
||||
|
||||
for component, files in sorted(components.items(), key=lambda x: (x is None, x)):
|
||||
print('%s :: %s' % (component.product, component.component) if component else 'UNKNOWN')
|
||||
for f in sorted(files):
|
||||
print(' %s' % f)
|
||||
|
||||
@SubCommand('file-info', 'missing-bugzilla',
|
||||
'Show files missing Bugzilla component info')
|
||||
@CommandArgument('paths', nargs='+',
|
||||
help='Paths whose data to query')
|
||||
def file_info_missing_bugzilla(self, paths):
|
||||
for p, m in sorted(self._get_files_info(paths).items()):
|
||||
if 'BUG_COMPONENT' not in m:
|
||||
print(p)
|
||||
|
||||
def _get_reader(self):
|
||||
from mozbuild.frontend.reader import BuildReader
|
||||
config = self.config_environment
|
||||
return BuildReader(config)
|
||||
|
||||
def _get_files_info(self, paths):
|
||||
relpaths = []
|
||||
for p in paths:
|
||||
a = mozpath.abspath(p)
|
||||
if not mozpath.basedir(a, [self.topsrcdir]):
|
||||
print('path is not inside topsrcdir: %s' % p)
|
||||
return 1
|
||||
|
||||
relpaths.append(mozpath.relpath(a, self.topsrcdir))
|
||||
|
||||
reader = self._get_reader()
|
||||
return reader.files_info(relpaths)
|
||||
|
@ -29,10 +29,14 @@ import tokenize
|
||||
import traceback
|
||||
import types
|
||||
|
||||
from collections import OrderedDict
|
||||
from collections import (
|
||||
defaultdict,
|
||||
OrderedDict,
|
||||
)
|
||||
from io import StringIO
|
||||
|
||||
from mozbuild.util import (
|
||||
EmptyValue,
|
||||
memoize,
|
||||
ReadOnlyDefaultDict,
|
||||
ReadOnlyDict,
|
||||
@ -58,11 +62,13 @@ from .sandbox import (
|
||||
from .context import (
|
||||
Context,
|
||||
ContextDerivedValue,
|
||||
Files,
|
||||
FUNCTIONS,
|
||||
VARIABLES,
|
||||
DEPRECATION_HINTS,
|
||||
SPECIAL_VARIABLES,
|
||||
SUBCONTEXTS,
|
||||
SubContext,
|
||||
TemplateContext,
|
||||
)
|
||||
|
||||
@ -78,6 +84,48 @@ def log(logger, level, action, params, formatter):
|
||||
logger.log(level, formatter, extra={'action': action, 'params': params})
|
||||
|
||||
|
||||
class EmptyConfig(object):
|
||||
"""A config object that is empty.
|
||||
|
||||
This config object is suitable for using with a BuildReader on a vanilla
|
||||
checkout, without any existing configuration. The config is simply
|
||||
bootstrapped from a top source directory path.
|
||||
"""
|
||||
class PopulateOnGetDict(ReadOnlyDefaultDict):
|
||||
"""A variation on ReadOnlyDefaultDict that populates during .get().
|
||||
|
||||
This variation is needed because CONFIG uses .get() to access members.
|
||||
Without it, None (instead of our EmptyValue types) would be returned.
|
||||
"""
|
||||
def get(self, key, default=None):
|
||||
return self[key]
|
||||
|
||||
def __init__(self, topsrcdir):
|
||||
self.topsrcdir = topsrcdir
|
||||
self.topobjdir = ''
|
||||
|
||||
self.substs = self.PopulateOnGetDict(EmptyValue, {
|
||||
# These 2 variables are used semi-frequently and it isn't worth
|
||||
# changing all the instances.
|
||||
b'MOZ_APP_NAME': b'empty',
|
||||
b'MOZ_CHILD_PROCESS_NAME': b'empty',
|
||||
# Set manipulations are performed within the moz.build files. But
|
||||
# set() is not an exposed symbol, so we can't create an empty set.
|
||||
b'NECKO_PROTOCOLS': set(),
|
||||
# Needed to prevent js/src's config.status from loading.
|
||||
b'JS_STANDALONE': b'1',
|
||||
})
|
||||
udict = {}
|
||||
for k, v in self.substs.items():
|
||||
if isinstance(v, str):
|
||||
udict[k.decode('utf-8')] = v.decode('utf-8')
|
||||
else:
|
||||
udict[k] = v
|
||||
self.substs_unicode = self.PopulateOnGetDict(EmptyValue, udict)
|
||||
self.defines = self.substs
|
||||
self.external_source_dir = None
|
||||
|
||||
|
||||
def is_read_allowed(path, config):
|
||||
"""Whether we are allowed to load a mozbuild file at the specified path.
|
||||
|
||||
@ -135,20 +183,25 @@ class MozbuildSandbox(Sandbox):
|
||||
self.exports = set(exports.keys())
|
||||
context.update(exports)
|
||||
self.templates = self.metadata.setdefault('templates', {})
|
||||
self.special_variables = self.metadata.setdefault('special_variables',
|
||||
SPECIAL_VARIABLES)
|
||||
self.functions = self.metadata.setdefault('functions', FUNCTIONS)
|
||||
self.subcontext_types = self.metadata.setdefault('subcontexts',
|
||||
SUBCONTEXTS)
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key in SPECIAL_VARIABLES:
|
||||
return SPECIAL_VARIABLES[key][0](self._context)
|
||||
if key in FUNCTIONS:
|
||||
return self._create_function(FUNCTIONS[key])
|
||||
if key in SUBCONTEXTS:
|
||||
return self._create_subcontext(SUBCONTEXTS[key])
|
||||
if key in self.special_variables:
|
||||
return self.special_variables[key][0](self._context)
|
||||
if key in self.functions:
|
||||
return self._create_function(self.functions[key])
|
||||
if key in self.subcontext_types:
|
||||
return self._create_subcontext(self.subcontext_types[key])
|
||||
if key in self.templates:
|
||||
return self._create_template_function(self.templates[key])
|
||||
return Sandbox.__getitem__(self, key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if key in SPECIAL_VARIABLES or key in FUNCTIONS or key in SUBCONTEXTS:
|
||||
if key in self.special_variables or key in self.functions or key in self.subcontext_types:
|
||||
raise KeyError()
|
||||
if key in self.exports:
|
||||
self._context[key] = value
|
||||
@ -356,12 +409,20 @@ class MozbuildSandbox(Sandbox):
|
||||
func, code, path = template
|
||||
|
||||
def template_function(*args, **kwargs):
|
||||
context = TemplateContext(VARIABLES, self._context.config)
|
||||
context = TemplateContext(self._context._allowed_variables,
|
||||
self._context.config)
|
||||
context.add_source(self._context.current_path)
|
||||
for p in self._context.all_paths:
|
||||
context.add_source(p)
|
||||
|
||||
sandbox = MozbuildSandbox(context, {
|
||||
sandbox = MozbuildSandbox(context, metadata={
|
||||
# We should arguably set these defaults to something else.
|
||||
# Templates, for example, should arguably come from the state
|
||||
# of the sandbox from when the template was declared, not when
|
||||
# it was instantiated. Bug 1137319.
|
||||
'functions': self.metadata.get('functions', {}),
|
||||
'special_variables': self.metadata.get('special_variables', {}),
|
||||
'subcontexts': self.metadata.get('subcontexts', {}),
|
||||
'templates': self.metadata.get('templates', {})
|
||||
})
|
||||
for k, v in inspect.getcallargs(func, *args, **kwargs).items():
|
||||
@ -972,6 +1033,11 @@ class BuildReader(object):
|
||||
sandbox.exec_file(path)
|
||||
context.execution_time = time.time() - time_start
|
||||
|
||||
# Yield main context before doing any processing. This gives immediate
|
||||
# consumers an opportunity to change state before our remaining
|
||||
# processing is performed.
|
||||
yield context
|
||||
|
||||
# We first collect directories populated in variables.
|
||||
dir_vars = ['DIRS']
|
||||
|
||||
@ -1016,8 +1082,6 @@ class BuildReader(object):
|
||||
context['DIRS'].append(mozpath.relpath(gyp_context.objdir, context.objdir))
|
||||
sandbox.subcontexts.append(gyp_context)
|
||||
|
||||
yield context
|
||||
|
||||
for subcontext in sandbox.subcontexts:
|
||||
yield subcontext
|
||||
|
||||
@ -1035,12 +1099,11 @@ class BuildReader(object):
|
||||
mozpath.relpath(d, context.srcdir), var), context)
|
||||
|
||||
recurse_info[d] = {}
|
||||
if 'templates' in sandbox.metadata:
|
||||
recurse_info[d]['templates'] = dict(
|
||||
sandbox.metadata['templates'])
|
||||
if 'exports' in sandbox.metadata:
|
||||
sandbox.recompute_exports()
|
||||
recurse_info[d]['exports'] = dict(sandbox.metadata['exports'])
|
||||
for key in sandbox.metadata:
|
||||
if key == 'exports':
|
||||
sandbox.recompute_exports()
|
||||
|
||||
recurse_info[d][key] = dict(sandbox.metadata[key])
|
||||
|
||||
for path, child_metadata in recurse_info.items():
|
||||
child_path = path.join('moz.build')
|
||||
@ -1062,3 +1125,159 @@ class BuildReader(object):
|
||||
yield res
|
||||
|
||||
self._execution_stack.pop()
|
||||
|
||||
def _find_relevant_mozbuilds(self, paths):
|
||||
"""Given a set of filesystem paths, find all relevant moz.build files.
|
||||
|
||||
We assume that a moz.build file in the directory ancestry of a given path
|
||||
is relevant to that path. Let's say we have the following files on disk::
|
||||
|
||||
moz.build
|
||||
foo/moz.build
|
||||
foo/baz/moz.build
|
||||
foo/baz/file1
|
||||
other/moz.build
|
||||
other/file2
|
||||
|
||||
If ``foo/baz/file1`` is passed in, the relevant moz.build files are
|
||||
``moz.build``, ``foo/moz.build``, and ``foo/baz/moz.build``. For
|
||||
``other/file2``, the relevant moz.build files are ``moz.build`` and
|
||||
``other/moz.build``.
|
||||
|
||||
Returns a dict of input paths to a list of relevant moz.build files.
|
||||
The root moz.build file is first and the leaf-most moz.build is last.
|
||||
"""
|
||||
root = self.config.topsrcdir
|
||||
result = {}
|
||||
|
||||
@memoize
|
||||
def exists(path):
|
||||
return os.path.exists(path)
|
||||
|
||||
def itermozbuild(path):
|
||||
subpath = ''
|
||||
yield 'moz.build'
|
||||
for part in mozpath.split(path):
|
||||
subpath = mozpath.join(subpath, part)
|
||||
yield mozpath.join(subpath, 'moz.build')
|
||||
|
||||
for path in sorted(paths):
|
||||
path = mozpath.normpath(path)
|
||||
if os.path.isabs(path):
|
||||
if not mozpath.basedir(path, [root]):
|
||||
raise Exception('Path outside topsrcdir: %s' % path)
|
||||
path = mozpath.relpath(path, root)
|
||||
|
||||
result[path] = [p for p in itermozbuild(path)
|
||||
if exists(mozpath.join(root, p))]
|
||||
|
||||
return result
|
||||
|
||||
def read_relevant_mozbuilds(self, paths):
|
||||
"""Read and process moz.build files relevant for a set of paths.
|
||||
|
||||
For an iterable of relative-to-root filesystem paths ``paths``,
|
||||
find all moz.build files that may apply to them based on filesystem
|
||||
hierarchy and read those moz.build files.
|
||||
|
||||
The return value is a 2-tuple. The first item is a dict mapping each
|
||||
input filesystem path to a list of Context instances that are relevant
|
||||
to that path. The second item is a list of all Context instances. Each
|
||||
Context instance is in both data structures.
|
||||
"""
|
||||
relevants = self._find_relevant_mozbuilds(paths)
|
||||
|
||||
topsrcdir = self.config.topsrcdir
|
||||
|
||||
# Source moz.build file to directories to traverse.
|
||||
dirs = defaultdict(set)
|
||||
# Relevant path to absolute paths of relevant contexts.
|
||||
path_mozbuilds = {}
|
||||
|
||||
# There is room to improve this code (and the code in
|
||||
# _find_relevant_mozbuilds) to better handle multiple files in the same
|
||||
# directory. Bug 1136966 tracks.
|
||||
for path, mbpaths in relevants.items():
|
||||
path_mozbuilds[path] = [mozpath.join(topsrcdir, p) for p in mbpaths]
|
||||
|
||||
for i, mbpath in enumerate(mbpaths[0:-1]):
|
||||
source_dir = mozpath.dirname(mbpath)
|
||||
target_dir = mozpath.dirname(mbpaths[i + 1])
|
||||
|
||||
d = mozpath.normpath(mozpath.join(topsrcdir, mbpath))
|
||||
dirs[d].add(mozpath.relpath(target_dir, source_dir))
|
||||
|
||||
# Exporting doesn't work reliably in tree traversal mode. Override
|
||||
# the function to no-op.
|
||||
functions = dict(FUNCTIONS)
|
||||
def export(sandbox):
|
||||
return lambda varname: None
|
||||
functions['export'] = tuple([export] + list(FUNCTIONS['export'][1:]))
|
||||
|
||||
metadata = {
|
||||
'functions': functions,
|
||||
}
|
||||
|
||||
contexts = defaultdict(list)
|
||||
all_contexts = []
|
||||
for context in self.read_mozbuild(mozpath.join(topsrcdir, 'moz.build'),
|
||||
self.config, metadata=metadata):
|
||||
# Explicitly set directory traversal variables to override default
|
||||
# traversal rules.
|
||||
if not isinstance(context, SubContext):
|
||||
for v in ('DIRS', 'GYP_DIRS', 'TEST_DIRS'):
|
||||
context[v][:] = []
|
||||
|
||||
context['DIRS'] = sorted(dirs[context.main_path])
|
||||
|
||||
contexts[context.main_path].append(context)
|
||||
all_contexts.append(context)
|
||||
|
||||
result = {}
|
||||
for path, paths in path_mozbuilds.items():
|
||||
result[path] = reduce(lambda x, y: x + y, (contexts[p] for p in paths), [])
|
||||
|
||||
return result, all_contexts
|
||||
|
||||
def files_info(self, paths):
|
||||
"""Obtain aggregate data from Files for a set of files.
|
||||
|
||||
Given a set of input paths, determine which moz.build files may
|
||||
define metadata for them, evaluate those moz.build files, and
|
||||
apply file metadata rules defined within to determine metadata
|
||||
values for each file requested.
|
||||
|
||||
Essentially, for each input path:
|
||||
|
||||
1. Determine the set of moz.build files relevant to that file by
|
||||
looking for moz.build files in ancestor directories.
|
||||
2. Evaluate moz.build files starting with the most distant.
|
||||
3. Iterate over Files sub-contexts.
|
||||
4. If the file pattern matches the file we're seeking info on,
|
||||
apply attribute updates.
|
||||
5. Return the most recent value of attributes.
|
||||
"""
|
||||
paths, _ = self.read_relevant_mozbuilds(paths)
|
||||
|
||||
r = {}
|
||||
|
||||
for path, ctxs in paths.items():
|
||||
flags = Files(Context())
|
||||
|
||||
for ctx in ctxs:
|
||||
if not isinstance(ctx, Files):
|
||||
continue
|
||||
|
||||
relpath = mozpath.relpath(path, ctx.relsrcdir)
|
||||
pattern = ctx.pattern
|
||||
|
||||
# Only do wildcard matching if the '*' character is present.
|
||||
# Otherwise, mozpath.match will match directories, which we've
|
||||
# arbitrarily chosen to not allow.
|
||||
if pattern == relpath or \
|
||||
('*' in pattern and mozpath.match(relpath, pattern)):
|
||||
flags += ctx
|
||||
|
||||
r[path] = flags
|
||||
|
||||
return r
|
||||
|
@ -0,0 +1,2 @@
|
||||
with Files('*'):
|
||||
BUG_COMPONENT = 'bad value'
|
@ -0,0 +1,4 @@
|
||||
with Files('*.jsm'):
|
||||
BUG_COMPONENT = ('Firefox', 'JS')
|
||||
with Files('*.cpp'):
|
||||
BUG_COMPONENT = ('Firefox', 'C++')
|
@ -0,0 +1,3 @@
|
||||
with Files('**/Makefile.in'):
|
||||
BUG_COMPONENT = ('Core', 'Build Config')
|
||||
FINAL = True
|
@ -0,0 +1,2 @@
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Another', 'Component')
|
@ -0,0 +1,2 @@
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('default_product', 'default_component')
|
@ -0,0 +1,2 @@
|
||||
with Files('*'):
|
||||
BUG_COMPONENT = ('Core', 'Build Config')
|
@ -0,0 +1,5 @@
|
||||
with Files('foo'):
|
||||
BUG_COMPONENT = ('FooProduct', 'FooComponent')
|
||||
|
||||
with Files('bar'):
|
||||
BUG_COMPONENT = ('BarProduct', 'BarComponent')
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user