Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2013-10-16 13:11:30 +02:00
Родитель 52e19b318b fd5be0de78
Коммит cfcb3551f1
166 изменённых файлов: 2299 добавлений и 1230 удалений

Просмотреть файл

@ -1,4 +1,4 @@
{ {
"revision": "e811ee9b89a2a4cbb789fb88e532113dc5105e2a", "revision": "36aa3e5d226a844b07b3e4b2219f54b549456ec1",
"repo_path": "/integration/gaia-central" "repo_path": "/integration/gaia-central"
} }

Просмотреть файл

@ -1082,9 +1082,10 @@ pref("devtools.toolbar.visible", false);
pref("devtools.gcli.allowSet", false); pref("devtools.gcli.allowSet", false);
pref("devtools.commands.dir", ""); pref("devtools.commands.dir", "");
// Disable the app manager // Enable the app manager
pref("devtools.appmanager.enabled", true); pref("devtools.appmanager.enabled", true);
pref("devtools.appmanager.firstrun", true); pref("devtools.appmanager.firstrun", true);
pref("devtools.appmanager.manifestEditor.enabled", false);
// Toolbox preferences // Toolbox preferences
pref("devtools.toolbox.footer.height", 250); pref("devtools.toolbox.footer.height", 250);

Просмотреть файл

@ -19,9 +19,9 @@ let gDataNotificationInfoBar = {
}, },
get _log() { get _log() {
let log4moz = Cu.import("resource://services-common/log4moz.js", {}).Log4Moz; let Log = Cu.import("resource://gre/modules/Log.jsm", {}).Log;
delete this._log; delete this._log;
return this._log = log4moz.repository.getLogger("Services.DataReporting.InfoBar"); return this._log = Log.repository.getLogger("Services.DataReporting.InfoBar");
}, },
init: function() { init: function() {

Просмотреть файл

@ -473,6 +473,9 @@ var PlacesCommandHook = {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// HistoryMenu //// HistoryMenu
XPCOMUtils.defineLazyModuleGetter(this, "RecentlyClosedTabsAndWindowsMenuUtils",
"resource:///modules/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm");
// View for the history menu. // View for the history menu.
function HistoryMenu(aPopupShowingEvent) { function HistoryMenu(aPopupShowingEvent) {
// Workaround for Bug 610187. The sidebar does not include all the Places // Workaround for Bug 610187. The sidebar does not include all the Places
@ -531,45 +534,8 @@ HistoryMenu.prototype = {
undoMenu.removeAttribute("disabled"); undoMenu.removeAttribute("disabled");
// populate menu // populate menu
var undoItems = JSON.parse(SessionStore.getClosedTabData(window)); let tabsFragment = RecentlyClosedTabsAndWindowsMenuUtils.getTabsFragment(window, "menuitem");
for (var i = 0; i < undoItems.length; i++) { undoPopup.appendChild(tabsFragment);
var m = document.createElement("menuitem");
m.setAttribute("label", undoItems[i].title);
if (undoItems[i].image) {
let iconURL = undoItems[i].image;
// don't initiate a connection just to fetch a favicon (see bug 467828)
if (/^https?:/.test(iconURL))
iconURL = "moz-anno:favicon:" + iconURL;
m.setAttribute("image", iconURL);
}
m.setAttribute("class", "menuitem-iconic bookmark-item menuitem-with-favicon");
m.setAttribute("value", i);
m.setAttribute("oncommand", "undoCloseTab(" + i + ");");
// Set the targetURI attribute so it will be shown in tooltip and trigger
// onLinkHovered. SessionStore uses one-based indexes, so we need to
// normalize them.
let tabData = undoItems[i].state;
let activeIndex = (tabData.index || tabData.entries.length) - 1;
if (activeIndex >= 0 && tabData.entries[activeIndex])
m.setAttribute("targetURI", tabData.entries[activeIndex].url);
m.addEventListener("click", this._undoCloseMiddleClick, false);
if (i == 0)
m.setAttribute("key", "key_undoCloseTab");
undoPopup.appendChild(m);
}
// "Restore All Tabs"
var strings = gNavigatorBundle;
undoPopup.appendChild(document.createElement("menuseparator"));
m = undoPopup.appendChild(document.createElement("menuitem"));
m.id = "menu_restoreAllTabs";
m.setAttribute("label", strings.getString("menuRestoreAllTabs.label"));
m.addEventListener("command", function() {
for (var i = 0; i < undoItems.length; i++)
undoCloseTab(0);
}, false);
}, },
toggleRecentlyClosedWindows: function PHM_toggleRecentlyClosedWindows() { toggleRecentlyClosedWindows: function PHM_toggleRecentlyClosedWindows() {
@ -607,45 +573,8 @@ HistoryMenu.prototype = {
undoMenu.removeAttribute("disabled"); undoMenu.removeAttribute("disabled");
// populate menu // populate menu
let undoItems = JSON.parse(SessionStore.getClosedWindowData()); let windowsFragment = RecentlyClosedTabsAndWindowsMenuUtils.getWindowsFragment(window, "menuitem");
for (let i = 0; i < undoItems.length; i++) { undoPopup.appendChild(windowsFragment);
let undoItem = undoItems[i];
let otherTabsCount = undoItem.tabs.length - 1;
let label = (otherTabsCount == 0) ? menuLabelStringSingleTab
: PluralForm.get(otherTabsCount, menuLabelString);
let menuLabel = label.replace("#1", undoItem.title)
.replace("#2", otherTabsCount);
let m = document.createElement("menuitem");
m.setAttribute("label", menuLabel);
let selectedTab = undoItem.tabs[undoItem.selected - 1];
if (selectedTab.image) {
let iconURL = selectedTab.image;
// don't initiate a connection just to fetch a favicon (see bug 467828)
if (/^https?:/.test(iconURL))
iconURL = "moz-anno:favicon:" + iconURL;
m.setAttribute("image", iconURL);
}
m.setAttribute("class", "menuitem-iconic bookmark-item menuitem-with-favicon");
m.setAttribute("oncommand", "undoCloseWindow(" + i + ");");
// Set the targetURI attribute so it will be shown in tooltip.
// SessionStore uses one-based indexes, so we need to normalize them.
let activeIndex = (selectedTab.index || selectedTab.entries.length) - 1;
if (activeIndex >= 0 && selectedTab.entries[activeIndex])
m.setAttribute("targetURI", selectedTab.entries[activeIndex].url);
if (i == 0)
m.setAttribute("key", "key_undoCloseWindow");
undoPopup.appendChild(m);
}
// "Open All in Windows"
undoPopup.appendChild(document.createElement("menuseparator"));
let m = undoPopup.appendChild(document.createElement("menuitem"));
m.id = "menu_restoreAllWindows";
m.setAttribute("label", gNavigatorBundle.getString("menuRestoreAllWindows.label"));
m.setAttribute("oncommand",
"for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
}, },
toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() { toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() {

Просмотреть файл

@ -7127,7 +7127,14 @@ function safeModeRestart()
let rv = Services.prompt.confirmEx(window, promptTitle, promptMessage, let rv = Services.prompt.confirmEx(window, promptTitle, promptMessage,
buttonFlags, restartText, null, null, buttonFlags, restartText, null, null,
null, {}); null, {});
if (rv == 0) { if (rv != 0)
return;
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
.createInstance(Ci.nsISupportsPRBool);
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
if (!cancelQuit.data) {
Services.startup.restartInSafeMode(Ci.nsIAppStartup.eAttemptQuit); Services.startup.restartInSafeMode(Ci.nsIAppStartup.eAttemptQuit);
} }
} }

Просмотреть файл

@ -1671,9 +1671,26 @@
throw new Error("Invalid argument: " + aCloseTabs); throw new Error("Invalid argument: " + aCloseTabs);
} }
if (tabsToClose <= 1 || let maxUndo =
aCloseTabs != this.closingTabsEnum.ALL || Services.prefs.getIntPref("browser.sessionstore.max_tabs_undo");
!Services.prefs.getBoolPref("browser.tabs.warnOnClose")) let warnOnCloseOtherTabs =
Services.prefs.getBoolPref("browser.tabs.warnOnCloseOtherTabs");
let warnOnCloseWindow =
Services.prefs.getBoolPref("browser.tabs.warnOnClose");
let isWindowClosing = aCloseTabs == this.closingTabsEnum.ALL;
let skipWarning =
// 1) If there is only one tab to close, we'll never warn the user.
tabsToClose <= 1 ||
// 2) If the whole window is going to be closed, don't warn the
// user if the user has browser.tabs.warnOnClose set to false.
(isWindowClosing && !warnOnCloseWindow) ||
// 3) If the number of tabs are less than the undo threshold
// or if the user has specifically opted-in to ignoring
// this warning via the warnOnCloseOtherTabs pref.
(!isWindowClosing && (!warnOnCloseOtherTabs ||
tabsToClose <= maxUndo));
if (skipWarning)
return true; return true;
var ps = Services.prompt; var ps = Services.prompt;
@ -1702,8 +1719,11 @@
var reallyClose = (buttonPressed == 0); var reallyClose = (buttonPressed == 0);
// don't set the pref unless they press OK and it's false // don't set the pref unless they press OK and it's false
if (reallyClose && !warnOnClose.value) if (reallyClose && !warnOnClose.value) {
Services.prefs.setBoolPref("browser.tabs.warnOnClose", false); let pref = isWindowClosing ? "browser.tabs.warnOnClose" :
"browser.tabs.warnOnCloseOtherTabs";
Services.prefs.setBoolPref(pref, false);
}
return reallyClose; return reallyClose;
]]> ]]>

Просмотреть файл

@ -199,6 +199,7 @@ support-files =
[browser_bug880101.js] [browser_bug880101.js]
[browser_bug882977.js] [browser_bug882977.js]
[browser_bug887515.js] [browser_bug887515.js]
[browser_bug896291_closeMaxSessionStoreTabs.js]
[browser_bug902156.js] [browser_bug902156.js]
[browser_canonizeURL.js] [browser_canonizeURL.js]
[browser_clearplugindata.html] [browser_clearplugindata.html]

Просмотреть файл

@ -0,0 +1,108 @@
function numClosedTabs()
Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore).
getNumberOfTabsClosedLast(window);
let originalTab;
let maxTabsUndo;
let maxTabsUndoPlusOne;
let acceptRemoveAllTabsDialogListener;
let cancelRemoveAllTabsDialogListener;
function test() {
waitForExplicitFinish();
Services.prefs.setBoolPref("browser.tabs.animate", false);
registerCleanupFunction(function() {
Services.prefs.clearUserPref("browser.tabs.animate");
originalTab.linkedBrowser.loadURI("about:blank");
originalTab = null;
});
// Creating and throwing away this tab guarantees that the
// number of tabs closed in the previous tab-close operation is 1.
let throwaway_tab = gBrowser.addTab("http://mochi.test:8888/");
gBrowser.removeTab(throwaway_tab);
let undoCloseTabElement = document.getElementById("context_undoCloseTab");
updateTabContextMenu();
is(undoCloseTabElement.label, undoCloseTabElement.getAttribute("singletablabel"),
"The label should be showing that the command will restore a single tab");
originalTab = gBrowser.selectedTab;
gBrowser.selectedBrowser.loadURI("http://mochi.test:8888/");
maxTabsUndo = Services.prefs.getIntPref("browser.sessionstore.max_tabs_undo");
maxTabsUndoPlusOne = maxTabsUndo + 1;
let numberOfTabsLoaded = 0;
for (let i = 0; i < maxTabsUndoPlusOne; i++) {
let tab = gBrowser.addTab("http://mochi.test:8888/");
let browser = gBrowser.getBrowserForTab(tab);
browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
if (++numberOfTabsLoaded == maxTabsUndoPlusOne)
verifyUndoMultipleClose();
}, true);
}
}
function verifyUndoMultipleClose() {
info("all tabs opened and loaded");
cancelRemoveAllTabsDialogListener = new WindowListener("chrome://global/content/commonDialog.xul", cancelRemoveAllTabsDialog);
Services.wm.addListener(cancelRemoveAllTabsDialogListener);
gBrowser.removeAllTabsBut(originalTab);
}
function cancelRemoveAllTabsDialog(domWindow) {
ok(true, "dialog appeared in response to multiple tab close action");
domWindow.document.documentElement.cancelDialog();
Services.wm.removeListener(cancelRemoveAllTabsDialogListener);
acceptRemoveAllTabsDialogListener = new WindowListener("chrome://global/content/commonDialog.xul", acceptRemoveAllTabsDialog);
Services.wm.addListener(acceptRemoveAllTabsDialogListener);
waitForCondition(function () gBrowser.tabs.length == 1 + maxTabsUndoPlusOne, function verifyCancel() {
is(gBrowser.tabs.length, 1 + maxTabsUndoPlusOne, /* The '1 +' is for the original tab */
"All tabs should still be open after the 'Cancel' option on the prompt is chosen");
gBrowser.removeAllTabsBut(originalTab);
}, "Waited too long to find that no tabs were closed.");
}
function acceptRemoveAllTabsDialog(domWindow) {
ok(true, "dialog appeared in response to multiple tab close action");
domWindow.document.documentElement.acceptDialog();
Services.wm.removeListener(acceptRemoveAllTabsDialogListener);
waitForCondition(function () gBrowser.tabs.length == 1, function verifyAccept() {
is(gBrowser.tabs.length, 1,
"All other tabs should be closed after the 'OK' option on the prompt is chosen");
finish();
}, "Waited too long for the other tabs to be closed.");
}
function WindowListener(aURL, aCallback) {
this.callback = aCallback;
this.url = aURL;
}
WindowListener.prototype = {
onOpenWindow: function(aXULWindow) {
var domWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
var self = this;
domWindow.addEventListener("load", function() {
domWindow.removeEventListener("load", arguments.callee, false);
info("domWindow.document.location.href: " + domWindow.document.location.href);
if (domWindow.document.location.href != self.url)
return;
// Allow other window load listeners to execute before passing to callback
executeSoon(function() {
self.callback(domWindow);
});
}, false);
},
onCloseWindow: function(aXULWindow) {},
onWindowTitleChange: function(aXULWindow, aNewTitle) {}
}

Просмотреть файл

@ -58,10 +58,10 @@ function test() {
waitForExplicitFinish(); waitForExplicitFinish();
let ns = {}; let ns = {};
Components.utils.import("resource://services-common/log4moz.js", ns); Components.utils.import("resource://gre/modules/Log.jsm", ns);
rootLogger = ns.Log4Moz.repository.rootLogger; rootLogger = ns.Log.repository.rootLogger;
dumpAppender = new ns.Log4Moz.DumpAppender(); dumpAppender = new ns.Log.DumpAppender();
dumpAppender.level = ns.Log4Moz.Level.All; dumpAppender.level = ns.Log.Level.All;
rootLogger.addAppender(dumpAppender); rootLogger.addAppender(dumpAppender);
let notification = document.getElementById("global-notificationbox"); let notification = document.getElementById("global-notificationbox");

Просмотреть файл

@ -0,0 +1,139 @@
/* 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/. */
this.EXPORTED_SYMBOLS = ["RecentlyClosedTabsAndWindowsMenuUtils"];
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var Ci = Components.interfaces;
var Cc = Components.classes;
var Cr = Components.results;
var Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
let navigatorBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
this.RecentlyClosedTabsAndWindowsMenuUtils = {
/**
* Builds up a document fragment of UI items for the recently closed tabs.
* @param aWindow
* The window that the tabs were closed in.
* @param aTagName
* The tag name that will be used when creating the UI items.
* @returns A document fragment with UI items for each recently closed tab.
*/
getTabsFragment: function(aWindow, aTagName) {
let doc = aWindow.document;
let fragment = doc.createDocumentFragment();
if (ss.getClosedTabCount(aWindow) != 0) {
let closedTabs = JSON.parse(ss.getClosedTabData(aWindow));
for (let i = 0; i < closedTabs.length; i++) {
let element = doc.createElementNS(kNSXUL, aTagName);
element.setAttribute("label", closedTabs[i].title);
if (closedTabs[i].image) {
setImage(closedTabs[i], element);
}
element.setAttribute("value", i);
if (aTagName == "menuitem") {
element.setAttribute("class", "menuitem-iconic bookmark-item menuitem-with-favicon");
}
element.setAttribute("oncommand", "undoCloseTab(" + i + ");");
// Set the targetURI attribute so it will be shown in tooltip and trigger
// onLinkHovered. SessionStore uses one-based indexes, so we need to
// normalize them.
let tabData = closedTabs[i].state;
let activeIndex = (tabData.index || tabData.entries.length) - 1;
if (activeIndex >= 0 && tabData.entries[activeIndex]) {
element.setAttribute("targetURI", tabData.entries[activeIndex].url);
}
element.addEventListener("click", this._undoCloseMiddleClick, false);
if (i == 0)
element.setAttribute("key", "key_undoCloseTab");
fragment.appendChild(element);
}
fragment.appendChild(doc.createElementNS(kNSXUL, "menuseparator"));
let restoreAllTabs = fragment.appendChild(doc.createElementNS(kNSXUL, aTagName));
restoreAllTabs.setAttribute("label", navigatorBundle.GetStringFromName("menuRestoreAllTabs.label"));
restoreAllTabs.addEventListener("command", function() {
for (var i = 0; i < closedTabs.length; i++)
undoCloseTab(0);
}, false);
}
return fragment;
},
/**
* Builds up a document fragment of UI items for the recently closed windows.
* @param aWindow
* A window that can be used to create the elements and document fragment.
* @param aTagName
* The tag name that will be used when creating the UI items.
* @returns A document fragment with UI items for each recently closed window.
*/
getWindowsFragment: function(aWindow, aTagName) {
let closedWindowData = JSON.parse(ss.getClosedWindowData());
let fragment = aWindow.document.createDocumentFragment();
if (closedWindowData.length != 0) {
let menuLabelString = navigatorBundle.GetStringFromName("menuUndoCloseWindowLabel");
let menuLabelStringSingleTab =
navigatorBundle.GetStringFromName("menuUndoCloseWindowSingleTabLabel");
let doc = aWindow.document;
for (let i = 0; i < closedWindowData.length; i++) {
let undoItem = closedWindowData[i];
let otherTabsCount = undoItem.tabs.length - 1;
let label = (otherTabsCount == 0) ? menuLabelStringSingleTab
: PluralForm.get(otherTabsCount, menuLabelString);
let menuLabel = label.replace("#1", undoItem.title)
.replace("#2", otherTabsCount);
let item = doc.createElementNS(kNSXUL, aTagName);
item.setAttribute("label", menuLabel);
let selectedTab = undoItem.tabs[undoItem.selected - 1];
if (selectedTab.image) {
setImage(selectedTab, item);
}
if (aTagName == "menuitem") {
item.setAttribute("class", "menuitem-iconic bookmark-item menuitem-with-favicon");
}
item.setAttribute("oncommand", "undoCloseWindow(" + i + ");");
// Set the targetURI attribute so it will be shown in tooltip.
// SessionStore uses one-based indexes, so we need to normalize them.
let activeIndex = (selectedTab.index || selectedTab.entries.length) - 1;
if (activeIndex >= 0 && selectedTab.entries[activeIndex])
item.setAttribute("targetURI", selectedTab.entries[activeIndex].url);
if (i == 0)
item.setAttribute("key", "key_undoCloseWindow");
fragment.appendChild(item);
}
// "Open All in Windows"
fragment.appendChild(doc.createElementNS(kNSXUL, "menuseparator"));
let restoreAllWindows = fragment.appendChild(doc.createElementNS(kNSXUL, aTagName));
restoreAllWindows.setAttribute("label", navigatorBundle.GetStringFromName("menuRestoreAllWindows.label"));
restoreAllWindows.setAttribute("oncommand",
"for (var i = 0; i < " + closedWindowData.length + "; i++) undoCloseWindow();");
}
return fragment;
},
};
function setImage(aItem, aElement) {
let iconURL = aItem.image;
// don't initiate a connection just to fetch a favicon (see bug 467828)
if (/^https?:/.test(iconURL))
iconURL = "moz-anno:favicon:" + iconURL;
aElement.setAttribute("image", iconURL);
}

Просмотреть файл

@ -202,15 +202,6 @@ let SessionSaverInternal = {
} }
} }
#ifndef XP_MACOSX
// Don't save invalid states.
// Looks like we currently have private windows, only.
if (state.windows.length == 0) {
stopWatchCancel("COLLECT_DATA_MS", "COLLECT_DATA_LONGEST_OP_MS");
return;
}
#endif
// Remove private windows from the list of closed windows. // Remove private windows from the list of closed windows.
for (let i = state._closedWindows.length - 1; i >= 0; i--) { for (let i = state._closedWindows.length - 1; i >= 0; i--) {
if (state._closedWindows[i].isPrivate) { if (state._closedWindows[i].isPrivate) {
@ -218,6 +209,13 @@ let SessionSaverInternal = {
} }
} }
// Make sure that we keep the previous session if we started with a single
// private window and no non-private windows have been opened, yet.
if (state.deferredInitialState) {
state.windows = state.deferredInitialState.windows || [];
delete state.deferredInitialState;
}
#ifndef XP_MACOSX #ifndef XP_MACOSX
// We want to restore closed windows that are marked with _shouldRestore. // We want to restore closed windows that are marked with _shouldRestore.
// We're doing this here because we want to control this only when saving // We're doing this here because we want to control this only when saving

Просмотреть файл

@ -352,7 +352,7 @@ let SessionStoreInternal = {
/* ........ Public Getters .............. */ /* ........ Public Getters .............. */
get canRestoreLastSession() { get canRestoreLastSession() {
return this._lastSessionState; return !!this._lastSessionState;
}, },
set canRestoreLastSession(val) { set canRestoreLastSession(val) {
@ -728,7 +728,7 @@ let SessionStoreInternal = {
// We're starting with a single private window. Save the state we // We're starting with a single private window. Save the state we
// actually wanted to restore so that we can do it later in case // actually wanted to restore so that we can do it later in case
// the user opens another, non-private window. // the user opens another, non-private window.
this._deferredInitialState = aInitialState; this._deferredInitialState = gSessionStartup.state;
// Nothing to restore now, notify observers things are complete. // Nothing to restore now, notify observers things are complete.
Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED, ""); Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED, "");
@ -1346,6 +1346,9 @@ let SessionStoreInternal = {
// Don't include the last session state in getBrowserState(). // Don't include the last session state in getBrowserState().
delete state.lastSessionState; delete state.lastSessionState;
// Don't include any deferred initial state.
delete state.deferredInitialState;
return this._toJSONString(state); return this._toJSONString(state);
}, },
@ -2074,6 +2077,13 @@ let SessionStoreInternal = {
state.lastSessionState = this._lastSessionState; state.lastSessionState = this._lastSessionState;
} }
// If we were called by the SessionSaver and started with only a private
// window we want to pass the deferred initial state to not lose the
// previous session.
if (this._deferredInitialState) {
state.deferredInitialState = this._deferredInitialState;
}
return state; return state;
}, },
@ -3524,6 +3534,14 @@ let SessionStoreInternal = {
* @returns [defaultState, state] * @returns [defaultState, state]
*/ */
_prepDataForDeferredRestore: function ssi_prepDataForDeferredRestore(state) { _prepDataForDeferredRestore: function ssi_prepDataForDeferredRestore(state) {
// Make sure that we don't modify the global state as provided by
// nsSessionStartup.state. Converting the object to a JSON string and
// parsing it again is the easiest way to do that, although not the most
// efficient one. Deferred sessions that don't have automatic session
// restore enabled tend to be a lot smaller though so that this shouldn't
// be a big perf hit.
state = JSON.parse(JSON.stringify(state));
let defaultState = { windows: [], selectedWindow: 1 }; let defaultState = { windows: [], selectedWindow: 1 };
state.selectedWindow = state.selectedWindow || 1; state.selectedWindow = state.selectedWindow || 1;
@ -3715,9 +3733,9 @@ let SessionStoreInternal = {
* @param aTab the which has been restored * @param aTab the which has been restored
*/ */
_sendTabRestoredNotification: function ssi_sendTabRestoredNotification(aTab) { _sendTabRestoredNotification: function ssi_sendTabRestoredNotification(aTab) {
let event = aTab.ownerDocument.createEvent("Events"); let event = aTab.ownerDocument.createEvent("Events");
event.initEvent("SSTabRestored", true, false); event.initEvent("SSTabRestored", true, false);
aTab.dispatchEvent(event); aTab.dispatchEvent(event);
}, },
/** /**
@ -4248,7 +4266,7 @@ let TabState = {
} }
if (disallow.length > 0) { if (disallow.length > 0) {
tabData.disallow = disallow.join(","); tabData.disallow = disallow.join(",");
} }
// Save text and scroll data. // Save text and scroll data.
@ -4395,9 +4413,9 @@ let TabState = {
if (!options || !options.omitDocShellCapabilities) { if (!options || !options.omitDocShellCapabilities) {
let disallow = DocShellCapabilities.collect(browser.docShell); let disallow = DocShellCapabilities.collect(browser.docShell);
if (disallow.length > 0) if (disallow.length > 0)
tabData.disallow = disallow.join(","); tabData.disallow = disallow.join(",");
else if (tabData.disallow) else if (tabData.disallow)
delete tabData.disallow; delete tabData.disallow;
} }
// Save tab attributes. // Save tab attributes.
@ -4604,5 +4622,3 @@ let TabState = {
return ""; return "";
} }
}; };

Просмотреть файл

@ -17,6 +17,7 @@ EXTRA_JS_MODULES = [
'DocumentUtils.jsm', 'DocumentUtils.jsm',
'Messenger.jsm', 'Messenger.jsm',
'PrivacyLevel.jsm', 'PrivacyLevel.jsm',
'RecentlyClosedTabsAndWindowsMenuUtils.jsm',
'SessionCookies.jsm', 'SessionCookies.jsm',
'SessionHistory.jsm', 'SessionHistory.jsm',
'SessionMigration.jsm', 'SessionMigration.jsm',

Просмотреть файл

@ -24,24 +24,31 @@ AppValidator.prototype.warning = function (message) {
this.warnings.push(message); this.warnings.push(message);
} }
AppValidator.prototype._getPackagedManifestURL = function () { AppValidator.prototype._getPackagedManifestFile = function () {
let manifestFile = FileUtils.File(this.project.location); let manifestFile = FileUtils.File(this.project.location);
if (!manifestFile.exists()) { if (!manifestFile.exists()) {
this.error(strings.GetStringFromName("validator.nonExistingFolder")); this.error(strings.GetStringFromName("validator.nonExistingFolder"));
return; return null;
} }
if (!manifestFile.isDirectory()) { if (!manifestFile.isDirectory()) {
this.error(strings.GetStringFromName("validator.expectProjectFolder")); this.error(strings.GetStringFromName("validator.expectProjectFolder"));
return; return null;
} }
manifestFile.append("manifest.webapp"); manifestFile.append("manifest.webapp");
if (!manifestFile.exists() || !manifestFile.isFile()) { if (!manifestFile.exists() || !manifestFile.isFile()) {
this.error(strings.GetStringFromName("validator.wrongManifestFileName")); this.error(strings.GetStringFromName("validator.wrongManifestFileName"));
return; return null;
} }
return manifestFile;
};
AppValidator.prototype._getPackagedManifestURL = function () {
let manifestFile = this._getPackagedManifestFile();
if (!manifestFile) {
return null;
}
return Services.io.newFileURI(manifestFile).spec; return Services.io.newFileURI(manifestFile).spec;
} };
AppValidator.prototype._fetchManifest = function (manifestURL) { AppValidator.prototype._fetchManifest = function (manifestURL) {
let deferred = promise.defer(); let deferred = promise.defer();
@ -54,7 +61,7 @@ AppValidator.prototype._fetchManifest = function (manifestURL) {
deferred.resolve(null); deferred.resolve(null);
return deferred.promise; return deferred.promise;
} }
req.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING; req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING;
req.onload = (function () { req.onload = (function () {
let manifest = null; let manifest = null;
try { try {

Просмотреть файл

@ -0,0 +1,106 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
Cu.import("resource://gre/modules/osfile.jsm");
const {VariablesView} =
Cu.import("resource:///modules/devtools/VariablesView.jsm", {});
const VARIABLES_VIEW_URL =
"chrome://browser/content/devtools/widgets/VariablesView.xul";
function ManifestEditor(project) {
this.project = project;
this._onContainerReady = this._onContainerReady.bind(this);
this._onEval = this._onEval.bind(this);
this._onSwitch = this._onSwitch.bind(this);
this._onDelete = this._onDelete.bind(this);
}
ManifestEditor.prototype = {
get manifest() { return this.project.manifest; },
show: function(containerElement) {
let deferred = promise.defer();
let iframe = document.createElement("iframe");
iframe.addEventListener("load", function onIframeLoad() {
iframe.removeEventListener("load", onIframeLoad, true);
deferred.resolve(iframe.contentWindow);
}, true);
iframe.setAttribute("src", VARIABLES_VIEW_URL);
iframe.classList.add("variables-view");
containerElement.appendChild(iframe);
return deferred.promise.then(this._onContainerReady);
},
_onContainerReady: function(varWindow) {
let variablesContainer = varWindow.document.querySelector("#variables");
let editor = this.editor = new VariablesView(variablesContainer);
editor.onlyEnumVisible = true;
editor.eval = this._onEval;
editor.switch = this._onSwitch;
editor.delete = this._onDelete;
return this.update();
},
_onEval: function(evalString) {
let manifest = this.manifest;
eval("manifest" + evalString);
this.update();
},
_onSwitch: function(variable, newName) {
let manifest = this.manifest;
let newSymbolicName = variable.ownerView.symbolicName +
"['" + newName + "']";
if (newSymbolicName == variable.symbolicName) {
return;
}
let evalString = "manifest" + newSymbolicName + " = " +
"manifest" + variable.symbolicName + ";" +
"delete manifest" + variable.symbolicName;
eval(evalString);
this.update();
},
_onDelete: function(variable) {
let manifest = this.manifest;
let evalString = "delete manifest" + variable.symbolicName;
eval(evalString);
},
update: function() {
this.editor.createHierarchy();
this.editor.rawObject = this.manifest;
this.editor.commitHierarchy();
// Wait until the animation from commitHierarchy has completed
let deferred = promise.defer();
setTimeout(deferred.resolve, this.editor.lazyEmptyDelay + 1);
return deferred.promise;
},
save: function() {
if (this.project.type == "packaged") {
let validator = new AppValidator(this.project);
let manifestFile = validator._getPackagedManifestFile();
let path = manifestFile.path;
let encoder = new TextEncoder();
let data = encoder.encode(JSON.stringify(this.manifest, null, 2));
return OS.File.writeAtomic(path, data, { tmpPath: path + ".tmp" });
}
return promise.resolve();
}
};

Просмотреть файл

@ -15,9 +15,12 @@ const {AppValidator} = require("devtools/app-manager/app-validator");
const {Services} = Cu.import("resource://gre/modules/Services.jsm"); const {Services} = Cu.import("resource://gre/modules/Services.jsm");
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm"); const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
const {installHosted, installPackaged, getTargetForApp} = require("devtools/app-actor-front"); const {installHosted, installPackaged, getTargetForApp} = require("devtools/app-actor-front");
const {EventEmitter} = Cu.import("resource:///modules/devtools/shared/event-emitter.js");
const promise = require("sdk/core/promise"); const promise = require("sdk/core/promise");
const MANIFEST_EDITOR_ENABLED = "devtools.appmanager.manifestEditor.enabled";
window.addEventListener("message", function(event) { window.addEventListener("message", function(event) {
try { try {
let json = JSON.parse(event.data); let json = JSON.parse(event.data);
@ -35,12 +38,20 @@ window.addEventListener("message", function(event) {
}, false); }, false);
let UI = { let UI = {
isReady: false,
onload: function() { onload: function() {
if (Services.prefs.getBoolPref(MANIFEST_EDITOR_ENABLED)) {
document.querySelector("#lense").setAttribute("manifest-editable", "");
}
this.template = new Template(document.body, AppProjects.store, Utils.l10n); this.template = new Template(document.body, AppProjects.store, Utils.l10n);
this.template.start(); this.template.start();
AppProjects.load().then(() => { AppProjects.load().then(() => {
AppProjects.store.object.projects.forEach(UI.validate); AppProjects.store.object.projects.forEach(UI.validate);
this.isReady = true;
this.emit("ready");
}); });
}, },
@ -88,11 +99,11 @@ let UI = {
let urlInput = document.querySelector("#url-input"); let urlInput = document.querySelector("#url-input");
let manifestURL = urlInput.value; let manifestURL = urlInput.value;
AppProjects.addHosted(manifestURL) return AppProjects.addHosted(manifestURL)
.then(function (project) { .then(function (project) {
UI.validate(project); UI.validate(project);
UI.selectProject(project.location); UI.selectProject(project.location);
}); });
}, },
_getLocalIconURL: function(project, manifest) { _getLocalIconURL: function(project, manifest) {
@ -121,7 +132,6 @@ let UI = {
return validation.validate() return validation.validate()
.then(function () { .then(function () {
if (validation.manifest) { if (validation.manifest) {
project.name = validation.manifest.name;
project.icon = UI._getLocalIconURL(project, validation.manifest); project.icon = UI._getLocalIconURL(project, validation.manifest);
project.manifest = validation.manifest; project.manifest = validation.manifest;
} }
@ -153,7 +163,10 @@ let UI = {
update: function(button, location) { update: function(button, location) {
button.disabled = true; button.disabled = true;
let project = AppProjects.get(location); let project = AppProjects.get(location);
this.validate(project) this.manifestEditor.save()
.then(() => {
return this.validate(project);
})
.then(() => { .then(() => {
// Install the app to the device if we are connected, // Install the app to the device if we are connected,
// and there is no error // and there is no error
@ -386,5 +399,16 @@ let UI = {
let lense = document.querySelector("#lense"); let lense = document.querySelector("#lense");
lense.setAttribute("template-for", template); lense.setAttribute("template-for", template);
this.template._processFor(lense); this.template._processFor(lense);
let project = projects[idx];
this._showManifestEditor(project).then(() => this.emit("project-selected"));
}, },
}
_showManifestEditor: function(project) {
let editorContainer = document.querySelector("#lense .manifest-editor");
this.manifestEditor = new ManifestEditor(project);
return this.manifestEditor.show(editorContainer);
}
};
EventEmitter.decorate(UI);

Просмотреть файл

@ -14,6 +14,10 @@
<base href="chrome://browser/content/devtools/app-manager/"></base> <base href="chrome://browser/content/devtools/app-manager/"></base>
<title>&projects.title;</title> <title>&projects.title;</title>
<link rel="stylesheet" href="chrome://browser/skin/devtools/app-manager/projects.css" type="text/css"/> <link rel="stylesheet" href="chrome://browser/skin/devtools/app-manager/projects.css" type="text/css"/>
<script type="application/javascript;version=1.8" src="utils.js"></script>
<script type="application/javascript;version=1.8" src="projects.js"></script>
<script type="application/javascript;version=1.8" src="template.js"></script>
<script type="application/javascript;version=1.8" src="manifest-editor.js"></script>
</head> </head>
<body onload="UI.onload()"> <body onload="UI.onload()">
@ -25,7 +29,7 @@
<div id="new-packaged-project" onclick="UI.addPackaged()" title="&projects.addPackagedTooltip;">&projects.addPackaged;</div> <div id="new-packaged-project" onclick="UI.addPackaged()" title="&projects.addPackagedTooltip;">&projects.addPackaged;</div>
<div id="new-hosted-project">&projects.addHosted; <div id="new-hosted-project">&projects.addHosted;
<form onsubmit="UI.addHosted(); return false;" id="new-hosted-project-wrapper"> <form onsubmit="UI.addHosted(); return false;" id="new-hosted-project-wrapper">
<input value="" id="url-input" type="url" required="true" pattern="https?://.+" placeholder="&projects.hostedManifestPlaceHolder2;" size="50" /> <input value="" id="url-input" type="url" required="true" pattern="(https?|chrome)://.+" placeholder="&projects.hostedManifestPlaceHolder2;" size="50" />
<div onclick="UI.addHosted()" id="new-hosted-project-click" title="&projects.addHostedTooltip;"></div> <div onclick="UI.addHosted()" id="new-hosted-project-click" title="&projects.addHostedTooltip;"></div>
<input type="submit" hidden="true"></input> <input type="submit" hidden="true"></input>
</form> </form>
@ -40,7 +44,7 @@
<img class="project-item-icon" template='{"type":"attribute","path":"icon","name":"src"}' /> <img class="project-item-icon" template='{"type":"attribute","path":"icon","name":"src"}' />
<div class="project-item-meta"> <div class="project-item-meta">
<div class="button-remove" onclick="UI.remove(this.dataset.location, event)" template='{"type":"attribute","path":"location","name":"data-location"}' title="&projects.removeAppFromList;"></div> <div class="button-remove" onclick="UI.remove(this.dataset.location, event)" template='{"type":"attribute","path":"location","name":"data-location"}' title="&projects.removeAppFromList;"></div>
<strong template='{"type":"textContent","path":"name"}'></strong> <strong template='{"type":"textContent","path":"manifest.name"}'></strong>
<span class="project-item-type" template='{"type":"textContent","path":"type"}'></span> <span class="project-item-type" template='{"type":"textContent","path":"type"}'></span>
<p class="project-item-description" template='{"type":"textContent","path":"manifest.description"}'></p> <p class="project-item-description" template='{"type":"textContent","path":"manifest.description"}'></p>
<div template='{"type":"attribute","path":"validationStatus","name":"status"}'> <div template='{"type":"attribute","path":"validationStatus","name":"status"}'>
@ -56,9 +60,9 @@
<div class="project-details" template='{"type":"attribute","path":"validationStatus","name":"status"}'> <div class="project-details" template='{"type":"attribute","path":"validationStatus","name":"status"}'>
<div class="project-header"> <div class="project-header">
<img class="project-icon" template='{"type":"attribute","path":"icon","name":"src"}'/> <img class="project-icon" template='{"type":"attribute","path":"icon","name":"src"}'/>
<div class="project-details"> <div class="project-metadata">
<div class="project-title"> <div class="project-title">
<h1 template='{"type":"textContent","path":"name"}'></h1> <h1 template='{"type":"textContent","path":"manifest.name"}'></h1>
<div class="project-status" template='{"type":"attribute","path":"validationStatus","name":"status"}'> <div class="project-status" template='{"type":"attribute","path":"validationStatus","name":"status"}'>
<p class="project-validation" template='{"type":"textContent","path":"validationStatus"}'></p> <p class="project-validation" template='{"type":"textContent","path":"validationStatus"}'></p>
<p class="project-type" template='{"type":"textContent","path":"type"}'></p> <p class="project-type" template='{"type":"textContent","path":"type"}'></p>
@ -76,11 +80,9 @@
<div class="project-errors" template='{"type":"textContent","path":"errors"}'></div> <div class="project-errors" template='{"type":"textContent","path":"errors"}'></div>
<div class="project-warnings" template='{"type":"textContent","path":"warnings"}'></div> <div class="project-warnings" template='{"type":"textContent","path":"warnings"}'></div>
</div> </div>
<div class="manifest-editor">
<h2>&projects.manifestEditor;</h2>
</div>
</div> </div>
</template> </template>
<script type="application/javascript;version=1.8" src="utils.js"></script>
<script type="application/javascript;version=1.8" src="projects.js"></script>
<script type="application/javascript;version=1.8" src="template.js"></script>
</html> </html>

Просмотреть файл

@ -0,0 +1,6 @@
[DEFAULT]
support-files =
head.js
hosted_app.manifest
[browser_manifest_editor.js]

Просмотреть файл

@ -0,0 +1,54 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
const MANIFEST_EDITOR_ENABLED = "devtools.appmanager.manifestEditor.enabled";
function test() {
waitForExplicitFinish();
Task.spawn(function() {
Services.prefs.setBoolPref(MANIFEST_EDITOR_ENABLED, true);
let tab = yield openAppManager();
yield selectProjectsPanel();
yield addSampleHostedApp();
yield showSampleProjectDetails();
yield changeManifestValue("name", "the best app");
yield removeSampleHostedApp();
yield removeTab(tab);
Services.prefs.setBoolPref(MANIFEST_EDITOR_ENABLED, false);
finish();
});
}
function changeManifestValue(key, value) {
return Task.spawn(function() {
let manifestWindow = getManifestWindow();
let manifestEditor = getProjectsWindow().UI.manifestEditor;
let propElem = manifestWindow.document
.querySelector("[id ^= '" + key + "']");
is(propElem.querySelector(".name").value, key,
"Key doesn't match expected value");
let valueElem = propElem.querySelector(".value");
EventUtils.sendMouseEvent({ type: "mousedown" }, valueElem, manifestWindow);
let valueInput = propElem.querySelector(".element-value-input");
valueInput.value = '"' + value + '"';
EventUtils.sendKey("RETURN", manifestWindow);
// Wait until the animation from commitHierarchy has completed
yield waitForTime(manifestEditor.editor.lazyEmptyDelay + 1);
// Elements have all been replaced, re-select them
propElem = manifestWindow.document.querySelector("[id ^= '" + key + "']");
valueElem = propElem.querySelector(".value");
is(valueElem.value, '"' + value + '"',
"Value doesn't match expected value");
is(manifestEditor.manifest[key], value,
"Manifest doesn't contain expected value");
});
}

Просмотреть файл

@ -0,0 +1,152 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {utils: Cu} = Components;
const {Promise: promise} =
Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
const {devtools} =
Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const {require} = devtools;
const {AppProjects} = require("devtools/app-manager/app-projects");
const APP_MANAGER_URL = "about:app-manager";
const TEST_BASE =
"chrome://mochitests/content/browser/browser/devtools/app-manager/test/";
const HOSTED_APP_MANIFEST = TEST_BASE + "hosted_app.manifest";
function addTab(url, targetWindow = window) {
info("Adding tab: " + url);
let deferred = promise.defer();
let targetBrowser = targetWindow.gBrowser;
targetWindow.focus();
let tab = targetBrowser.selectedTab = targetBrowser.addTab(url);
let linkedBrowser = tab.linkedBrowser;
linkedBrowser.addEventListener("load", function onLoad() {
linkedBrowser.removeEventListener("load", onLoad, true);
info("Tab added and finished loading: " + url);
deferred.resolve(tab);
}, true);
return deferred.promise;
}
function removeTab(tab, targetWindow = window) {
info("Removing tab.");
let deferred = promise.defer();
let targetBrowser = targetWindow.gBrowser;
let tabContainer = targetBrowser.tabContainer;
tabContainer.addEventListener("TabClose", function onClose(aEvent) {
tabContainer.removeEventListener("TabClose", onClose, false);
info("Tab removed and finished closing.");
deferred.resolve();
}, false);
targetBrowser.removeTab(tab);
return deferred.promise;
}
function openAppManager() {
return addTab(APP_MANAGER_URL);
}
function addSampleHostedApp() {
info("Adding sample hosted app");
let projectsWindow = getProjectsWindow();
let projectsDocument = projectsWindow.document;
let url = projectsDocument.querySelector("#url-input");
url.value = HOSTED_APP_MANIFEST;
return projectsWindow.UI.addHosted();
}
function removeSampleHostedApp() {
info("Removing sample hosted app");
return AppProjects.remove(HOSTED_APP_MANIFEST);
}
function getProjectsWindow() {
return content.document.querySelector(".projects-panel").contentWindow;
}
function getManifestWindow() {
return getProjectsWindow().document.querySelector(".variables-view")
.contentWindow;
}
function waitForProjectsPanel(deferred = promise.defer()) {
info("Wait for projects panel");
let projectsWindow = getProjectsWindow();
let projectsUI = projectsWindow.UI;
if (!projectsUI) {
projectsWindow.addEventListener("load", function onLoad() {
projectsWindow.removeEventListener("load", onLoad);
waitForProjectsPanel(deferred);
});
return deferred.promise;
}
if (projectsUI.isReady) {
deferred.resolve();
return deferred.promise;
}
projectsUI.once("ready", deferred.resolve);
return deferred.promise;
}
function selectProjectsPanel() {
return Task.spawn(function() {
let projectsButton = content.document.querySelector(".projects-button");
EventUtils.sendMouseEvent({ type: "click" }, projectsButton, content);
yield waitForProjectsPanel();
});
}
function waitForProjectSelection() {
info("Wait for project selection");
let deferred = promise.defer();
getProjectsWindow().UI.once("project-selected", deferred.resolve);
return deferred.promise;
}
function selectFirstProject() {
return Task.spawn(function() {
let projectsFrame = content.document.querySelector(".projects-panel");
let projectsWindow = projectsFrame.contentWindow;
let projectsDoc = projectsWindow.document;
let projectItem = projectsDoc.querySelector(".project-item");
EventUtils.sendMouseEvent({ type: "click" }, projectItem, projectsWindow);
yield waitForProjectSelection();
});
}
function showSampleProjectDetails() {
return Task.spawn(function() {
yield selectProjectsPanel();
yield selectFirstProject();
});
}
function waitForTick() {
let deferred = promise.defer();
executeSoon(deferred.resolve);
return deferred.promise;
}
function waitForTime(aDelay) {
let deferred = promise.defer();
setTimeout(deferred.resolve, aDelay);
return deferred.promise;
}

Просмотреть файл

@ -4,5 +4,5 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
BROWSER_CHROME_MANIFESTS += ['browser.ini']
MOCHITEST_CHROME_MANIFESTS += ['chrome.ini'] MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']

Просмотреть файл

@ -100,19 +100,26 @@ function test() {
ok(!testScope.expanded, ok(!testScope.expanded,
"The testScope should remember it is collapsed after it is reshown."); "The testScope should remember it is collapsed after it is reshown.");
EventUtils.sendMouseEvent({ type: "mousedown", button: 1 },
testScope.target.querySelector(".title"),
aPanel.panelWin);
ok(!testScope.expanded,
"Clicking the testScope title with the right mouse button should't expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
testScope.target.querySelector(".title"), testScope.target.querySelector(".title"),
aPanel.panelWin); aPanel.panelWin);
ok(testScope.expanded, ok(testScope.expanded,
"Clicking the testScope tilte should expand it."); "Clicking the testScope title should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
testScope.target.querySelector(".title"), testScope.target.querySelector(".title"),
aPanel.panelWin); aPanel.panelWin);
ok(!testScope.expanded, ok(!testScope.expanded,
"Clicking again the testScope tilte should collapse it."); "Clicking again the testScope title should collapse it.");
closeDebuggerAndFinish(aPanel); closeDebuggerAndFinish(aPanel);
}); });

Просмотреть файл

@ -45,6 +45,6 @@
<section id="connecting"> <section id="connecting">
<p><img src="chrome://browser/skin/tabbrowser/loading.png"></img> &connecting;</p> <p><img src="chrome://browser/skin/tabbrowser/loading.png"></img> &connecting;</p>
</section> </section>
<footer>&help;</footer> <footer>&help2;</footer>
</body> </body>
</html> </html>

Просмотреть файл

@ -743,6 +743,15 @@ InspectorPanel.prototype = {
} }
}, },
/**
* Trigger a high-priority layout change for things that need to be
* updated immediately
*/
immediateLayoutChange: function Inspector_immediateLayoutChange()
{
this.emit("layout-change");
},
/** /**
* Schedule a low-priority change event for things like paint * Schedule a low-priority change event for things like paint
* and resize. * and resize.

Просмотреть файл

@ -17,7 +17,7 @@ function test() {
} }
function getInspectorProp(aName) function getInspectorComputedProp(aName)
{ {
let computedview = inspector.sidebar.getWindowForTab("computedview").computedview.view; let computedview = inspector.sidebar.getWindowForTab("computedview").computedview.view;
for each (let view in computedview.propertyViews) { for each (let view in computedview.propertyViews) {
@ -28,6 +28,19 @@ function test() {
return null; return null;
} }
function getInspectorRuleProp(aName)
{
let ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview.view;
let inlineStyles = ruleview._elementStyle.rules[0];
for each (let prop in inlineStyles.textProps) {
if (prop.name == aName) {
return prop;
}
}
return null;
}
function runInspectorTests(aInspector) function runInspectorTests(aInspector)
{ {
inspector = aInspector; inspector = aInspector;
@ -40,59 +53,97 @@ function test() {
testDiv.style.fontSize = "10px"; testDiv.style.fontSize = "10px";
// Start up the style inspector panel... // Start up the style inspector panel...
inspector.once("computed-view-refreshed", stylePanelTests); inspector.once("computed-view-refreshed", computedStylePanelTests);
inspector.selection.setNode(testDiv); inspector.selection.setNode(testDiv);
}); });
} }
function stylePanelTests() function computedStylePanelTests()
{ {
let computedview = inspector.sidebar.getWindowForTab("computedview").computedview; let computedview = inspector.sidebar.getWindowForTab("computedview").computedview;
ok(computedview, "Style Panel has a cssHtmlTree"); ok(computedview, "Style Panel has a cssHtmlTree");
let propView = getInspectorProp("font-size"); let propView = getInspectorComputedProp("font-size");
is(propView.value, "10px", "Style inspector should be showing the correct font size."); is(propView.value, "10px", "Style inspector should be showing the correct font size.");
inspector.once("computed-view-refreshed", stylePanelAfterChange); testDiv.style.cssText = "font-size: 15px; color: red;";
testDiv.style.fontSize = "15px"; // Wait until layout-change fires from mutation to skip earlier refresh event
inspector.once("layout-change", () => {
// FIXME: This shouldn't be needed but as long as we don't fix the bug inspector.once("computed-view-refreshed", computedStylePanelAfterChange);
// where the rule/computed views are not updated when the selected node's });
// styles change, it has to stay here
inspector.emit("layout-change");
} }
function stylePanelAfterChange() function computedStylePanelAfterChange()
{ {
let propView = getInspectorProp("font-size"); let propView = getInspectorComputedProp("font-size");
is(propView.value, "15px", "Style inspector should be showing the new font size."); is(propView.value, "15px", "Style inspector should be showing the new font size.");
stylePanelNotActive(); let propView = getInspectorComputedProp("color");
is(propView.value, "#F00", "Style inspector should be showing the new color.");
computedStylePanelNotActive();
} }
function stylePanelNotActive() function computedStylePanelNotActive()
{ {
// Tests changes made while the style panel is not active. // Tests changes made while the style panel is not active.
inspector.sidebar.select("ruleview"); inspector.sidebar.select("ruleview");
executeSoon(function() { testDiv.style.fontSize = "20px";
inspector.once("computed-view-refreshed", stylePanelAfterSwitch); testDiv.style.color = "blue";
testDiv.style.fontSize = "20px"; testDiv.style.textAlign = "center";
inspector.sidebar.select("computedview");
// FIXME: This shouldn't be needed but as long as we don't fix the bug inspector.once("computed-view-refreshed", computedStylePanelAfterSwitch);
// where the rule/computed views are not updated when the selected node's inspector.sidebar.select("computedview");
// styles change, it has to stay here
inspector.emit("layout-change");
});
} }
function stylePanelAfterSwitch() function computedStylePanelAfterSwitch()
{ {
let propView = getInspectorProp("font-size"); let propView = getInspectorComputedProp("font-size");
is(propView.value, "20px", "Style inspector should be showing the newest font size."); is(propView.value, "20px", "Style inspector should be showing the new font size.");
let propView = getInspectorComputedProp("color");
is(propView.value, "#00F", "Style inspector should be showing the new color.");
let propView = getInspectorComputedProp("text-align");
is(propView.value, "center", "Style inspector should be showing the new text align.");
rulePanelTests();
}
function rulePanelTests()
{
inspector.sidebar.select("ruleview");
let ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview;
ok(ruleview, "Style Panel has a ruleview");
let propView = getInspectorRuleProp("text-align");
is(propView.value, "center", "Style inspector should be showing the new text align.");
testDiv.style.textAlign = "right";
testDiv.style.color = "lightgoldenrodyellow";
testDiv.style.fontSize = "3em";
testDiv.style.textTransform = "uppercase";
inspector.once("rule-view-refreshed", rulePanelAfterChange);
}
function rulePanelAfterChange()
{
let propView = getInspectorRuleProp("text-align");
is(propView.value, "right", "Style inspector should be showing the new text align.");
let propView = getInspectorRuleProp("color");
is(propView.value, "#FAFAD2", "Style inspector should be showing the new color.")
let propView = getInspectorRuleProp("font-size");
is(propView.value, "3em", "Style inspector should be showing the new font size.");
let propView = getInspectorRuleProp("text-transform");
is(propView.value, "uppercase", "Style inspector should be showing the new text transform.");
finishTest(); finishTest();
} }

Просмотреть файл

@ -85,3 +85,4 @@ browser.jar:
content/browser/devtools/app-manager/index.xul (app-manager/content/index.xul) content/browser/devtools/app-manager/index.xul (app-manager/content/index.xul)
content/browser/devtools/app-manager/index.js (app-manager/content/index.js) content/browser/devtools/app-manager/index.js (app-manager/content/index.js)
content/browser/devtools/app-manager/help.xhtml (app-manager/content/help.xhtml) content/browser/devtools/app-manager/help.xhtml (app-manager/content/help.xhtml)
content/browser/devtools/app-manager/manifest-editor.js (app-manager/content/manifest-editor.js)

Просмотреть файл

@ -387,6 +387,7 @@ MarkupView.prototype = {
* Mutation observer used for included nodes. * Mutation observer used for included nodes.
*/ */
_mutationObserver: function(aMutations) { _mutationObserver: function(aMutations) {
let requiresLayoutChange = false;
for (let mutation of aMutations) { for (let mutation of aMutations) {
let type = mutation.type; let type = mutation.type;
let target = mutation.target; let target = mutation.target;
@ -409,6 +410,11 @@ MarkupView.prototype = {
} }
if (type === "attributes" || type === "characterData") { if (type === "attributes" || type === "characterData") {
container.update(); container.update();
// Auto refresh style properties on selected node when they change.
if (type === "attributes" && container.selected) {
requiresLayoutChange = true;
}
} else if (type === "childList") { } else if (type === "childList") {
container.childrenDirty = true; container.childrenDirty = true;
// Update the children to take care of changes in the DOM // Update the children to take care of changes in the DOM
@ -417,6 +423,10 @@ MarkupView.prototype = {
this._updateChildren(container, {flash: true}); this._updateChildren(container, {flash: true});
} }
} }
if (requiresLayoutChange) {
this._inspector.immediateLayoutChange();
}
this._waitForChildren().then(() => { this._waitForChildren().then(() => {
this._flashMutatedNodes(aMutations); this._flashMutatedNodes(aMutations);
this._inspector.emit("markupmutation"); this._inspector.emit("markupmutation");

Просмотреть файл

@ -32,7 +32,7 @@ Parser.prototype = {
* @param string aSource * @param string aSource
* The source text content. * The source text content.
*/ */
get: function P_get(aUrl, aSource) { get: function(aUrl, aSource) {
// Try to use the cached AST nodes, to avoid useless parsing operations. // Try to use the cached AST nodes, to avoid useless parsing operations.
if (this._cache.has(aUrl)) { if (this._cache.has(aUrl)) {
return this._cache.get(aUrl); return this._cache.get(aUrl);
@ -89,7 +89,7 @@ Parser.prototype = {
/** /**
* Clears all the parsed sources from cache. * Clears all the parsed sources from cache.
*/ */
clearCache: function P_clearCache() { clearCache: function() {
this._cache.clear(); this._cache.clear();
}, },
@ -99,7 +99,7 @@ Parser.prototype = {
* @param String aUrl * @param String aUrl
* The URL of the source that is being cleared. * The URL of the source that is being cleared.
*/ */
clearSource: function P_clearSource(aUrl) { clearSource: function(aUrl) {
this._cache.delete(aUrl); this._cache.delete(aUrl);
}, },
@ -121,17 +121,10 @@ SyntaxTreesPool.prototype = {
/** /**
* @see SyntaxTree.prototype.getNamedFunctionDefinitions * @see SyntaxTree.prototype.getNamedFunctionDefinitions
*/ */
getNamedFunctionDefinitions: function STP_getNamedFunctionDefinitions(aSubstring) { getNamedFunctionDefinitions: function(aSubstring) {
return this._call("getNamedFunctionDefinitions", aSubstring); return this._call("getNamedFunctionDefinitions", aSubstring);
}, },
/**
* @see SyntaxTree.prototype.getFunctionAtLocation
*/
getFunctionAtLocation: function STP_getFunctionAtLocation(aLine, aColumn) {
return this._call("getFunctionAtLocation", [aLine, aColumn]);
},
/** /**
* Finds the offset and length of the script containing the specified offset * Finds the offset and length of the script containing the specified offset
* relative to its parent source. * relative to its parent source.
@ -141,7 +134,7 @@ SyntaxTreesPool.prototype = {
* @return array * @return array
* The offset and length relative to the enclosing script. * The offset and length relative to the enclosing script.
*/ */
getScriptInfo: function STP_getScriptInfo(aOffset) { getScriptInfo: function(aOffset) {
for (let { offset, length } of this._trees) { for (let { offset, length } of this._trees) {
if (offset <= aOffset && offset + length >= aOffset) { if (offset <= aOffset && offset + length >= aOffset) {
return [offset, length]; return [offset, length];
@ -160,7 +153,7 @@ SyntaxTreesPool.prototype = {
* @return array * @return array
* The results given by all known syntax trees. * The results given by all known syntax trees.
*/ */
_call: function STP__call(aFunction, aParams) { _call: function(aFunction, aParams) {
let results = []; let results = [];
let requestId = aFunction + aParams; // Cache all the things! let requestId = aFunction + aParams; // Cache all the things!
@ -221,7 +214,7 @@ SyntaxTree.prototype = {
* All the matching function declarations and expressions, as * All the matching function declarations and expressions, as
* { functionName, functionLocation ... } object hashes. * { functionName, functionLocation ... } object hashes.
*/ */
getNamedFunctionDefinitions: function ST_getNamedFunctionDefinitions(aSubstring) { getNamedFunctionDefinitions: function(aSubstring) {
let lowerCaseToken = aSubstring.toLowerCase(); let lowerCaseToken = aSubstring.toLowerCase();
let store = []; let store = [];
@ -230,7 +223,7 @@ SyntaxTree.prototype = {
* Callback invoked for each function declaration node. * Callback invoked for each function declaration node.
* @param Node aNode * @param Node aNode
*/ */
onFunctionDeclaration: function STW_onFunctionDeclaration(aNode) { onFunctionDeclaration: function(aNode) {
let functionName = aNode.id.name; let functionName = aNode.id.name;
if (functionName.toLowerCase().contains(lowerCaseToken)) { if (functionName.toLowerCase().contains(lowerCaseToken)) {
store.push({ store.push({
@ -244,31 +237,27 @@ SyntaxTree.prototype = {
* Callback invoked for each function expression node. * Callback invoked for each function expression node.
* @param Node aNode * @param Node aNode
*/ */
onFunctionExpression: function STW_onFunctionExpression(aNode) { onFunctionExpression: function(aNode) {
let parent = aNode._parent;
let functionName, inferredName, inferredChain, inferredLocation;
// Function expressions don't necessarily have a name. // Function expressions don't necessarily have a name.
if (aNode.id) { let functionName = aNode.id ? aNode.id.name : "";
functionName = aNode.id.name; let functionLocation = aNode.loc || null;
}
// Infer the function's name from an enclosing syntax tree node. // Infer the function's name from an enclosing syntax tree node.
if (parent) { let inferredInfo = ParserHelpers.inferFunctionExpressionInfo(aNode);
let inferredInfo = ParserHelpers.inferFunctionExpressionInfo(aNode); let inferredName = inferredInfo.name;
inferredName = inferredInfo.name; let inferredChain = inferredInfo.chain;
inferredChain = inferredInfo.chain; let inferredLocation = inferredInfo.loc;
inferredLocation = inferredInfo.loc;
}
// Current node may be part of a larger assignment expression stack. // Current node may be part of a larger assignment expression stack.
if (parent.type == "AssignmentExpression") { if (aNode._parent.type == "AssignmentExpression") {
this.onFunctionExpression(parent); this.onFunctionExpression(aNode._parent);
} }
if ((functionName && functionName.toLowerCase().contains(lowerCaseToken)) || if ((functionName && functionName.toLowerCase().contains(lowerCaseToken)) ||
(inferredName && inferredName.toLowerCase().contains(lowerCaseToken))) { (inferredName && inferredName.toLowerCase().contains(lowerCaseToken))) {
store.push({ store.push({
functionName: functionName, functionName: functionName,
functionLocation: aNode.loc, functionLocation: functionLocation,
inferredName: inferredName, inferredName: inferredName,
inferredChain: inferredChain, inferredChain: inferredChain,
inferredLocation: inferredLocation inferredLocation: inferredLocation
@ -280,19 +269,16 @@ SyntaxTree.prototype = {
* Callback invoked for each arrow expression node. * Callback invoked for each arrow expression node.
* @param Node aNode * @param Node aNode
*/ */
onArrowExpression: function STW_onArrowExpression(aNode) { onArrowExpression: function(aNode) {
let parent = aNode._parent;
let inferredName, inferredChain, inferredLocation;
// Infer the function's name from an enclosing syntax tree node. // Infer the function's name from an enclosing syntax tree node.
let inferredInfo = ParserHelpers.inferFunctionExpressionInfo(aNode); let inferredInfo = ParserHelpers.inferFunctionExpressionInfo(aNode);
inferredName = inferredInfo.name; let inferredName = inferredInfo.name;
inferredChain = inferredInfo.chain; let inferredChain = inferredInfo.chain;
inferredLocation = inferredInfo.loc; let inferredLocation = inferredInfo.loc;
// Current node may be part of a larger assignment expression stack. // Current node may be part of a larger assignment expression stack.
if (parent.type == "AssignmentExpression") { if (aNode._parent.type == "AssignmentExpression") {
this.onFunctionExpression(parent); this.onFunctionExpression(aNode._parent);
} }
if (inferredName && inferredName.toLowerCase().contains(lowerCaseToken)) { if (inferredName && inferredName.toLowerCase().contains(lowerCaseToken)) {
@ -308,100 +294,6 @@ SyntaxTree.prototype = {
return store; return store;
}, },
/**
* Gets the "new" or "call" expression at the specified location.
*
* @param number aLine
* The line in the source.
* @param number aColumn
* The column in the source.
* @return object
* An { functionName, functionLocation } object hash,
* or null if nothing is found at the specified location.
*/
getFunctionAtLocation: function STW_getFunctionAtLocation([aLine, aColumn]) {
let self = this;
let func = null;
SyntaxTreeVisitor.walk(this.AST, {
/**
* Callback invoked for each node.
* @param Node aNode
*/
onNode: function STW_onNode(aNode) {
// Make sure the node is part of a branch that's guaranteed to be
// hovered. Otherwise, return true to abruptly halt walking this
// syntax tree branch. This is a really efficient optimization.
return ParserHelpers.isWithinLines(aNode, aLine);
},
/**
* Callback invoked for each identifier node.
* @param Node aNode
*/
onIdentifier: function STW_onIdentifier(aNode) {
// Make sure the identifier itself is hovered.
let hovered = ParserHelpers.isWithinBounds(aNode, aLine, aColumn);
if (!hovered) {
return;
}
// Make sure the identifier is part of a "new" expression or
// "call" expression node.
let expression = ParserHelpers.getEnclosingFunctionExpression(aNode);
if (!expression) {
return;
}
// Found an identifier node that is part of a "new" expression or
// "call" expression node. However, it may be an argument, not a callee.
if (ParserHelpers.isFunctionCalleeArgument(aNode)) {
// It's an argument.
if (self.functionIdentifiersCache.has(aNode.name)) {
// It's a function as an argument.
func = {
functionName: aNode.name,
functionLocation: aNode.loc || aNode._parent.loc
};
}
return;
}
// Found a valid "new" expression or "call" expression node.
func = {
functionName: aNode.name,
functionLocation: ParserHelpers.getFunctionCalleeInfo(expression).loc
};
// Abruptly halt walking the syntax tree.
this.break = true;
}
});
return func;
},
/**
* Gets all the function identifiers in this syntax tree (both the
* function names and their inferred names).
*
* @return array
* An array of strings.
*/
get functionIdentifiersCache() {
if (this._functionIdentifiersCache) {
return this._functionIdentifiersCache;
}
let functionDefinitions = this.getNamedFunctionDefinitions("");
let functionIdentifiers = new Set();
for (let { functionName, inferredName } of functionDefinitions) {
functionIdentifiers.add(functionName);
functionIdentifiers.add(inferredName);
}
return this._functionIdentifiersCache = functionIdentifiers;
},
AST: null, AST: null,
url: "", url: "",
length: 0, length: 0,
@ -422,7 +314,7 @@ let ParserHelpers = {
* @return boolean * @return boolean
* True if the line and column is contained in the node's bounds. * True if the line and column is contained in the node's bounds.
*/ */
isWithinLines: function PH_isWithinLines(aNode, aLine) { isWithinLines: function(aNode, aLine) {
// Not all nodes have location information attached. // Not all nodes have location information attached.
if (!aNode.loc) { if (!aNode.loc) {
return this.isWithinLines(aNode._parent, aLine); return this.isWithinLines(aNode._parent, aLine);
@ -442,7 +334,7 @@ let ParserHelpers = {
* @return boolean * @return boolean
* True if the line and column is contained in the node's bounds. * True if the line and column is contained in the node's bounds.
*/ */
isWithinBounds: function PH_isWithinBounds(aNode, aLine, aColumn) { isWithinBounds: function(aNode, aLine, aColumn) {
// Not all nodes have location information attached. // Not all nodes have location information attached.
if (!aNode.loc) { if (!aNode.loc) {
return this.isWithinBounds(aNode._parent, aLine, aColumn); return this.isWithinBounds(aNode._parent, aLine, aColumn);
@ -453,16 +345,16 @@ let ParserHelpers = {
/** /**
* Try to infer a function expression's name & other details based on the * Try to infer a function expression's name & other details based on the
* enclosing VariableDeclarator, AssignmentExpression or ObjectExpression node. * enclosing VariableDeclarator, AssignmentExpression or ObjectExpression.
* *
* @param Node aNode * @param Node aNode
* The function expression node to get the name for. * The function expression node to get the name for.
* @return object * @return object
* The inferred function name, or empty string can't infer name, * The inferred function name, or empty string can't infer the name,
* along with the chain (a generic "context", like a prototype chain) * along with the chain (a generic "context", like a prototype chain)
* and location if available. * and location if available.
*/ */
inferFunctionExpressionInfo: function PH_inferFunctionExpressionInfo(aNode) { inferFunctionExpressionInfo: function(aNode) {
let parent = aNode._parent; let parent = aNode._parent;
// A function expression may be defined in a variable declarator, // A function expression may be defined in a variable declarator,
@ -480,11 +372,11 @@ let ParserHelpers = {
// e.g. foo = function(){} or foo.bar = function(){}, in which case it is // e.g. foo = function(){} or foo.bar = function(){}, in which case it is
// possible to infer the assignee name ("foo" and "bar" respectively). // possible to infer the assignee name ("foo" and "bar" respectively).
if (parent.type == "AssignmentExpression") { if (parent.type == "AssignmentExpression") {
let assigneeChain = this.getAssignmentExpressionAssigneeChain(parent); let propertyChain = this.getMemberExpressionPropertyChain(parent.left);
let assigneeLeaf = assigneeChain.pop(); let propertyLeaf = propertyChain.pop();
return { return {
name: assigneeLeaf, name: propertyLeaf,
chain: assigneeChain, chain: propertyChain,
loc: parent.left.loc loc: parent.left.loc
}; };
} }
@ -493,13 +385,13 @@ let ParserHelpers = {
// e.g. { foo: function(){} }, then it is possible to infer the name // e.g. { foo: function(){} }, then it is possible to infer the name
// from the corresponding property. // from the corresponding property.
if (parent.type == "ObjectExpression") { if (parent.type == "ObjectExpression") {
let propertyDetails = this.getObjectExpressionPropertyKeyForValue(aNode); let propertyKey = this.getObjectExpressionPropertyKeyForValue(aNode);
let propertyChain = this.getObjectExpressionPropertyChain(parent); let propertyChain = this.getObjectExpressionPropertyChain(parent);
let propertyLeaf = propertyDetails.name; let propertyLeaf = propertyKey.name;
return { return {
name: propertyLeaf, name: propertyLeaf,
chain: propertyChain, chain: propertyChain,
loc: propertyDetails.loc loc: propertyKey.loc
}; };
} }
@ -512,17 +404,18 @@ let ParserHelpers = {
}, },
/** /**
* Gets details about an object expression's property to which a specified * Gets the name of an object expression's property to which a specified
* value is assigned. For example, the node returned for the value 42 in * value is assigned.
* "{ foo: { bar: 42 } }" is "bar". *
* For example, if aNode represents the "bar" identifier in a hypothetical
* "{ foo: bar }" object expression, the returned node is the "foo" identifier.
* *
* @param Node aNode * @param Node aNode
* The value node assigned to a property in an object expression. * The value node in an object expression.
* @return object * @return object
* The details about the assignee property node. * The key identifier node in the object expression.
*/ */
getObjectExpressionPropertyKeyForValue: getObjectExpressionPropertyKeyForValue: function(aNode) {
function PH_getObjectExpressionPropertyKeyForValue(aNode) {
let parent = aNode._parent; let parent = aNode._parent;
if (parent.type != "ObjectExpression") { if (parent.type != "ObjectExpression") {
return null; return null;
@ -535,9 +428,12 @@ let ParserHelpers = {
}, },
/** /**
* Gets an object expression property chain to its parent variable declarator. * Gets an object expression's property chain to its parent
* For example, the chain to "baz" in "foo = { bar: { baz: { } } }" is * variable declarator or assignment expression, if available.
* ["foo", "bar", "baz"]. *
* For example, if aNode represents the "baz: {}" object expression in a
* hypothetical "foo = { bar: { baz: {} } }" assignment expression, the
* returned chain is ["foo", "bar", "baz"].
* *
* @param Node aNode * @param Node aNode
* The object expression node to begin the scan from. * The object expression node to begin the scan from.
@ -546,59 +442,56 @@ let ParserHelpers = {
* @return array * @return array
* The chain to the parent variable declarator, as strings. * The chain to the parent variable declarator, as strings.
*/ */
getObjectExpressionPropertyChain: getObjectExpressionPropertyChain: function(aNode, aStore = []) {
function PH_getObjectExpressionPropertyChain(aNode, aStore = []) {
switch (aNode.type) { switch (aNode.type) {
case "ObjectExpression": case "ObjectExpression":
this.getObjectExpressionPropertyChain(aNode._parent, aStore); this.getObjectExpressionPropertyChain(aNode._parent, aStore);
let propertyKey = this.getObjectExpressionPropertyKeyForValue(aNode);
let propertyDetails = this.getObjectExpressionPropertyKeyForValue(aNode); if (propertyKey) {
if (propertyDetails) { aStore.push(propertyKey.name);
aStore.push(this.getObjectExpressionPropertyKeyForValue(aNode).name);
} }
break; break;
// Handle "foo.bar = { ... }" since it's commonly used when defining an // Handle "var foo = { ... }" variable declarators.
// object's prototype methods; for example: "Foo.prototype = { ... }". case "VariableDeclarator":
aStore.push(aNode.id.name);
break;
// Handle "foo.bar = { ... }" assignment expressions, since they're
// commonly used when defining an object's prototype methods; e.g:
// "Foo.prototype = { ... }".
case "AssignmentExpression": case "AssignmentExpression":
this.getAssignmentExpressionAssigneeChain(aNode, aStore); this.getMemberExpressionPropertyChain(aNode.left, aStore);
break; break;
// Additionally handle stuff like "foo = bar.baz({ ... })", because it's // Additionally handle stuff like "foo = bar.baz({ ... })", because it's
// commonly used in prototype-based inheritance in many libraries; // commonly used in prototype-based inheritance in many libraries; e.g:
// for example: "Foo.Bar = Baz.extend({ ... })". // "Foo = Bar.extend({ ... })".
case "NewExpression": case "NewExpression":
case "CallExpression": case "CallExpression":
this.getObjectExpressionPropertyChain(aNode._parent, aStore); this.getObjectExpressionPropertyChain(aNode._parent, aStore);
break; break;
// End of the chain.
case "VariableDeclarator":
aStore.push(aNode.id.name);
break;
} }
return aStore; return aStore;
}, },
/** /**
* Gets the assignee property chain in an assignment expression. * Gets a member expression's property chain.
* For example, the chain in "foo.bar.baz = 42" is ["foo", "bar", "baz"]. *
* For example, if aNode represents a hypothetical "foo.bar.baz"
* member expression, the returned chain ["foo", "bar", "baz"].
*
* More complex expressions like foo.bar().baz are intentionally not handled.
* *
* @param Node aNode * @param Node aNode
* The assignment expression node to begin the scan from. * The member expression node to begin the scan from.
* @param array aStore
* The chain to store the nodes into.
* @param array aStore [optional] * @param array aStore [optional]
* The chain to store the nodes into. * The chain to store the nodes into.
* @return array * @return array
* The full assignee chain, as strings. * The full member chain, as strings.
*/ */
getAssignmentExpressionAssigneeChain: getMemberExpressionPropertyChain: function(aNode, aStore = []) {
function PH_getAssignmentExpressionAssigneeChain(aNode, aStore = []) {
switch (aNode.type) { switch (aNode.type) {
case "AssignmentExpression":
this.getAssignmentExpressionAssigneeChain(aNode.left, aStore);
break;
case "MemberExpression": case "MemberExpression":
this.getAssignmentExpressionAssigneeChain(aNode.object, aStore); this.getMemberExpressionPropertyChain(aNode.object, aStore);
this.getAssignmentExpressionAssigneeChain(aNode.property, aStore); this.getMemberExpressionPropertyChain(aNode.property, aStore);
break; break;
case "ThisExpression": case "ThisExpression":
// Such expressions may appear in an assignee chain, for example // Such expressions may appear in an assignee chain, for example
@ -610,80 +503,6 @@ let ParserHelpers = {
break; break;
} }
return aStore; return aStore;
},
/**
* Gets the "new" expression or "call" expression containing the specified
* node. If the node is not enclosed in either of these expression types,
* null is returned.
*
* @param Node aNode
* The child node of an enclosing "new" expression or "call" expression.
* @return Node
* The enclosing "new" expression or "call" expression node, or
* null if nothing is found.
*/
getEnclosingFunctionExpression:
function PH_getEnclosingFunctionExpression(aNode) {
switch (aNode.type) {
case "NewExpression":
case "CallExpression":
return aNode;
case "MemberExpression":
case "Identifier":
return this.getEnclosingFunctionExpression(aNode._parent);
default:
return null;
}
},
/**
* Gets the name and { line, column } location of a "new" expression or
* "call" expression's callee node.
*
* @param Node aNode
* The "new" expression or "call" expression to get the callee info for.
* @return object
* An object containing the name and location as properties, or
* null if nothing is found.
*/
getFunctionCalleeInfo: function PH_getFunctionCalleeInfo(aNode) {
switch (aNode.type) {
case "NewExpression":
case "CallExpression":
return this.getFunctionCalleeInfo(aNode.callee);
case "MemberExpression":
return this.getFunctionCalleeInfo(aNode.property);
case "Identifier":
return {
name: aNode.name,
loc: aNode.loc || (aNode._parent || {}).loc
};
default:
return null;
}
},
/**
* Determines if an identifier node is part of a "new" expression or
* "call" expression's callee arguments.
*
* @param Node aNode
* The node to determine if part of a function's arguments.
* @return boolean
* True if the identifier is an argument, false otherwise.
*/
isFunctionCalleeArgument: function PH_isFunctionCalleeArgument(aNode) {
if (!aNode._parent) {
return false;
}
switch (aNode._parent.type) {
case "NewExpression":
case "CallExpression":
return aNode._parent.arguments.indexOf(aNode) != -1;
default:
return this.isFunctionCalleeArgument(aNode._parent);
}
} }
}; };
@ -707,7 +526,7 @@ let SyntaxTreeVisitor = {
* A map of all the callbacks to invoke when passing through certain * A map of all the callbacks to invoke when passing through certain
* types of noes (e.g: onFunctionDeclaration, onBlockStatement etc.). * types of noes (e.g: onFunctionDeclaration, onBlockStatement etc.).
*/ */
walk: function STV_walk(aTree, aCallbacks) { walk: function(aTree, aCallbacks) {
this[aTree.type](aTree, aCallbacks); this[aTree.type](aTree, aCallbacks);
}, },
@ -725,7 +544,7 @@ let SyntaxTreeVisitor = {
* body: [ Statement ]; * body: [ Statement ];
* } * }
*/ */
Program: function STV_Program(aNode, aCallbacks) { Program: function(aNode, aCallbacks) {
if (aCallbacks.onProgram) { if (aCallbacks.onProgram) {
aCallbacks.onProgram(aNode); aCallbacks.onProgram(aNode);
} }
@ -739,7 +558,7 @@ let SyntaxTreeVisitor = {
* *
* interface Statement <: Node { } * interface Statement <: Node { }
*/ */
Statement: function STV_Statement(aNode, aParent, aCallbacks) { Statement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -762,7 +581,7 @@ let SyntaxTreeVisitor = {
* type: "EmptyStatement"; * type: "EmptyStatement";
* } * }
*/ */
EmptyStatement: function STV_EmptyStatement(aNode, aParent, aCallbacks) { EmptyStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -786,7 +605,7 @@ let SyntaxTreeVisitor = {
* body: [ Statement ]; * body: [ Statement ];
* } * }
*/ */
BlockStatement: function STV_BlockStatement(aNode, aParent, aCallbacks) { BlockStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -813,7 +632,7 @@ let SyntaxTreeVisitor = {
* expression: Expression; * expression: Expression;
* } * }
*/ */
ExpressionStatement: function STV_ExpressionStatement(aNode, aParent, aCallbacks) { ExpressionStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -840,7 +659,7 @@ let SyntaxTreeVisitor = {
* alternate: Statement | null; * alternate: Statement | null;
* } * }
*/ */
IfStatement: function STV_IfStatement(aNode, aParent, aCallbacks) { IfStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -870,7 +689,7 @@ let SyntaxTreeVisitor = {
* body: Statement; * body: Statement;
* } * }
*/ */
LabeledStatement: function STV_LabeledStatement(aNode, aParent, aCallbacks) { LabeledStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -896,7 +715,7 @@ let SyntaxTreeVisitor = {
* label: Identifier | null; * label: Identifier | null;
* } * }
*/ */
BreakStatement: function STV_BreakStatement(aNode, aParent, aCallbacks) { BreakStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -923,7 +742,7 @@ let SyntaxTreeVisitor = {
* label: Identifier | null; * label: Identifier | null;
* } * }
*/ */
ContinueStatement: function STV_ContinueStatement(aNode, aParent, aCallbacks) { ContinueStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -951,7 +770,7 @@ let SyntaxTreeVisitor = {
* body: Statement; * body: Statement;
* } * }
*/ */
WithStatement: function STV_WithStatement(aNode, aParent, aCallbacks) { WithStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -981,7 +800,7 @@ let SyntaxTreeVisitor = {
* lexical: boolean; * lexical: boolean;
* } * }
*/ */
SwitchStatement: function STV_SwitchStatement(aNode, aParent, aCallbacks) { SwitchStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1009,7 +828,7 @@ let SyntaxTreeVisitor = {
* argument: Expression | null; * argument: Expression | null;
* } * }
*/ */
ReturnStatement: function STV_ReturnStatement(aNode, aParent, aCallbacks) { ReturnStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1036,7 +855,7 @@ let SyntaxTreeVisitor = {
* argument: Expression; * argument: Expression;
* } * }
*/ */
ThrowStatement: function STV_ThrowStatement(aNode, aParent, aCallbacks) { ThrowStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1064,7 +883,7 @@ let SyntaxTreeVisitor = {
* finalizer: BlockStatement | null; * finalizer: BlockStatement | null;
* } * }
*/ */
TryStatement: function STV_TryStatement(aNode, aParent, aCallbacks) { TryStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1099,7 +918,7 @@ let SyntaxTreeVisitor = {
* body: Statement; * body: Statement;
* } * }
*/ */
WhileStatement: function STV_WhileStatement(aNode, aParent, aCallbacks) { WhileStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1126,7 +945,7 @@ let SyntaxTreeVisitor = {
* test: Expression; * test: Expression;
* } * }
*/ */
DoWhileStatement: function STV_DoWhileStatement(aNode, aParent, aCallbacks) { DoWhileStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1155,7 +974,7 @@ let SyntaxTreeVisitor = {
* body: Statement; * body: Statement;
* } * }
*/ */
ForStatement: function STV_ForStatement(aNode, aParent, aCallbacks) { ForStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1192,7 +1011,7 @@ let SyntaxTreeVisitor = {
* each: boolean; * each: boolean;
* } * }
*/ */
ForInStatement: function STV_ForInStatement(aNode, aParent, aCallbacks) { ForInStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1221,7 +1040,7 @@ let SyntaxTreeVisitor = {
* body: Statement; * body: Statement;
* } * }
*/ */
ForOfStatement: function STV_ForOfStatement(aNode, aParent, aCallbacks) { ForOfStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1249,7 +1068,7 @@ let SyntaxTreeVisitor = {
* body: Statement; * body: Statement;
* } * }
*/ */
LetStatement: function STV_LetStatement(aNode, aParent, aCallbacks) { LetStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1279,7 +1098,7 @@ let SyntaxTreeVisitor = {
* type: "DebuggerStatement"; * type: "DebuggerStatement";
* } * }
*/ */
DebuggerStatement: function STV_DebuggerStatement(aNode, aParent, aCallbacks) { DebuggerStatement: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1302,7 +1121,7 @@ let SyntaxTreeVisitor = {
* *
* interface Declaration <: Statement { } * interface Declaration <: Statement { }
*/ */
Declaration: function STV_Declaration(aNode, aParent, aCallbacks) { Declaration: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1332,7 +1151,7 @@ let SyntaxTreeVisitor = {
* expression: boolean; * expression: boolean;
* } * }
*/ */
FunctionDeclaration: function STV_FunctionDeclaration(aNode, aParent, aCallbacks) { FunctionDeclaration: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1368,7 +1187,7 @@ let SyntaxTreeVisitor = {
* kind: "var" | "let" | "const"; * kind: "var" | "let" | "const";
* } * }
*/ */
VariableDeclaration: function STV_VariableDeclaration(aNode, aParent, aCallbacks) { VariableDeclaration: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1396,7 +1215,7 @@ let SyntaxTreeVisitor = {
* init: Expression | null; * init: Expression | null;
* } * }
*/ */
VariableDeclarator: function STV_VariableDeclarator(aNode, aParent, aCallbacks) { VariableDeclarator: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1422,7 +1241,7 @@ let SyntaxTreeVisitor = {
* *
* interface Expression <: Node, Pattern { } * interface Expression <: Node, Pattern { }
*/ */
Expression: function STV_Expression(aNode, aParent, aCallbacks) { Expression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1445,7 +1264,7 @@ let SyntaxTreeVisitor = {
* type: "ThisExpression"; * type: "ThisExpression";
* } * }
*/ */
ThisExpression: function STV_ThisExpression(aNode, aParent, aCallbacks) { ThisExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1469,7 +1288,7 @@ let SyntaxTreeVisitor = {
* elements: [ Expression | null ]; * elements: [ Expression | null ];
* } * }
*/ */
ArrayExpression: function STV_ArrayExpression(aNode, aParent, aCallbacks) { ArrayExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1505,7 +1324,7 @@ let SyntaxTreeVisitor = {
* kind: "init" | "get" | "set" } ]; * kind: "init" | "get" | "set" } ];
* } * }
*/ */
ObjectExpression: function STV_ObjectExpression(aNode, aParent, aCallbacks) { ObjectExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1539,7 +1358,7 @@ let SyntaxTreeVisitor = {
* expression: boolean; * expression: boolean;
* } * }
*/ */
FunctionExpression: function STV_FunctionExpression(aNode, aParent, aCallbacks) { FunctionExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1581,7 +1400,7 @@ let SyntaxTreeVisitor = {
* expression: boolean; * expression: boolean;
* } * }
*/ */
ArrowExpression: function STV_ArrowExpression(aNode, aParent, aCallbacks) { ArrowExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1615,7 +1434,7 @@ let SyntaxTreeVisitor = {
* expressions: [ Expression ]; * expressions: [ Expression ];
* } * }
*/ */
SequenceExpression: function STV_SequenceExpression(aNode, aParent, aCallbacks) { SequenceExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1644,7 +1463,7 @@ let SyntaxTreeVisitor = {
* argument: Expression; * argument: Expression;
* } * }
*/ */
UnaryExpression: function STV_UnaryExpression(aNode, aParent, aCallbacks) { UnaryExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1671,7 +1490,7 @@ let SyntaxTreeVisitor = {
* right: Expression; * right: Expression;
* } * }
*/ */
BinaryExpression: function STV_BinaryExpression(aNode, aParent, aCallbacks) { BinaryExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1699,7 +1518,7 @@ let SyntaxTreeVisitor = {
* right: Expression; * right: Expression;
* } * }
*/ */
AssignmentExpression: function STV_AssignmentExpression(aNode, aParent, aCallbacks) { AssignmentExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1727,7 +1546,7 @@ let SyntaxTreeVisitor = {
* prefix: boolean; * prefix: boolean;
* } * }
*/ */
UpdateExpression: function STV_UpdateExpression(aNode, aParent, aCallbacks) { UpdateExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1754,7 +1573,7 @@ let SyntaxTreeVisitor = {
* right: Expression; * right: Expression;
* } * }
*/ */
LogicalExpression: function STV_LogicalExpression(aNode, aParent, aCallbacks) { LogicalExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1782,7 +1601,7 @@ let SyntaxTreeVisitor = {
* consequent: Expression; * consequent: Expression;
* } * }
*/ */
ConditionalExpression: function STV_ConditionalExpression(aNode, aParent, aCallbacks) { ConditionalExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1810,7 +1629,7 @@ let SyntaxTreeVisitor = {
* arguments: [ Expression | null ]; * arguments: [ Expression | null ];
* } * }
*/ */
NewExpression: function STV_NewExpression(aNode, aParent, aCallbacks) { NewExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1841,7 +1660,7 @@ let SyntaxTreeVisitor = {
* arguments: [ Expression | null ]; * arguments: [ Expression | null ];
* } * }
*/ */
CallExpression: function STV_CallExpression(aNode, aParent, aCallbacks) { CallExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1876,7 +1695,7 @@ let SyntaxTreeVisitor = {
* computed: boolean; * computed: boolean;
* } * }
*/ */
MemberExpression: function STV_MemberExpression(aNode, aParent, aCallbacks) { MemberExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1901,7 +1720,7 @@ let SyntaxTreeVisitor = {
* argument: Expression | null; * argument: Expression | null;
* } * }
*/ */
YieldExpression: function STV_YieldExpression(aNode, aParent, aCallbacks) { YieldExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1931,7 +1750,7 @@ let SyntaxTreeVisitor = {
* filter: Expression | null; * filter: Expression | null;
* } * }
*/ */
ComprehensionExpression: function STV_ComprehensionExpression(aNode, aParent, aCallbacks) { ComprehensionExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1965,7 +1784,7 @@ let SyntaxTreeVisitor = {
* filter: Expression | null; * filter: Expression | null;
* } * }
*/ */
GeneratorExpression: function STV_GeneratorExpression(aNode, aParent, aCallbacks) { GeneratorExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -1996,7 +1815,7 @@ let SyntaxTreeVisitor = {
* expression: Literal; * expression: Literal;
* } * }
*/ */
GraphExpression: function STV_GraphExpression(aNode, aParent, aCallbacks) { GraphExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2020,7 +1839,7 @@ let SyntaxTreeVisitor = {
* index: uint32; * index: uint32;
* } * }
*/ */
GraphIndexExpression: function STV_GraphIndexExpression(aNode, aParent, aCallbacks) { GraphIndexExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2045,7 +1864,7 @@ let SyntaxTreeVisitor = {
* body: Expression; * body: Expression;
* } * }
*/ */
LetExpression: function STV_LetExpression(aNode, aParent, aCallbacks) { LetExpression: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2073,7 +1892,7 @@ let SyntaxTreeVisitor = {
* *
* interface Pattern <: Node { } * interface Pattern <: Node { }
*/ */
Pattern: function STV_Pattern(aNode, aParent, aCallbacks) { Pattern: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2098,7 +1917,7 @@ let SyntaxTreeVisitor = {
* properties: [ { key: Literal | Identifier, value: Pattern } ]; * properties: [ { key: Literal | Identifier, value: Pattern } ];
* } * }
*/ */
ObjectPattern: function STV_ObjectPattern(aNode, aParent, aCallbacks) { ObjectPattern: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2126,7 +1945,7 @@ let SyntaxTreeVisitor = {
* elements: [ Pattern | null ]; * elements: [ Pattern | null ];
* } * }
*/ */
ArrayPattern: function STV_ArrayPattern(aNode, aParent, aCallbacks) { ArrayPattern: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2157,7 +1976,7 @@ let SyntaxTreeVisitor = {
* consequent: [ Statement ]; * consequent: [ Statement ];
* } * }
*/ */
SwitchCase: function STV_SwitchCase(aNode, aParent, aCallbacks) { SwitchCase: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2190,7 +2009,7 @@ let SyntaxTreeVisitor = {
* body: BlockStatement; * body: BlockStatement;
* } * }
*/ */
CatchClause: function STV_CatchClause(aNode, aParent, aCallbacks) { CatchClause: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2220,7 +2039,7 @@ let SyntaxTreeVisitor = {
* each: boolean; * each: boolean;
* } * }
*/ */
ComprehensionBlock: function STV_ComprehensionBlock(aNode, aParent, aCallbacks) { ComprehensionBlock: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2247,7 +2066,7 @@ let SyntaxTreeVisitor = {
* name: string; * name: string;
* } * }
*/ */
Identifier: function STV_Identifier(aNode, aParent, aCallbacks) { Identifier: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {
@ -2271,7 +2090,7 @@ let SyntaxTreeVisitor = {
* value: string | boolean | null | number | RegExp; * value: string | boolean | null | number | RegExp;
* } * }
*/ */
Literal: function STV_Literal(aNode, aParent, aCallbacks) { Literal: function(aNode, aParent, aCallbacks) {
aNode._parent = aParent; aNode._parent = aParent;
if (this.break) { if (this.break) {

Просмотреть файл

@ -35,7 +35,10 @@
winUtils.loadSheet(newThemeUrl, winUtils.AUTHOR_SHEET); winUtils.loadSheet(newThemeUrl, winUtils.AUTHOR_SHEET);
// Floating scrollbars à la osx // Floating scrollbars à la osx
if (!window.matchMedia("(-moz-overlay-scrollbars)").matches) { let hiddenDOMWindow = Cc["@mozilla.org/appshell/appShellService;1"]
.getService(Ci.nsIAppShellService)
.hiddenDOMWindow;
if (!hiddenDOMWindow.matchMedia("(-moz-overlay-scrollbars)").matches) {
let scrollbarsUrl = Services.io.newURI( let scrollbarsUrl = Services.io.newURI(
DEVTOOLS_SKIN_URL + "floating-scrollbars-light.css", null, null); DEVTOOLS_SKIN_URL + "floating-scrollbars-light.css", null, null);

Просмотреть файл

@ -167,7 +167,7 @@ SideMenuWidget.prototype = {
* The element associated with the displayed item. * The element associated with the displayed item.
*/ */
removeChild: function(aChild) { removeChild: function(aChild) {
if (aChild.className == "side-menu-widget-item-contents") { if (aChild.classList.contains("side-menu-widget-item-contents")) {
// Remove the item itself, not the contents. // Remove the item itself, not the contents.
aChild.parentNode.remove(); aChild.parentNode.remove();
} else { } else {

Просмотреть файл

@ -21,6 +21,7 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource:///modules/devtools/ViewHelpers.jsm"); Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
Cu.import("resource:///modules/devtools/shared/event-emitter.js"); Cu.import("resource:///modules/devtools/shared/event-emitter.js");
Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "devtools", XPCOMUtils.defineLazyModuleGetter(this, "devtools",
"resource://gre/modules/devtools/Loader.jsm"); "resource://gre/modules/devtools/Loader.jsm");
@ -108,7 +109,9 @@ VariablesView.prototype = {
*/ */
set rawObject(aObject) { set rawObject(aObject) {
this.empty(); this.empty();
this.addScope().addItem().populate(aObject, { sorted: true }); this.addScope()
.addItem("", { enumerable: true })
.populate(aObject, { sorted: true });
}, },
/** /**
@ -1120,14 +1123,6 @@ function Scope(aView, aName, aFlags = {}) {
this.contextMenuId = aView.contextMenuId; this.contextMenuId = aView.contextMenuId;
this.separatorStr = aView.separatorStr; this.separatorStr = aView.separatorStr;
// Creating maps and arrays thousands of times for variables or properties
// with a large number of children fills up a lot of memory. Make sure
// these are instantiated only if needed.
XPCOMUtils.defineLazyGetter(this, "_store", () => new Map());
XPCOMUtils.defineLazyGetter(this, "_enumItems", () => []);
XPCOMUtils.defineLazyGetter(this, "_nonEnumItems", () => []);
XPCOMUtils.defineLazyGetter(this, "_batchItems", () => []);
this._init(aName.trim(), aFlags); this._init(aName.trim(), aFlags);
} }
@ -1649,7 +1644,8 @@ Scope.prototype = {
* The click listener for this scope's title. * The click listener for this scope's title.
*/ */
_onClick: function(e) { _onClick: function(e) {
if (e.target == this._inputNode || if (e.button != 0 ||
e.target == this._inputNode ||
e.target == this._editNode || e.target == this._editNode ||
e.target == this._deleteNode) { e.target == this._deleteNode) {
return; return;
@ -2036,6 +2032,14 @@ Scope.prototype = {
_throbber: null _throbber: null
}; };
// Creating maps and arrays thousands of times for variables or properties
// with a large number of children fills up a lot of memory. Make sure
// these are instantiated only if needed.
DevToolsUtils.defineLazyPrototypeGetter(Scope.prototype, "_store", Map);
DevToolsUtils.defineLazyPrototypeGetter(Scope.prototype, "_enumItems", Array);
DevToolsUtils.defineLazyPrototypeGetter(Scope.prototype, "_nonEnumItems", Array);
DevToolsUtils.defineLazyPrototypeGetter(Scope.prototype, "_batchItems", Array);
/** /**
* A Variable is a Scope holding Property instances. * A Variable is a Scope holding Property instances.
* Iterable via "for (let [name, property] in instance) { }". * Iterable via "for (let [name, property] in instance) { }".
@ -2776,6 +2780,10 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
* The click listener for the edit button. * The click listener for the edit button.
*/ */
_onEdit: function(e) { _onEdit: function(e) {
if (e.button != 0) {
return;
}
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
this._activateValueInput(); this._activateValueInput();
@ -2785,6 +2793,10 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
* The click listener for the delete button. * The click listener for the delete button.
*/ */
_onDelete: function(e) { _onDelete: function(e) {
if ("button" in e && e.button != 0) {
return;
}
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();

Просмотреть файл

@ -1283,13 +1283,13 @@ CssRuleView.prototype = {
{ {
// Ignore refreshes during editing or when no element is selected. // Ignore refreshes during editing or when no element is selected.
if (this.isEditing || !this._elementStyle) { if (this.isEditing || !this._elementStyle) {
return promise.resolve(null); return;
} }
this._clearRules(); this._clearRules();
// Repopulate the element style. // Repopulate the element style.
return this._populate(); this._populate();
}, },
_populate: function() { _populate: function() {

Просмотреть файл

@ -7,6 +7,7 @@ let doc;
let inspector; let inspector;
let ruleView; let ruleView;
let testElement; let testElement;
let rule;
function startTest(aInspector, aRuleView) function startTest(aInspector, aRuleView)
{ {
@ -29,9 +30,7 @@ function startTest(aInspector, aRuleView)
testElement.setAttribute("style", elementStyle); testElement.setAttribute("style", elementStyle);
inspector.selection.setNode(testElement); inspector.selection.setNode(testElement);
inspector.once("inspector-updated", () => { inspector.once("rule-view-refreshed", testRuleChanges);
testRuleChanges();
}, true);
} }
function testRuleChanges() function testRuleChanges()
@ -43,25 +42,29 @@ function testRuleChanges()
is(selectors[2].textContent.indexOf(".testclass"), 0, "Third item is class rule."); is(selectors[2].textContent.indexOf(".testclass"), 0, "Third item is class rule.");
// Change the id and refresh. // Change the id and refresh.
inspector.once("rule-view-refreshed", testRuleChange1);
testElement.setAttribute("id", "differentid"); testElement.setAttribute("id", "differentid");
promiseDone(ruleView.nodeChanged().then(() => { }
let selectors = ruleView.doc.querySelectorAll(".ruleview-selector");
is(selectors.length, 2, "Two rules visible.");
is(selectors[0].textContent.indexOf("element"), 0, "First item is inline style.");
is(selectors[1].textContent.indexOf(".testclass"), 0, "Second item is class rule.");
testElement.setAttribute("id", "testid"); function testRuleChange1()
return ruleView.nodeChanged(); {
}).then(() => { let selectors = ruleView.doc.querySelectorAll(".ruleview-selector");
// Put the id back. is(selectors.length, 2, "Two rules visible.");
let selectors = ruleView.doc.querySelectorAll(".ruleview-selector"); is(selectors[0].textContent.indexOf("element"), 0, "First item is inline style.");
is(selectors.length, 3, "Three rules visible."); is(selectors[1].textContent.indexOf(".testclass"), 0, "Second item is class rule.");
is(selectors[0].textContent.indexOf("element"), 0, "First item is inline style.");
is(selectors[1].textContent.indexOf("#testid"), 0, "Second item is id rule.");
is(selectors[2].textContent.indexOf(".testclass"), 0, "Third item is class rule.");
testPropertyChanges(); inspector.once("rule-view-refreshed", testRuleChange2);
})); testElement.setAttribute("id", "testid");
}
function testRuleChange2()
{
let selectors = ruleView.doc.querySelectorAll(".ruleview-selector");
is(selectors.length, 3, "Three rules visible.");
is(selectors[0].textContent.indexOf("element"), 0, "First item is inline style.");
is(selectors[1].textContent.indexOf("#testid"), 0, "Second item is id rule.");
is(selectors[2].textContent.indexOf(".testclass"), 0, "Third item is class rule.");
testPropertyChanges();
} }
function validateTextProp(aProp, aEnabled, aName, aValue, aDesc) function validateTextProp(aProp, aEnabled, aName, aValue, aDesc)
@ -77,65 +80,86 @@ function validateTextProp(aProp, aEnabled, aName, aValue, aDesc)
function testPropertyChanges() function testPropertyChanges()
{ {
// Add a second margin-top value, just to make things interesting. rule = ruleView._elementStyle.rules[0];
let rule = ruleView._elementStyle.rules[0];
let ruleEditor = ruleView._elementStyle.rules[0].editor; let ruleEditor = ruleView._elementStyle.rules[0].editor;
inspector.once("rule-view-refreshed", testPropertyChange0);
// Add a second margin-top value, just to make things interesting.
ruleEditor.addProperty("margin-top", "5px", ""); ruleEditor.addProperty("margin-top", "5px", "");
promiseDone(expectRuleChange(rule).then(() => { }
// Set the element style back to a 1px margin-top.
testElement.setAttribute("style", "margin-top: 1px; padding-top: 5px");
return ruleView.nodeChanged();
}).then(() => {
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
validateTextProp(rule.textProps[0], true, "margin-top", "1px", "First margin property re-enabled");
validateTextProp(rule.textProps[2], false, "margin-top", "5px", "Second margin property disabled");
// Now set it back to 5px, the 5px value should be re-enabled. function testPropertyChange0()
testElement.setAttribute("style", "margin-top: 5px; padding-top: 5px;"); {
return ruleView.nodeChanged(); validateTextProp(rule.textProps[0], false, "margin-top", "1px", "Original margin property active");
}).then(() => { inspector.once("rule-view-refreshed", testPropertyChange1);
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); testElement.setAttribute("style", "margin-top: 1px; padding-top: 5px");
validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled"); }
validateTextProp(rule.textProps[2], true, "margin-top", "5px", "Second margin property disabled"); function testPropertyChange1()
{
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
validateTextProp(rule.textProps[0], true, "margin-top", "1px", "First margin property re-enabled");
validateTextProp(rule.textProps[2], false, "margin-top", "5px", "Second margin property disabled");
// Set the margin property to a value that doesn't exist in the editor. inspector.once("rule-view-refreshed", testPropertyChange2);
// Should reuse the currently-enabled element (the second one.)
testElement.setAttribute("style", "margin-top: 15px; padding-top: 5px;");
return ruleView.nodeChanged();
}).then(() => {
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled");
validateTextProp(rule.textProps[2], true, "margin-top", "15px", "Second margin property disabled");
// Remove the padding-top attribute. Should disable the padding property but not remove it. // Now set it back to 5px, the 5px value should be re-enabled.
testElement.setAttribute("style", "margin-top: 5px;"); testElement.setAttribute("style", "margin-top: 5px; padding-top: 5px;");
return ruleView.nodeChanged(); }
}).then(() => { function testPropertyChange2()
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); {
validateTextProp(rule.textProps[1], false, "padding-top", "5px", "Padding property disabled"); is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled");
validateTextProp(rule.textProps[2], true, "margin-top", "5px", "Second margin property disabled");
// Put the padding-top attribute back in, should re-enable the padding property. inspector.once("rule-view-refreshed", testPropertyChange3);
testElement.setAttribute("style", "margin-top: 5px; padding-top: 25px");
return ruleView.nodeChanged();
}).then(() => {
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
validateTextProp(rule.textProps[1], true, "padding-top", "25px", "Padding property enabled");
// Add an entirely new property. // Set the margin property to a value that doesn't exist in the editor.
testElement.setAttribute("style", "margin-top: 5px; padding-top: 25px; padding-left: 20px;"); // Should reuse the currently-enabled element (the second one.)
return ruleView.nodeChanged(); testElement.setAttribute("style", "margin-top: 15px; padding-top: 5px;");
}).then(() => { }
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 4, "Added a property"); function testPropertyChange3()
validateTextProp(rule.textProps[3], true, "padding-left", "20px", "Padding property enabled"); {
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled");
validateTextProp(rule.textProps[2], true, "margin-top", "15px", "Second margin property disabled");
finishTest(); inspector.once("rule-view-refreshed", testPropertyChange4);
}));
// Remove the padding-top attribute. Should disable the padding property but not remove it.
testElement.setAttribute("style", "margin-top: 5px;");
}
function testPropertyChange4()
{
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
validateTextProp(rule.textProps[1], false, "padding-top", "5px", "Padding property disabled");
inspector.once("rule-view-refreshed", testPropertyChange5);
// Put the padding-top attribute back in, should re-enable the padding property.
testElement.setAttribute("style", "margin-top: 5px; padding-top: 25px");
}
function testPropertyChange5()
{
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
validateTextProp(rule.textProps[1], true, "padding-top", "25px", "Padding property enabled");
inspector.once("rule-view-refreshed", testPropertyChange6);
// Add an entirely new property
testElement.setAttribute("style", "margin-top: 5px; padding-top: 25px; padding-left: 20px;");
}
function testPropertyChange6()
{
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 4, "Added a property");
validateTextProp(rule.textProps[3], true, "padding-left", "20px", "Padding property enabled");
finishTest();
} }
function finishTest() function finishTest()
{ {
inspector = ruleView = null; inspector = ruleView = rule = null;
doc = null; doc = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

Просмотреть файл

@ -73,6 +73,7 @@
<!ENTITY projects.debugAppTooltip "Open Developer Tools connected to this app"> <!ENTITY projects.debugAppTooltip "Open Developer Tools connected to this app">
<!ENTITY projects.hostedManifestPlaceHolder2 "http://example.com/app/manifest.webapp"> <!ENTITY projects.hostedManifestPlaceHolder2 "http://example.com/app/manifest.webapp">
<!ENTITY projects.noProjects "No projects. Add a new packaged app below (local directory) or a hosted app (link to a manifest file)."> <!ENTITY projects.noProjects "No projects. Add a new packaged app below (local directory) or a hosted app (link to a manifest file).">
<!ENTITY projects.manifestEditor "Manifest Editor">
<!ENTITY help.title "App Manager"> <!ENTITY help.title "App Manager">
<!ENTITY help.close "Close"> <!ENTITY help.close "Close">

Просмотреть файл

@ -19,4 +19,4 @@
<!ENTITY errorTimeout "Error: connection timeout."> <!ENTITY errorTimeout "Error: connection timeout.">
<!ENTITY errorRefused "Error: connection refused."> <!ENTITY errorRefused "Error: connection refused.">
<!ENTITY errorUnexpected "Unexpected error."> <!ENTITY errorUnexpected "Unexpected error.">
<!ENTITY help "Firefox Developer Tools can debug remote devices (Firefox for Android and Firefox OS, for example). Make sure that you have turned on the 'Remote debugging' option in the remote device. See the <a target='_' href='https://developer.mozilla.org/docs/Tools/Debugger#Remote_Debugging'>documentation</a> for more."> <!ENTITY help2 "Firefox Developer Tools can debug remote devices (Firefox for Android and Firefox OS, for example). Make sure that you have turned on the 'Remote debugging' option in the remote device. See the <a target='_' href='https://developer.mozilla.org/docs/Tools/Remote_Debugging'>documentation</a> for more.">

Просмотреть файл

@ -548,6 +548,7 @@ let DOMEvents = {
DOMEvents.init(); DOMEvents.init();
let ContentScroll = { let ContentScroll = {
// The most recent offset set by APZC for the root scroll frame
_scrollOffset: { x: 0, y: 0 }, _scrollOffset: { x: 0, y: 0 },
init: function() { init: function() {
@ -617,9 +618,13 @@ let ContentScroll = {
// Set the scroll offset for this element if specified // Set the scroll offset for this element if specified
if (json.scrollX >= 0 || json.scrollY >= 0) { if (json.scrollX >= 0 || json.scrollY >= 0) {
this.setScrollOffsetForElement(element, json.scrollX, json.scrollY) this.setScrollOffsetForElement(element, json.scrollX, json.scrollY);
if (json.id == 1) if (element == content.document.documentElement) {
// scrollTo can make some small adjustments to the offset before
// actually scrolling the document. To ensure that _scrollOffset
// actually matches the offset stored in the window, re-query it.
this._scrollOffset = this.getScrollOffset(content); this._scrollOffset = this.getScrollOffset(content);
}
} }
// Set displayport. We want to set this after setting the scroll offset, because // Set displayport. We want to set this after setting the scroll offset, because
@ -690,6 +695,9 @@ let ContentScroll = {
if (target == content.document) { if (target == content.document) {
if (this._scrollOffset.x == scrollOffset.x && this._scrollOffset.y == scrollOffset.y) { if (this._scrollOffset.x == scrollOffset.x && this._scrollOffset.y == scrollOffset.y) {
// Don't send a scroll message back to APZC if it's the same as the
// last one set by APZC. We use this to avoid sending APZC back an
// event that it originally triggered.
return; return;
} }
this._scrollOffset = scrollOffset; this._scrollOffset = scrollOffset;

Просмотреть файл

@ -66,6 +66,10 @@
display: none; display: none;
} }
#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow {
background-image: none;
}
/* Black box message and source progress meter */ /* Black box message and source progress meter */
#black-boxed-message, #black-boxed-message,

Просмотреть файл

@ -64,6 +64,10 @@
display: none; display: none;
} }
#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow {
background-image: none;
}
/* Black box message and source progress meter */ /* Black box message and source progress meter */
#black-boxed-message, #black-boxed-message,

Просмотреть файл

@ -231,6 +231,7 @@ strong {
#lense > div { #lense > div {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
flex-direction: column;
} }
@ -240,8 +241,13 @@ strong {
.project-details { .project-details {
background-color: rgb(225, 225, 225); background-color: rgb(225, 225, 225);
padding: 10px; padding: 10px;
flex-grow: 1;
line-height: 160%; line-height: 160%;
display: flex;
flex-direction: column;
}
.project-metadata {
flex-grow: 1;
} }
.project-status { .project-status {
@ -438,3 +444,44 @@ strong {
padding-left: 16px; padding-left: 16px;
font-weight: bold; font-weight: bold;
} }
/********* MANIFEST EDITOR ***********/
.manifest-editor {
display: flex;
flex-direction: column;
flex-grow: 1;
background-color: #E1E1E1;
}
.manifest-editor > h2 {
font-size: 18px;
margin: 1em 30px;
}
.variables-view {
flex-grow: 1;
border: 0;
border-top: 5px solid #C9C9C9;
}
/* Bug 925921: Remove when the manifest editor is always on */
.manifest-editor {
display: none;
}
.project-details {
flex-grow: 1;
}
#lense[manifest-editable] .manifest-editor {
display: flex;
}
#lense[manifest-editable] .project-details {
flex-grow: 0;
}
/* End blocks to remove */

Просмотреть файл

@ -64,6 +64,10 @@
display: none; display: none;
} }
#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow {
background-image: none;
}
/* Black box message and source progress meter */ /* Black box message and source progress meter */
#black-boxed-message, #black-boxed-message,

Просмотреть файл

@ -77,7 +77,7 @@ class nsGeolocationRequest
void Shutdown(); void Shutdown();
void SendLocation(nsIDOMGeoPosition* location); void SendLocation(nsIDOMGeoPosition* location);
bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;} bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
void SetTimeoutTimer(); void SetTimeoutTimer();
nsIPrincipal* GetPrincipal(); nsIPrincipal* GetPrincipal();
@ -445,7 +445,7 @@ nsGeolocationRequest::Allow()
maximumAge = mOptions->mMaximumAge; maximumAge = mOptions->mMaximumAge;
} }
} }
gs->SetHigherAccuracy(mOptions && mOptions->mEnableHighAccuracy); gs->UpdateAccuracy(WantsHighAccuracy());
bool canUseCache = lastPosition && maximumAge > 0 && bool canUseCache = lastPosition && maximumAge > 0 &&
(PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <= (PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <=
@ -585,12 +585,12 @@ nsGeolocationRequest::Shutdown()
mTimeoutTimer = nullptr; mTimeoutTimer = nullptr;
} }
// This should happen last, to ensure that this request isn't taken into consideration // If there are no other high accuracy requests, the geolocation service will
// when deciding whether existing requests still require high accuracy. // notify the provider to switch to the default accuracy.
if (mOptions && mOptions->mEnableHighAccuracy) { if (mOptions && mOptions->mEnableHighAccuracy) {
nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService(); nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
if (gs) { if (gs) {
gs->SetHigherAccuracy(false); gs->UpdateAccuracy();
} }
} }
} }
@ -901,9 +901,9 @@ nsGeolocationService::HighAccuracyRequested()
} }
void void
nsGeolocationService::SetHigherAccuracy(bool aEnable) nsGeolocationService::UpdateAccuracy(bool aForceHigh)
{ {
bool highRequired = aEnable || HighAccuracyRequested(); bool highRequired = aForceHigh || HighAccuracyRequested();
if (XRE_GetProcessType() == GeckoProcessType_Content) { if (XRE_GetProcessType() == GeckoProcessType_Content) {
ContentChild* cpc = ContentChild::GetSingleton(); ContentChild* cpc = ContentChild::GetSingleton();
@ -1061,6 +1061,7 @@ Geolocation::Shutdown()
if (mService) { if (mService) {
mService->RemoveLocator(this); mService->RemoveLocator(this);
mService->UpdateAccuracy();
} }
mService = nullptr; mService = nullptr;

Просмотреть файл

@ -85,8 +85,8 @@ public:
// create, or reinitalize the callback timer // create, or reinitalize the callback timer
void SetDisconnectTimer(); void SetDisconnectTimer();
// request higher accuracy, if possible // Update the accuracy and notify the provider if changed
void SetHigherAccuracy(bool aEnable); void UpdateAccuracy(bool aForceHigh = false);
bool HighAccuracyRequested(); bool HighAccuracyRequested();
private: private:

Просмотреть файл

@ -73,6 +73,9 @@ function WifiGeoPositionProvider() {
this.timer = null; this.timer = null;
this.hasSeenWiFi = false; this.hasSeenWiFi = false;
this.started = false; this.started = false;
// this is only used when logging is enabled, to debug interactions with the
// geolocation service
this.highAccuracy = false;
} }
WifiGeoPositionProvider.prototype = { WifiGeoPositionProvider.prototype = {
@ -132,10 +135,12 @@ WifiGeoPositionProvider.prototype = {
}, },
setHighAccuracy: function(enable) { setHighAccuracy: function(enable) {
this.highAccuracy = enable;
LOG("setting highAccuracy to " + (this.highAccuracy?"TRUE":"FALSE"));
}, },
onChange: function(accessPoints) { onChange: function(accessPoints) {
LOG("onChange called"); LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE"));
this.hasSeenWiFi = true; this.hasSeenWiFi = true;
let url = Services.urlFormatter.formatURLPref("geo.wifi.uri"); let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");

Просмотреть файл

@ -0,0 +1,104 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const providerCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
const providerContract = "@mozilla.org/geolocation/provider;1";
const categoryName = "geolocation-provider";
var provider = {
QueryInterface: function eventsink_qi(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIGeolocationProvider))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function eventsink_ci(outer, iid) {
if (outer)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
lockFactory: function eventsink_lockf(lock) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
startup: function() {
},
watch: function() {
},
shutdown: function() {
},
setHighAccuracy: function(enable) {
this._isHigh = enable;
if (enable) {
this._seenHigh = true;
}
},
_isHigh: false,
_seenHigh: false
};
let runningInParent = true;
try {
runningInParent = Components.classes["@mozilla.org/xre/runtime;1"].
getService(Components.interfaces.nsIXULRuntime).processType
== Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}
catch (e) { }
function successCallback()
{
do_check_true(false);
do_test_finished();
}
function errorCallback()
{
do_check_true(false);
do_test_finished();
}
function run_test()
{
if (runningInParent) {
// XPCShell does not get a profile by default. The geolocation service
// depends on the settings service which uses IndexedDB and IndexedDB
// needs a place where it can store databases.
do_get_profile();
Components.manager.nsIComponentRegistrar.registerFactory(providerCID,
"Unit test geo provider", providerContract, provider);
var catMan = Components.classes["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
providerContract, false, true);
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
prefs.setBoolPref("geo.testing.ignore_ipc_principal", true);
prefs.setBoolPref("geo.wifi.scan", false);
}
let geolocation = Cc["@mozilla.org/geolocation;1"].createInstance(Ci.nsISupports);
do_test_pending();
let watchID1 = geolocation.watchPosition(successCallback, errorCallback);
let watchID2 = geolocation.watchPosition(successCallback, errorCallback,
{enableHighAccuracy: true});
do_timeout(1000, function() {
geolocation.clearWatch(watchID2);
do_timeout(1000, check_results);
});
}
function check_results()
{
if (runningInParent) {
// check the provider was set to high accuracy during the test
do_check_true(provider._seenHigh);
// check the provider is not currently set to high accuracy
do_check_false(provider._isHigh);
}
do_test_finished();
}

Просмотреть файл

@ -0,0 +1,70 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const providerCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
const providerContract = "@mozilla.org/geolocation/provider;1";
const categoryName = "geolocation-provider";
var provider = {
QueryInterface: function eventsink_qi(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIGeolocationProvider))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function eventsink_ci(outer, iid) {
if (outer)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
lockFactory: function eventsink_lockf(lock) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
startup: function() {
},
watch: function() {
},
shutdown: function() {
},
setHighAccuracy: function(enable) {
this._isHigh = enable;
if (enable) {
this._seenHigh = true;
}
},
_isHigh: false,
_seenHigh: false
};
function run_test()
{
// XPCShell does not get a profile by default. The geolocation service
// depends on the settings service which uses IndexedDB and IndexedDB
// needs a place where it can store databases.
do_get_profile();
Components.manager.nsIComponentRegistrar.registerFactory(providerCID,
"Unit test geo provider", providerContract, provider);
var catMan = Components.classes["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
providerContract, false, true);
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
prefs.setBoolPref("geo.testing.ignore_ipc_principal", true);
prefs.setBoolPref("geo.wifi.scan", false);
run_test_in_child("test_geolocation_reset_accuracy.js", check_results);
}
function check_results()
{
// check the provider was set to high accuracy during the test
do_check_true(provider._seenHigh);
// check the provider is not currently set to high accuracy
do_check_false(provider._isHigh);
do_test_finished();
}

Просмотреть файл

@ -12,3 +12,8 @@ skip-if = os == "android"
skip-if = os == "android" skip-if = os == "android"
[test_geolocation_timeout_wrap.js] [test_geolocation_timeout_wrap.js]
skip-if = os == "mac" || os == "android" skip-if = os == "mac" || os == "android"
[test_geolocation_reset_accuracy.js]
# Bug 919946: test hangs consistently on Android
skip-if = os == "android"
[test_geolocation_reset_accuracy_wrap.js]
skip-if = os == "mac" || os == "android"

Просмотреть файл

@ -27,6 +27,7 @@ import org.mozilla.gecko.R;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.NoSuchFieldException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
@ -81,6 +82,19 @@ public final class BitmapUtils {
return; return;
} }
if(data.startsWith("-moz-icon://")) {
Uri imageUri = Uri.parse(data);
String resource = imageUri.getSchemeSpecificPart();
resource = resource.substring(resource.lastIndexOf('/') + 1);
try {
Drawable d = context.getPackageManager().getApplicationIcon(resource);
loader.onBitmapFound(d);
} catch(Exception ex) { }
return;
}
if(data.startsWith("drawable://")) { if(data.startsWith("drawable://")) {
Uri imageUri = Uri.parse(data); Uri imageUri = Uri.parse(data);
int id = getResource(imageUri, R.drawable.ic_status_logo); int id = getResource(imageUri, R.drawable.ic_status_logo);
@ -282,11 +296,34 @@ public final class BitmapUtils {
if ("drawable".equals(scheme)) { if ("drawable".equals(scheme)) {
String resource = resourceUrl.getSchemeSpecificPart(); String resource = resourceUrl.getSchemeSpecificPart();
resource = resource.substring(resource.lastIndexOf('/') + 1); resource = resource.substring(resource.lastIndexOf('/') + 1);
try {
return Integer.parseInt(resource);
} catch(NumberFormatException ex) {
// This isn't a resource id, try looking for a string
}
try { try {
final Class<R.drawable> drawableClass = R.drawable.class; final Class<R.drawable> drawableClass = R.drawable.class;
final Field f = drawableClass.getField(resource); final Field f = drawableClass.getField(resource);
icon = f.getInt(null); icon = f.getInt(null);
} catch (final Exception e) {} // just means the resource doesn't exist } catch (final NoSuchFieldException e1) {
// just means the resource doesn't exist for fennec. Check in Android resources
try {
final Class<android.R.drawable> drawableClass = android.R.drawable.class;
final Field f = drawableClass.getField(resource);
icon = f.getInt(null);
} catch (final NoSuchFieldException e2) {
// This drawable doesn't seem to exist...
} catch(Exception e3) {
Log.i(LOGTAG, "Exception getting drawable", e3);
}
} catch (Exception e4) {
Log.i(LOGTAG, "Exception getting drawable", e4);
}
resourceUrl = null; resourceUrl = null;
} }
return icon; return icon;

Просмотреть файл

@ -20,7 +20,6 @@ import android.widget.TextView;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
/** /**
* This class is an extension of BaseTest that helps with interaction with about:home * This class is an extension of BaseTest that helps with interaction with about:home
@ -28,7 +27,7 @@ import java.util.Arrays;
* The purpose of this class is to collect all the logically connected methods that deal with about:home * The purpose of this class is to collect all the logically connected methods that deal with about:home
* To use any of these methods in your test make sure it extends AboutHomeTest instead of BaseTest * To use any of these methods in your test make sure it extends AboutHomeTest instead of BaseTest
*/ */
abstract class AboutHomeTest extends BaseTest { abstract class AboutHomeTest extends PixelTest {
protected enum AboutHomeTabs {HISTORY, MOST_RECENT, TABS_FROM_LAST_TIME, TOP_SITES, BOOKMARKS, READING_LIST}; protected enum AboutHomeTabs {HISTORY, MOST_RECENT, TABS_FROM_LAST_TIME, TOP_SITES, BOOKMARKS, READING_LIST};
private ArrayList<String> aboutHomeTabs = new ArrayList<String>() {{ private ArrayList<String> aboutHomeTabs = new ArrayList<String>() {{
add("TOP_SITES"); add("TOP_SITES");
@ -98,10 +97,6 @@ abstract class AboutHomeTest extends BaseTest {
// @return the View associated with bookmark for the provided url or null if the link is not bookmarked // @return the View associated with bookmark for the provided url or null if the link is not bookmarked
protected View getDisplayedBookmark(String url) { protected View getDisplayedBookmark(String url) {
openAboutHomeTab(AboutHomeTabs.BOOKMARKS); openAboutHomeTab(AboutHomeTabs.BOOKMARKS);
if (!mDevice.type.equals("tablet")) {
toggleVKB(); // dismiss the keyboard to make sure this works on small screen devices
}
getInstrumentation().waitForIdleSync();
ListView bookmarksTabList = findListViewWithTag("bookmarks"); ListView bookmarksTabList = findListViewWithTag("bookmarks");
waitForNonEmptyListToLoad(bookmarksTabList); waitForNonEmptyListToLoad(bookmarksTabList);
ListAdapter adapter = bookmarksTabList.getAdapter(); ListAdapter adapter = bookmarksTabList.getAdapter();
@ -182,30 +177,59 @@ abstract class AboutHomeTest extends BaseTest {
} }
/** /**
* @param1 a String with the original url * FIXME: rewrite this to work with fig when rewriting the testBookmarksTab test
* @param2 a String array with the new values for all fields * This method will edit the bookmark with index = bookmarkIndex from the list of bookmarks
* For the field index:
* fieldIndex = 1 - the Bookmark name
* fieldIndex = 2 - the Bookmark url
* fieldIndex = 3 - the Bookmark keyword
*/ */
protected void editBookmark(String originalUrl, String[] newValues) { protected void editBookmark(int bookmarkIndex, int fieldIndex, String addedText, ListView list) {
openBookmarkContextMenu(originalUrl);
// Open the Edit Bookmark context menu
View child;
mSolo.clickOnText("Bookmarks");
child = list.getChildAt(bookmarkIndex);
mAsserter.ok(child != null, "edit item can be retrieved", child != null ? child.toString() : "null!");
waitForText("Switch to tab");
mSolo.clickLongOnView(child);
waitForText("Share");
mSolo.clickOnText("Edit"); mSolo.clickOnText("Edit");
waitForText("Edit Bookmark"); waitForText("Edit Bookmark");
for (String value:newValues) {
mSolo.clearEditText(Arrays.asList(newValues).indexOf(value)); // Clear the Field
mSolo.clickOnEditText(Arrays.asList(newValues).indexOf(value)); mSolo.clearEditText(fieldIndex);
mActions.sendKeys(value);
} // Enter the new text
mSolo.clickOnButton("OK"); mSolo.clickOnEditText(fieldIndex);
mActions.sendKeys(addedText);
mSolo.clickOnText("OK");
waitForText("Bookmark updated"); waitForText("Bookmark updated");
} }
protected void checkBookmarkEdit(String bookmarkUrl, String[] values) { // FIXME: rewrite this to work with fig when rewriting the testBookmarksTab test
openBookmarkContextMenu(bookmarkUrl); protected boolean checkBookmarkEdit(int bookmarkIndex, String addedText, ListView list) {
// Open the Edit Bookmark context menu
View child;
mSolo.clickOnText("Bookmarks");
child = list.getChildAt(bookmarkIndex);
mAsserter.ok(child != null, "check item can be retrieved", child != null ? child.toString() : "null!");
waitForText("Switch to tab");
mSolo.clickLongOnView(child);
waitForText("Share");
mSolo.clickOnText("Edit"); mSolo.clickOnText("Edit");
for (String value:values) { waitForText("Edit Bookmark");
mAsserter.ok(mSolo.searchText(value), "Checking that the value is correct", "The value = " + value + " is correct");
// Check if the new text was added
if (mSolo.searchText(addedText)) {
clickOnButton("Cancel");
waitForText("about:home");
return true;
} else {
clickOnButton("Cancel");
waitForText("about:home");
return false;
} }
clickOnButton("Cancel");
waitForText("BOOKMARKS");
} }
// A wait in order for the about:home tab to be rendered after drag/tab selection // A wait in order for the about:home tab to be rendered after drag/tab selection
@ -256,12 +280,15 @@ abstract class AboutHomeTest extends BaseTest {
protected void openAboutHomeTab(AboutHomeTabs tab) { protected void openAboutHomeTab(AboutHomeTabs tab) {
focusUrlBar(); focusUrlBar();
ViewPager pager = (ViewPager)mSolo.getView(ViewPager.class, 0); ViewPager pager = (ViewPager)mSolo.getView(ViewPager.class, 0);
final int currentTabIndex = pager.getCurrentItem();
int tabOffset;
// Handle tablets by just clicking the visible tab title. // Handle tablets by just clicking the visible tab title.
if (mDevice.type.equals("tablet")) { if (mDevice.type.equals("tablet")) {
// Just click for tablets, since all the titles are visible.
if (AboutHomeTabs.MOST_RECENT == tab || AboutHomeTabs.TABS_FROM_LAST_TIME == tab) { if (AboutHomeTabs.MOST_RECENT == tab || AboutHomeTabs.TABS_FROM_LAST_TIME == tab) {
mSolo.clickOnText(AboutHomeTabs.HISTORY.toString()); tabOffset = aboutHomeTabs.indexOf(AboutHomeTabs.HISTORY.toString()) - currentTabIndex;
swipeAboutHome(tabOffset);
waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.HISTORY_LABEL));
TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0); TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0);
switch (tab) { switch (tab) {
@ -284,8 +311,7 @@ abstract class AboutHomeTest extends BaseTest {
} }
// Handle phones (non-tablets). // Handle phones (non-tablets).
final int currentTabIndex = pager.getCurrentItem(); tabOffset = aboutHomeTabs.indexOf(tab.toString()) - currentTabIndex;
int tabOffset = aboutHomeTabs.indexOf(tab.toString()) - currentTabIndex;
switch (tab) { switch (tab) {
case TOP_SITES : { case TOP_SITES : {
swipeAboutHome(tabOffset); swipeAboutHome(tabOffset);

Просмотреть файл

@ -45,8 +45,6 @@ class StringHelper {
"Add to Home Screen" "Add to Home Screen"
}; };
public static final String[] BOOKMARK_CONTEXT_MENU_ITEMS = {"Open in New Tab", "Open in Private Tab", "Share", "Edit", "Remove", "Add to Home Screen"};
// Robocop page urls // Robocop page urls
// Note: please use getAbsoluteUrl(String url) on each robocop url to get the correct url // Note: please use getAbsoluteUrl(String url) on each robocop url to get the correct url
public static final String ROBOCOP_BIG_LINK_URL = "/robocop/robocop_big_link.html"; public static final String ROBOCOP_BIG_LINK_URL = "/robocop/robocop_big_link.html";

Просмотреть файл

@ -1,7 +1,6 @@
[testAwesomebar] [testAwesomebar]
# [testAwesomebarSwipes] # disabled on fig - bug 880060 # [testAwesomebarSwipes] # disabled on fig - bug 880060
[testBookmark] [testBookmark]
[testBookmarksPage]
# [testBookmarklets] # see bug 915350 # [testBookmarklets] # see bug 915350
# [testBookmarkKeyword] # see bug 915350 # [testBookmarkKeyword] # see bug 915350
[testBrowserSearchVisibility] [testBrowserSearchVisibility]
@ -46,6 +45,7 @@
[testMasterPassword] [testMasterPassword]
[testDeviceSearchEngine] [testDeviceSearchEngine]
[testPrivateBrowsing] [testPrivateBrowsing]
[testReaderMode]
# Used for Talos, please don't use in mochitest # Used for Talos, please don't use in mochitest
#[testPan] #[testPan]

Просмотреть файл

@ -1,223 +0,0 @@
#filter substitution
package @ANDROID_PACKAGE_NAME@.tests;
import @ANDROID_PACKAGE_NAME@.*;
import com.jayway.android.robotium.solo.Condition;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
public class testBookmarksPage extends AboutHomeTest {
private static String BOOKMARK_URL;
private static String DESKTOP_BOOKMARK_URL;
@Override
protected int getTestType() {
return TEST_MOCHITEST;
}
public void testBookmarksPage() {
BOOKMARK_URL = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
DESKTOP_BOOKMARK_URL = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_02_URL);
setUpDesktopBookmarks();
checkBookmarkList();
checkBookmarkContextMenu();
}
private void checkBookmarkList() {
// Check that the default bookmarks are displayed
for (String url:StringHelper.DEFAULT_BOOKMARKS_URLS) {
mAsserter.ok(isBookmarkDisplayed(url), "Checking that default bookmark: " + url + " is displayed in the bookmarks list", url + " is displayed as a bookmark");
}
mAsserter.ok(isBookmarkDisplayed(BOOKMARK_URL), "Checking that added bookmark: " + BOOKMARK_URL + " is displayed in the bookmarks list", BOOKMARK_URL + " is displayed as a bookmark");
waitForText(StringHelper.DESKTOP_FOLDER_LABEL);
clickOnBookmarkFolder(StringHelper.DESKTOP_FOLDER_LABEL);
waitForText(StringHelper.TOOLBAR_FOLDER_LABEL);
// Verify the number of folders displayed in the Desktop Bookmarks folder is correct
ListView desktopFolderContent = findListViewWithTag("bookmarks");
ListAdapter adapter = desktopFolderContent.getAdapter();
if (mDevice.type.equals("tablet")) { // On tablets it's 4 folders and 1 view for top padding
mAsserter.is(adapter.getCount(), 5, "Checking that the correct number of folders is displayed in the Desktop Bookmarks folder");
} else { // On phones it's just the 4 folders
mAsserter.is(adapter.getCount(), 4, "Checking that the correct number of folders is displayed in the Desktop Bookmarks folder");
}
clickOnBookmarkFolder(StringHelper.TOOLBAR_FOLDER_LABEL);
// Go up in the bookmark folder hierarchy
clickOnBookmarkFolder(StringHelper.TOOLBAR_FOLDER_LABEL);
mAsserter.ok(waitForText(StringHelper.BOOKMARKS_MENU_FOLDER_LABEL), "Going up in the folder hierarchy", "We are back in the Desktop Bookmarks folder");
clickOnBookmarkFolder(StringHelper.DESKTOP_FOLDER_LABEL);
mAsserter.ok(waitForText(StringHelper.DESKTOP_FOLDER_LABEL), "Going up in the folder hierarchy", "We are back in the main Bookmarks List View");
clickOnBookmarkFolder(StringHelper.DESKTOP_FOLDER_LABEL);
clickOnBookmarkFolder(StringHelper.TOOLBAR_FOLDER_LABEL);
mAsserter.ok(isBookmarkDisplayed(DESKTOP_BOOKMARK_URL), "Checking that added bookmark: " + DESKTOP_BOOKMARK_URL + " is displayed in the bookmarks list", DESKTOP_BOOKMARK_URL + " is displayed as a bookmark");
// Open the bookmark from a bookmark folder hierarchy
loadBookmark(DESKTOP_BOOKMARK_URL);
waitForText(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
verifyPageTitle(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
openAboutHomeTab(AboutHomeTabs.BOOKMARKS);
// Check that folders don't have a context menu
boolean success = waitForCondition(new Condition() {
@Override
public boolean isSatisfied() {
View desktopFolder = getBookmarkFolderView(StringHelper.DESKTOP_FOLDER_LABEL);
if (desktopFolder != null) {
mSolo.clickLongOnView(desktopFolder);
return true;
}
return false;
}
}, MAX_WAIT_MS);
mAsserter.ok(success, "Trying to long click on the Desktop Bookmarks","Desktop Bookmarks folder could not be long clicked");
mAsserter.ok(!waitForText("Share"), "Folders do not have context menus", "The context menu was not opened");
// Even if no context menu is opened long clicking a folder still opens it. We need to close it.
clickOnBookmarkFolder(StringHelper.DESKTOP_FOLDER_LABEL);
}
private void checkBookmarkContextMenu() {
// Open default bookmarks in a new tab and a new private tab since the url is substituted with "Switch to tab" after opening the link
openBookmarkContextMenu(StringHelper.DEFAULT_BOOKMARKS_URLS[1]);
// Test that the options are all displayed
for (String contextMenuOption:StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS) {
mAsserter.ok(mSolo.searchText(contextMenuOption), "Checking that the context menu option is present", contextMenuOption + " is present");
}
// Test that "Open in New Tab" works
final Element tabCount = mDriver.findElement(getActivity(), "tabs_counter");
final int tabCountInt = Integer.parseInt(tabCount.getText());
Actions.EventExpecter tabEventExpecter = mActions.expectGeckoEvent("Tab:Added");
mSolo.clickOnText(StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS[0]);
tabEventExpecter.blockForEvent();
tabEventExpecter.unregisterListener();
// Test that "Open in Private Tab" works
openBookmarkContextMenu(StringHelper.DEFAULT_BOOKMARKS_URLS[2]);
tabEventExpecter = mActions.expectGeckoEvent("Tab:Added");
mSolo.clickOnText(StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS[1]);
tabEventExpecter.blockForEvent();
tabEventExpecter.unregisterListener();
// Test that "Share" works
openBookmarkContextMenu(BOOKMARK_URL);
mSolo.clickOnText(StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS[2]);
mAsserter.ok(waitForText("Share via"), "Checking to see if the share menu has been opened","The share menu has been opened");
mActions.sendSpecialKey(Actions.SpecialKey.BACK);
waitForText(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
// Test that "Edit" works
String[] editedBookmarkValues = {"New bookmark title", "www.NewBookmark.url", "newBookmarkKeyword"};
editBookmark(BOOKMARK_URL,editedBookmarkValues);
checkBookmarkEdit(editedBookmarkValues[1],editedBookmarkValues);
// Test that "Remove" works
openBookmarkContextMenu(editedBookmarkValues[1]);
mSolo.clickOnText(StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS[4]);
waitForText("Bookmark removed");
mAsserter.ok(!mDatabaseHelper.isBookmark(editedBookmarkValues[1]), "Checking that the bookmark was removed", "The bookmark was removed");
}
private void clickOnBookmarkFolder(final String folderName) {
boolean success = waitForCondition(new Condition() {
@Override
public boolean isSatisfied() {
View bookmarksFolder = getBookmarkFolderView(folderName);
if (bookmarksFolder != null) {
mSolo.clickOnView(bookmarksFolder);
return true;
}
return false;
}
}, MAX_WAIT_MS);
mAsserter.ok(success, "Trying to click on the " + folderName + " folder","The " + folderName + " folder was clicked");
}
private View getBookmarkFolderView(String folderName) {
ListView bookmarksTabList = findListViewWithTag("bookmarks");
ListAdapter adapter = bookmarksTabList.getAdapter();
if (adapter != null) {
for (int i = 0; i < adapter.getCount(); i++ ) {
View bookmarkView = bookmarksTabList.getChildAt(i);
if (bookmarkView instanceof TextView) {
TextView folderTextView = (TextView) bookmarkView;
if (folderTextView.getText().equals(folderName)) {
return bookmarkView;
}
}
}
}
return null;
}
// Add a bookmark in the Desktop folder so we can check the folder navigation in the bookmarks page
private void setUpDesktopBookmarks() {
// Get the folder id of the StringHelper.DESKTOP_FOLDER_LABEL folder
Long desktopFolderId = mDatabaseHelper.getFolderIdFromGuid("toolbar");
// Generate a Guid for the bookmark
String generatedGuid = null;
try {
ClassLoader classLoader = getActivity().getClassLoader();
Class syncUtilityClass = classLoader.loadClass("org.mozilla.gecko.sync.Utils");
Method generateGuid = syncUtilityClass.getMethod("generateGuid", (Class[]) null);
generatedGuid = (String)generateGuid.invoke(null);
} catch (Exception e) {
mAsserter.dumpLog("Exception in setUpDesktopBookmarks" + e);
}
mAsserter.ok((generatedGuid != null), "Generating a random Guid for the bookmark", "We could not generate a Guid for the bookmark");
// Insert the bookmark
ContentResolver resolver = getActivity().getContentResolver();
Uri bookmarksUri = mDatabaseHelper.buildUri(DatabaseHelper.BrowserDataType.BOOKMARKS);
ContentValues values = new ContentValues();
values.put("title", StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
values.put("url", DESKTOP_BOOKMARK_URL);
values.put("parent", desktopFolderId);
long now = System.currentTimeMillis();
values.put("modified", now);
values.put("type", 1);
values.put("guid", generatedGuid);
values.put("position", 10);
values.put("created", now);
int updated = resolver.update(bookmarksUri,
values,
"url = ?",
new String[] { DESKTOP_BOOKMARK_URL });
if (updated == 0) {
Uri uri = resolver.insert(bookmarksUri, values);
mAsserter.ok(true, "Inserted at: ", uri.toString());
} else {
mAsserter.ok(false, "Failed to insert the Desktop bookmark", "Something went wrong");
}
// Add a mobile bookmark
mDatabaseHelper.addOrUpdateMobileBookmark(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE, BOOKMARK_URL);
}
@Override
public void tearDown() throws Exception {
mDatabaseHelper.deleteBookmark(DESKTOP_BOOKMARK_URL);
super.tearDown();
}
}

Просмотреть файл

@ -0,0 +1,170 @@
#filter substitution
package @ANDROID_PACKAGE_NAME@.tests;
import @ANDROID_PACKAGE_NAME@.*;
import com.jayway.android.robotium.solo.Solo;
import android.widget.ListView;
import android.view.View;
import java.util.ArrayList;
import android.view.ViewGroup;
import org.json.JSONException;
import org.json.JSONObject;
/**
* This patch tests the Reader Mode feature by adding and removing items in reading list
* checks the reader toolbar functionality(share, add/remove to reading list, go to reading list)
* accessing a page from reading list menu, checks that the reader icon is associated in History tab
* and that the reading list is properly populated after adding or removing reader items
*/
public class testReaderMode extends AboutHomeTest {
int height,width;
@Override
protected int getTestType() {
return TEST_MOCHITEST;
}
public void testReaderMode() {
blockForGeckoReady();
Actions.EventExpecter contentEventExpecter;
Actions.EventExpecter contentReaderAddedExpecter;
Actions.EventExpecter faviconExpecter;
ListView list;
View child;
String textUrl = getAbsoluteUrl(StringHelper.ROBOCOP_TEXT_PAGE_URL);
String devType = mDevice.type;
int childNo;
contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
loadAndPaint(textUrl);
contentEventExpecter.blockForEvent();
contentEventExpecter.unregisterListener();
View readerIcon = getReaderIcon();
// Add the page to the Reading List using log click on the reader icon
contentReaderAddedExpecter = mActions.expectGeckoEvent("Reader:Added");
mSolo.clickLongOnView(readerIcon);
String eventData = contentReaderAddedExpecter.blockForEventData();
isAdded(eventData);
contentReaderAddedExpecter.unregisterListener();
// Try to add the page to the Reading List using log click on the reader icon a second time
contentReaderAddedExpecter = mActions.expectGeckoEvent("Reader:Added");
mSolo.clickLongOnView(readerIcon);
eventData = contentReaderAddedExpecter.blockForEventData();
isAdded(eventData);
contentReaderAddedExpecter.unregisterListener();
// Waiting for the favicon since is the last element loaded usually
faviconExpecter = mActions.expectGeckoEvent("Reader:FaviconRequest");
mSolo.clickOnView(getReaderIcon());
// Changing devices orientation to be sure that all devices are in portrait when will access the reader toolbar
mSolo.setActivityOrientation(Solo.PORTRAIT);
faviconExpecter.blockForEvent();
faviconExpecter.unregisterListener();
verifyPageTitle("Robocop Text Page");
// Open the share menu for the reader toolbar
height = mDriver.getGeckoTop() + mDriver.getGeckoHeight() - 10;
width = mDriver.getGeckoLeft() + mDriver.getGeckoWidth() - 10;
mAsserter.dumpLog("Long Clicking at width = " + String.valueOf(width) + " and height = " + String.valueOf(height));
mSolo.clickOnScreen(width,height);
mAsserter.ok(mSolo.waitForText("Share via"), "Waiting for the share menu", "The share menu is present");
mActions.sendSpecialKey(Actions.SpecialKey.BACK); // Close the share menu
// Remove page from the Reading List using reader toolbar
height = mDriver.getGeckoTop() + mDriver.getGeckoHeight() - 10;
width = mDriver.getGeckoLeft() + 50;
mAsserter.dumpLog("Long Clicking at width = " + String.valueOf(width) + " and height = " + String.valueOf(height));
mSolo.clickOnScreen(width,height);
mAsserter.ok(mSolo.waitForText("Page removed from your Reading List"), "Waiting for the page to removed from your Reading List", "The page is removed from your Reading List");
//Add page to the Reading List using reader toolbar
mSolo.clickOnScreen(width,height);
mAsserter.ok(mSolo.waitForText("Page added to your Reading List"), "Waiting for the page to be added to your Reading List", "The page was added to your Reading List");
// Open the Reading List menu for the toolbar
height = mDriver.getGeckoTop() + mDriver.getGeckoHeight() - 10;
width = mDriver.getGeckoLeft() + mDriver.getGeckoWidth()/2 - 10;
mAsserter.dumpLog("Long Clicking at width = " + String.valueOf(width) + " and height = " + String.valueOf(height));
contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
mSolo.clickOnScreen(width,height);
contentEventExpecter.blockForEvent();
contentEventExpecter.unregisterListener();
// Check if the page is present in the Reading List
mAsserter.ok(mSolo.waitForText("Robocop Text Page"), "Verify if the page is added to your Reading List", "The page is present in your Reading List");
// Check if the page is added in History tab like a Reading List item
openAboutHomeTab(AboutHomeTabs.MOST_RECENT);
list = findListViewWithTag("most_recent");
child = list.getChildAt(1);
mAsserter.ok(child != null, "item can be retrieved", child != null ? child.toString() : "null!");
mSolo.clickLongOnView(child);
mAsserter.ok(mSolo.waitForText("Open in Reader"), "Verify if the page is present in history as a Reading List item", "The page is present in history as a Reading List item");
mActions.sendSpecialKey(Actions.SpecialKey.BACK); // Dismiss the context menu
mSolo.waitForText("Robocop Text Page");
// Verify separately the Reading List entries for tablets and phone because for tablets there is an extra child in UI design
if (devType.equals("phone")) {
childNo = 1;
}
else {
childNo = 2;
}
// Verify if the page is present to your Reading List
openAboutHomeTab(AboutHomeTabs.READING_LIST);
list = findListViewWithTag("reading_list");
child = list.getChildAt(childNo-1);
mAsserter.ok(child != null, "Verify if the page is present to your Reading List", "The page is present in your Reading List");
contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
mSolo.clickOnView(child);
contentEventExpecter.blockForEvent();
contentEventExpecter.unregisterListener();
verifyPageTitle("Robocop Text Page");
// Verify that we are in reader mode and remove the page from Reading List
height = mDriver.getGeckoTop() + mDriver.getGeckoHeight() - 10;
width = mDriver.getGeckoLeft() + 50;
mAsserter.dumpLog("Long Clicking at width = " + String.valueOf(width) + " and height = " + String.valueOf(height));
mSolo.clickOnScreen(width,height);
mAsserter.ok(mSolo.waitForText("Page removed from your Reading List"), "Waiting for the page to removed from your Reading List", "The page is removed from your Reading List");
verifyPageTitle("Robocop Text Page");
//Check if the Reading List is empty
openAboutHomeTab(AboutHomeTabs.READING_LIST);
list = findListViewWithTag("reading_list");
child = list.getChildAt(childNo-1);
mAsserter.ok(child == null, "Verify if the Reading List is empty", "The Reading List is empty");
}
// Get the reader icon method
protected View getReaderIcon() {
View pageActionLayout = mSolo.getView(0x7f070025);
ArrayList<String> pageActionLayoutChilds = new ArrayList();
View actionLayoutItem = pageActionLayout;
ViewGroup actionLayoutEntry = (ViewGroup)actionLayoutItem;
View icon = actionLayoutEntry.getChildAt(1);
return icon;
}
// This method check to see if a reader item is added to the reader list
private boolean isAdded(String eventData) {
try {
JSONObject data = new JSONObject(eventData);
if (data.getInt("result") == 0) {
mAsserter.ok(true, "Waiting for the page to be added to your Reading List", "The page was added to your Reading List");
}
else {
if (data.getInt("result") == 2) {
mAsserter.ok(true, "Trying to add a second time the page in your Reading List", "The page is already in your Reading List");
}
}
} catch (JSONException e) {
mAsserter.ok(false, "Error parsing the event data", e.toString());
return false;
}
return true;
}
}

Просмотреть файл

@ -3,7 +3,6 @@
# You can obtain one at http://mozilla.org/MPL/2.0/. # You can obtain one at http://mozilla.org/MPL/2.0/.
modules := \ modules := \
log4moz.js \
storageservice.js \ storageservice.js \
stringbundle.js \ stringbundle.js \
tokenserverclient.js \ tokenserverclient.js \

Просмотреть файл

@ -24,7 +24,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/rest.js"); Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
@ -47,8 +47,8 @@ Object.freeze(BagheeraClientRequestResult.prototype);
function BagheeraRequest(uri) { function BagheeraRequest(uri) {
RESTRequest.call(this, uri); RESTRequest.call(this, uri);
this._log = Log4Moz.repository.getLogger("Services.BagheeraClient"); this._log = Log.repository.getLogger("Services.BagheeraClient");
this._log.level = Log4Moz.Level.Debug; this._log.level = Log.Level.Debug;
} }
BagheeraRequest.prototype = Object.freeze({ BagheeraRequest.prototype = Object.freeze({
@ -69,8 +69,8 @@ this.BagheeraClient = function BagheeraClient(baseURI) {
throw new Error("baseURI argument must be defined."); throw new Error("baseURI argument must be defined.");
} }
this._log = Log4Moz.repository.getLogger("Services.BagheeraClient"); this._log = Log.repository.getLogger("Services.BagheeraClient");
this._log.level = Log4Moz.Level.Debug; this._log.level = Log.Level.Debug;
this.baseURI = baseURI; this.baseURI = baseURI;

Просмотреть файл

@ -8,7 +8,7 @@ const {utils: Cu} = Components;
this.EXPORTED_SYMBOLS = ["BagheeraServer"]; this.EXPORTED_SYMBOLS = ["BagheeraServer"];
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
Cu.import("resource://testing-common/httpd.js"); Cu.import("resource://testing-common/httpd.js");
@ -23,7 +23,7 @@ Cu.import("resource://testing-common/httpd.js");
* The Bagheera server is essentially a glorified document store. * The Bagheera server is essentially a glorified document store.
*/ */
this.BagheeraServer = function BagheeraServer() { this.BagheeraServer = function BagheeraServer() {
this._log = Log4Moz.repository.getLogger("metrics.BagheeraServer"); this._log = Log.repository.getLogger("metrics.BagheeraServer");
this.server = new HttpServer(); this.server = new HttpServer();
this.namespaces = {}; this.namespaces = {};

Просмотреть файл

@ -11,7 +11,7 @@ this.EXPORTED_SYMBOLS = [
const {utils: Cu} = Components; const {utils: Cu} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
this.initTestLogging = function initTestLogging(level) { this.initTestLogging = function initTestLogging(level) {
function LogStats() { function LogStats() {
@ -19,7 +19,7 @@ this.initTestLogging = function initTestLogging(level) {
} }
LogStats.prototype = { LogStats.prototype = {
format: function format(message) { format: function format(message) {
if (message.level == Log4Moz.Level.Error) { if (message.level == Log.Level.Error) {
this.errorsLogged += 1; this.errorsLogged += 1;
} }
@ -27,20 +27,20 @@ this.initTestLogging = function initTestLogging(level) {
message.message + "\n"; message.message + "\n";
} }
}; };
LogStats.prototype.__proto__ = new Log4Moz.Formatter(); LogStats.prototype.__proto__ = new Log.Formatter();
let log = Log4Moz.repository.rootLogger; let log = Log.repository.rootLogger;
let logStats = new LogStats(); let logStats = new LogStats();
let appender = new Log4Moz.DumpAppender(logStats); let appender = new Log.DumpAppender(logStats);
if (typeof(level) == "undefined") { if (typeof(level) == "undefined") {
level = "Debug"; level = "Debug";
} }
getTestLogger().level = Log4Moz.Level[level]; getTestLogger().level = Log.Level[level];
Log4Moz.repository.getLogger("Services").level = Log4Moz.Level[level]; Log.repository.getLogger("Services").level = Log.Level[level];
log.level = Log4Moz.Level.Trace; log.level = Log.Level.Trace;
appender.level = Log4Moz.Level.Trace; appender.level = Log.Level.Trace;
// Overwrite any other appenders (e.g. from previous incarnations) // Overwrite any other appenders (e.g. from previous incarnations)
log.ownAppenders = [appender]; log.ownAppenders = [appender];
log.updateAppenders(); log.updateAppenders();
@ -49,6 +49,6 @@ this.initTestLogging = function initTestLogging(level) {
} }
this.getTestLogger = function getTestLogger(component) { this.getTestLogger = function getTestLogger(component) {
return Log4Moz.repository.getLogger("Testing"); return Log.repository.getLogger("Testing");
} }

Просмотреть файл

@ -20,7 +20,7 @@ this.EXPORTED_SYMBOLS = [
Cu.import("resource://testing-common/httpd.js"); Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://services-common/async.js"); Cu.import("resource://services-common/async.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
const STORAGE_HTTP_LOGGER = "Services.Common.Test.Server"; const STORAGE_HTTP_LOGGER = "Services.Common.Test.Server";
@ -74,7 +74,7 @@ this.ServerBSO = function ServerBSO(id, payload, modified) {
throw new Error("BSO ID is invalid: " + id); throw new Error("BSO ID is invalid: " + id);
} }
this._log = Log4Moz.repository.getLogger(STORAGE_HTTP_LOGGER); this._log = Log.repository.getLogger(STORAGE_HTTP_LOGGER);
this.id = id; this.id = id;
if (!payload) { if (!payload) {
@ -287,7 +287,7 @@ this.StorageServerCollection =
CommonUtils.ensureMillisecondsTimestamp(timestamp); CommonUtils.ensureMillisecondsTimestamp(timestamp);
this._timestamp = timestamp; this._timestamp = timestamp;
this._log = Log4Moz.repository.getLogger(STORAGE_HTTP_LOGGER); this._log = Log.repository.getLogger(STORAGE_HTTP_LOGGER);
} }
StorageServerCollection.prototype = { StorageServerCollection.prototype = {
BATCH_MAX_COUNT: 100, // # of records. BATCH_MAX_COUNT: 100, // # of records.
@ -872,7 +872,7 @@ this.StorageServer = function StorageServer(callback) {
this.started = false; this.started = false;
this.users = {}; this.users = {};
this.requestCount = 0; this.requestCount = 0;
this._log = Log4Moz.repository.getLogger(STORAGE_HTTP_LOGGER); this._log = Log.repository.getLogger(STORAGE_HTTP_LOGGER);
// Install our own default handler. This allows us to mess around with the // Install our own default handler. This allows us to mess around with the
// whole URL space. // whole URL space.

Просмотреть файл

@ -17,7 +17,7 @@ this.EXPORTED_SYMBOLS = [
Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
XPCOMUtils.defineLazyModuleGetter(this, "CryptoUtils", XPCOMUtils.defineLazyModuleGetter(this, "CryptoUtils",
@ -91,9 +91,9 @@ this.RESTRequest = function RESTRequest(uri) {
this.uri = uri; this.uri = uri;
this._headers = {}; this._headers = {};
this._log = Log4Moz.repository.getLogger(this._logName); this._log = Log.repository.getLogger(this._logName);
this._log.level = this._log.level =
Log4Moz.Level[Prefs.get("log.logger.rest.request")]; Log.Level[Prefs.get("log.logger.rest.request")];
} }
RESTRequest.prototype = { RESTRequest.prototype = {
@ -309,7 +309,7 @@ RESTRequest.prototype = {
} }
this._log.debug(method + " Length: " + data.length); this._log.debug(method + " Length: " + data.length);
if (this._log.level <= Log4Moz.Level.Trace) { if (this._log.level <= Log.Level.Trace) {
this._log.trace(method + " Body: " + data); this._log.trace(method + " Body: " + data);
} }
@ -444,7 +444,7 @@ RESTRequest.prototype = {
this._log.debug(this.method + " " + uri + " " + this.response.status); this._log.debug(this.method + " " + uri + " " + this.response.status);
// Additionally give the full response body when Trace logging. // Additionally give the full response body when Trace logging.
if (this._log.level <= Log4Moz.Level.Trace) { if (this._log.level <= Log.Level.Trace) {
this._log.trace(this.method + " body: " + this.response.body); this._log.trace(this.method + " body: " + this.response.body);
} }
@ -593,9 +593,9 @@ RESTRequest.prototype = {
* the RESTRequest. * the RESTRequest.
*/ */
this.RESTResponse = function RESTResponse() { this.RESTResponse = function RESTResponse() {
this._log = Log4Moz.repository.getLogger(this._logName); this._log = Log.repository.getLogger(this._logName);
this._log.level = this._log.level =
Log4Moz.Level[Prefs.get("log.logger.rest.response")]; Log.Level[Prefs.get("log.logger.rest.response")];
} }
RESTResponse.prototype = { RESTResponse.prototype = {

Просмотреть файл

@ -35,7 +35,7 @@ const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://services-common/async.js"); Cu.import("resource://services-common/async.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/rest.js"); Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
@ -470,8 +470,8 @@ this.StorageServiceRequestError = function StorageServiceRequestError() {
* to implement it transparently. * to implement it transparently.
*/ */
function StorageServiceRequest() { function StorageServiceRequest() {
this._log = Log4Moz.repository.getLogger("Sync.StorageService.Request"); this._log = Log.repository.getLogger("Sync.StorageService.Request");
this._log.level = Log4Moz.Level[Prefs.get("log.level")]; this._log.level = Log.Level[Prefs.get("log.level")];
this.notModified = false; this.notModified = false;
@ -1521,8 +1521,8 @@ Object.freeze(StorageCollectionBatchedDelete.prototype);
* (string) Base URI for all requests. * (string) Base URI for all requests.
*/ */
this.StorageServiceClient = function StorageServiceClient(baseURI) { this.StorageServiceClient = function StorageServiceClient(baseURI) {
this._log = Log4Moz.repository.getLogger("Services.Common.StorageServiceClient"); this._log = Log.repository.getLogger("Services.Common.StorageServiceClient");
this._log.level = Log4Moz.Level[Prefs.get("log.level")]; this._log.level = Log.Level[Prefs.get("log.level")];
this._baseURI = baseURI; this._baseURI = baseURI;

Просмотреть файл

@ -2,13 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
Cu.import("resource://testing-common/httpd.js"); Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://testing-common/services-common/logging.js"); Cu.import("resource://testing-common/services-common/logging.js");
let btoa = Cu.import("resource://services-common/log4moz.js").btoa; let btoa = Cu.import("resource://gre/modules/Log.jsm").btoa;
let atob = Cu.import("resource://services-common/log4moz.js").atob; let atob = Cu.import("resource://gre/modules/Log.jsm").atob;
function do_check_empty(obj) { function do_check_empty(obj) {
do_check_attribute_count(obj, 0); do_check_attribute_count(obj, 0);

Просмотреть файл

@ -4,7 +4,6 @@
const modules = [ const modules = [
"async.js", "async.js",
"bagheeraclient.js", "bagheeraclient.js",
"log4moz.js",
"rest.js", "rest.js",
"storageservice.js", "storageservice.js",
"stringbundle.js", "stringbundle.js",

Просмотреть файл

@ -2,15 +2,15 @@
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/rest.js"); Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
//DEBUG = true; //DEBUG = true;
function run_test() { function run_test() {
Log4Moz.repository.getLogger("Services.Common.RESTRequest").level = Log.repository.getLogger("Services.Common.RESTRequest").level =
Log4Moz.Level.Trace; Log.Level.Trace;
initTestLogging("Trace"); initTestLogging("Trace");
run_next_test(); run_next_test();

Просмотреть файл

@ -105,8 +105,8 @@ function doDeleteRequest(request) {
} }
function run_test() { function run_test() {
Log4Moz.repository.getLogger("Services.Common.Test.StorageServer").level = Log.repository.getLogger("Services.Common.Test.StorageServer").level =
Log4Moz.Level.Trace; Log.Level.Trace;
initTestLogging(); initTestLogging();
run_next_test(); run_next_test();

Просмотреть файл

@ -25,7 +25,6 @@ firefox-appdir = browser
[test_async_querySpinningly.js] [test_async_querySpinningly.js]
[test_bagheera_server.js] [test_bagheera_server.js]
[test_bagheera_client.js] [test_bagheera_client.js]
[test_log4moz.js]
[test_observers.js] [test_observers.js]
[test_restrequest.js] [test_restrequest.js]
[test_tokenauthenticatedrequest.js] [test_tokenauthenticatedrequest.js]

Просмотреть файл

@ -14,7 +14,7 @@ this.EXPORTED_SYMBOLS = [
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/rest.js"); Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
@ -114,8 +114,8 @@ TokenServerClientServerError.prototype.constructor =
* at fault (e.g. differentiating a 503 from a 401). * at fault (e.g. differentiating a 503 from a 401).
*/ */
this.TokenServerClient = function TokenServerClient() { this.TokenServerClient = function TokenServerClient() {
this._log = Log4Moz.repository.getLogger("Common.TokenServerClient"); this._log = Log.repository.getLogger("Common.TokenServerClient");
this._log.level = Log4Moz.Level[Prefs.get("logger.level")]; this._log.level = Log.Level[Prefs.get("logger.level")];
} }
TokenServerClient.prototype = { TokenServerClient.prototype = {
/** /**

Просмотреть файл

@ -10,7 +10,7 @@ Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/osfile.jsm") Cu.import("resource://gre/modules/osfile.jsm")
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
this.CommonUtils = { this.CommonUtils = {
exceptionStr: function exceptionStr(e) { exceptionStr: function exceptionStr(e) {
@ -88,7 +88,7 @@ this.CommonUtils = {
try { try {
return Services.io.newURI(URIString, null, null); return Services.io.newURI(URIString, null, null);
} catch (e) { } catch (e) {
let log = Log4Moz.repository.getLogger("Common.Utils"); let log = Log.repository.getLogger("Common.Utils");
log.debug("Could not create URI: " + CommonUtils.exceptionStr(e)); log.debug("Could not create URI: " + CommonUtils.exceptionStr(e));
return null; return null;
} }
@ -464,7 +464,7 @@ this.CommonUtils = {
* @param def * @param def
* (Number) The default value to use if the preference is not defined. * (Number) The default value to use if the preference is not defined.
* @param log * @param log
* (Log4Moz.Logger) Logger to write warnings to. * (Log.Logger) Logger to write warnings to.
*/ */
getEpochPref: function getEpochPref(branch, pref, def=0, log=null) { getEpochPref: function getEpochPref(branch, pref, def=0, log=null) {
if (!Number.isInteger(def)) { if (!Number.isInteger(def)) {
@ -507,7 +507,7 @@ this.CommonUtils = {
* (Number) The default value (in milliseconds) if the preference is * (Number) The default value (in milliseconds) if the preference is
* not defined or invalid. * not defined or invalid.
* @param log * @param log
* (Log4Moz.Logger) Logger to write warnings to. * (Log.Logger) Logger to write warnings to.
* @param oldestYear * @param oldestYear
* (Number) Oldest year to accept in read values. * (Number) Oldest year to accept in read values.
*/ */

Просмотреть файл

@ -223,7 +223,7 @@ DataReportingService.prototype = Object.freeze({
Cu.import("resource://gre/modules/Task.jsm", ns); Cu.import("resource://gre/modules/Task.jsm", ns);
Cu.import("resource://gre/modules/HealthReport.jsm", ns); Cu.import("resource://gre/modules/HealthReport.jsm", ns);
Cu.import("resource://services-common/log4moz.js", ns); Cu.import("resource://gre/modules/Log.jsm", ns);
// How many times will we rewrite this code before rolling it up into a // How many times will we rewrite this code before rolling it up into a
// generic module? See also bug 451283. // generic module? See also bug 451283.
@ -238,22 +238,22 @@ DataReportingService.prototype = Object.freeze({
let loggingPrefs = new Preferences(HEALTHREPORT_LOGGING_BRANCH); let loggingPrefs = new Preferences(HEALTHREPORT_LOGGING_BRANCH);
if (loggingPrefs.get("consoleEnabled", true)) { if (loggingPrefs.get("consoleEnabled", true)) {
let level = loggingPrefs.get("consoleLevel", "Warn"); let level = loggingPrefs.get("consoleLevel", "Warn");
let appender = new ns.Log4Moz.ConsoleAppender(); let appender = new ns.Log.ConsoleAppender();
appender.level = ns.Log4Moz.Level[level] || ns.Log4Moz.Level.Warn; appender.level = ns.Log.Level[level] || ns.Log.Level.Warn;
for (let name of LOGGERS) { for (let name of LOGGERS) {
let logger = ns.Log4Moz.repository.getLogger(name); let logger = ns.Log.repository.getLogger(name);
logger.addAppender(appender); logger.addAppender(appender);
} }
} }
if (loggingPrefs.get("dumpEnabled", false)) { if (loggingPrefs.get("dumpEnabled", false)) {
let level = loggingPrefs.get("dumpLevel", "Debug"); let level = loggingPrefs.get("dumpLevel", "Debug");
let appender = new ns.Log4Moz.DumpAppender(); let appender = new ns.Log.DumpAppender();
appender.level = ns.Log4Moz.Level[level] || ns.Log4Moz.Level.Debug; appender.level = ns.Log.Level[level] || ns.Log.Level.Debug;
for (let name of LOGGERS) { for (let name of LOGGERS) {
let logger = ns.Log4Moz.repository.getLogger(name); let logger = ns.Log.repository.getLogger(name);
logger.addAppender(appender); logger.addAppender(appender);
} }
} }

Просмотреть файл

@ -8,12 +8,12 @@ this.EXPORTED_SYMBOLS = ["MockPolicyListener"];
const {utils: Cu} = Components; const {utils: Cu} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
this.MockPolicyListener = function MockPolicyListener() { this.MockPolicyListener = function MockPolicyListener() {
this._log = Log4Moz.repository.getLogger("Services.DataReporting.Testing.MockPolicyListener"); this._log = Log.repository.getLogger("Services.DataReporting.Testing.MockPolicyListener");
this._log.level = Log4Moz.Level["Debug"]; this._log.level = Log.Level["Debug"];
this.requestDataUploadCount = 0; this.requestDataUploadCount = 0;
this.lastDataRequest = null; this.lastDataRequest = null;

Просмотреть файл

@ -27,7 +27,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
#endif #endif
Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
@ -263,8 +263,8 @@ this.DataSubmissionRequest.prototype = Object.freeze({
* events. * events.
*/ */
this.DataReportingPolicy = function (prefs, healthReportPrefs, listener) { this.DataReportingPolicy = function (prefs, healthReportPrefs, listener) {
this._log = Log4Moz.repository.getLogger("Services.DataReporting.Policy"); this._log = Log.repository.getLogger("Services.DataReporting.Policy");
this._log.level = Log4Moz.Level["Debug"]; this._log.level = Log.Level["Debug"];
for (let handler of this.REQUIRED_LISTENERS) { for (let handler of this.REQUIRED_LISTENERS) {
if (!listener[handler]) { if (!listener[handler]) {

Просмотреть файл

@ -16,7 +16,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
@ -69,7 +69,7 @@ this.SessionRecorder = function (branch) {
throw new Error("branch argument must end with '.': " + branch); throw new Error("branch argument must end with '.': " + branch);
} }
this._log = Log4Moz.repository.getLogger("Services.DataReporting.SessionRecorder"); this._log = Log.repository.getLogger("Services.DataReporting.SessionRecorder");
this._prefs = new Preferences(branch); this._prefs = new Preferences(branch);
this._lastActivityWasInactive = false; this._lastActivityWasInactive = false;

Просмотреть файл

@ -18,7 +18,7 @@ Cu.import("resource://services-common/async.js");
Cu.import("resource://services-common/bagheeraclient.js"); Cu.import("resource://services-common/bagheeraclient.js");
#endif #endif
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/osfile.jsm"); Cu.import("resource://gre/modules/osfile.jsm");
@ -260,7 +260,7 @@ function AbstractHealthReporter(branch, policy, sessionRecorder) {
throw new Error("Must provide policy to HealthReporter constructor."); throw new Error("Must provide policy to HealthReporter constructor.");
} }
this._log = Log4Moz.repository.getLogger("Services.HealthReport.HealthReporter"); this._log = Log.repository.getLogger("Services.HealthReport.HealthReporter");
this._log.info("Initializing health reporter instance against " + branch); this._log.info("Initializing health reporter instance against " + branch);
this._branch = branch; this._branch = branch;

Просмотреть файл

@ -25,7 +25,7 @@ const REQUIRED_UINT32_TYPE = {type: "TYPE_UINT32"};
Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/osfile.jsm") Cu.import("resource://gre/modules/osfile.jsm")
Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
// Profile creation time access. // Profile creation time access.

Просмотреть файл

@ -20,7 +20,7 @@ const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
@ -86,7 +86,7 @@ this.Measurement = function () {
} }
} }
this._log = Log4Moz.repository.getLogger("Services.Metrics.Measurement." + this.name); this._log = Log.repository.getLogger("Services.Metrics.Measurement." + this.name);
this.id = null; this.id = null;
this.storage = null; this.storage = null;
@ -502,7 +502,7 @@ this.Provider = function () {
throw new Error("Provider must define measurement types."); throw new Error("Provider must define measurement types.");
} }
this._log = Log4Moz.repository.getLogger("Services.Metrics.Provider." + this.name); this._log = Log.repository.getLogger("Services.Metrics.Provider." + this.name);
this.measurements = null; this.measurements = null;
this.storage = null; this.storage = null;

Просмотреть файл

@ -14,7 +14,7 @@ Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm");
Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
@ -25,7 +25,7 @@ Cu.import("resource://services-common/utils.js");
* provides APIs for bulk collection of data. * provides APIs for bulk collection of data.
*/ */
this.ProviderManager = function (storage) { this.ProviderManager = function (storage) {
this._log = Log4Moz.repository.getLogger("Services.Metrics.ProviderManager"); this._log = Log.repository.getLogger("Services.Metrics.ProviderManager");
this._providers = new Map(); this._providers = new Map();
this._storage = storage; this._storage = storage;

Просмотреть файл

@ -22,7 +22,7 @@ const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Sqlite.jsm"); Cu.import("resource://gre/modules/Sqlite.jsm");
Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
@ -698,7 +698,7 @@ this.MetricsStorageBackend = function (path) {
* FUTURE enforce 1 read/write connection per database limit. * FUTURE enforce 1 read/write connection per database limit.
*/ */
function MetricsStorageSqliteBackend(connection) { function MetricsStorageSqliteBackend(connection) {
this._log = Log4Moz.repository.getLogger("Services.Metrics.MetricsStorage"); this._log = Log.repository.getLogger("Services.Metrics.MetricsStorage");
this._connection = connection; this._connection = connection;
this._enabledWALCheckpointPages = null; this._enabledWALCheckpointPages = null;

Просмотреть файл

@ -16,7 +16,7 @@ const {utils: Cu} = Components;
Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
let btoa = Cu.import("resource://services-common/log4moz.js").btoa; let btoa = Cu.import("resource://gre/modules/Log.jsm").btoa;
this.FakeFilesystemService = function FakeFilesystemService(contents) { this.FakeFilesystemService = function FakeFilesystemService(contents) {
this.fakeContents = contents; this.fakeContents = contents;

Просмотреть файл

@ -19,7 +19,7 @@
const Cu = Components.utils; const Cu = Components.utils;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
Cu.import("resource://gre/modules/AddonManager.jsm"); Cu.import("resource://gre/modules/AddonManager.jsm");
@ -113,9 +113,9 @@ this.EXPORTED_SYMBOLS = ["AddonsReconciler", "CHANGE_INSTALLED",
* heed them like they were normal. In the end, the state is proper. * heed them like they were normal. In the end, the state is proper.
*/ */
this.AddonsReconciler = function AddonsReconciler() { this.AddonsReconciler = function AddonsReconciler() {
this._log = Log4Moz.repository.getLogger("Sync.AddonsReconciler"); this._log = Log.repository.getLogger("Sync.AddonsReconciler");
let level = Svc.Prefs.get("log.logger.addonsreconciler", "Debug"); let level = Svc.Prefs.get("log.logger.addonsreconciler", "Debug");
this._log.level = Log4Moz.Level[level]; this._log.level = Log.Level[level];
Svc.Obs.add("xpcom-shutdown", this.stopListening, this); Svc.Obs.add("xpcom-shutdown", this.stopListening, this);
}; };
@ -140,7 +140,7 @@ AddonsReconciler.prototype = {
*/ */
_shouldPersist: true, _shouldPersist: true,
/** log4moz logger instance */ /** Log logger instance */
_log: null, _log: null,
/** /**

Просмотреть файл

@ -9,7 +9,7 @@ this.EXPORTED_SYMBOLS = ["AddonUtils"];
const {interfaces: Ci, utils: Cu} = Components; const {interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
@ -18,8 +18,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository",
"resource://gre/modules/AddonRepository.jsm"); "resource://gre/modules/AddonRepository.jsm");
function AddonUtilsInternal() { function AddonUtilsInternal() {
this._log = Log4Moz.repository.getLogger("Sync.AddonUtils"); this._log = Log.repository.getLogger("Sync.AddonUtils");
this._log.Level = Log4Moz.Level[Svc.Prefs.get("log.logger.addonutils")]; this._log.Level = Log.Level[Svc.Prefs.get("log.logger.addonutils")];
} }
AddonUtilsInternal.prototype = { AddonUtilsInternal.prototype = {
/** /**

Просмотреть файл

@ -13,7 +13,7 @@ this.EXPORTED_SYMBOLS = [
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components; const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
Cu.import("resource://services-common/async.js"); Cu.import("resource://services-common/async.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/observers.js"); Cu.import("resource://services-common/observers.js");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
@ -42,9 +42,9 @@ this.Tracker = function Tracker(name, engine) {
this.name = this.file = name.toLowerCase(); this.name = this.file = name.toLowerCase();
this.engine = engine; this.engine = engine;
this._log = Log4Moz.repository.getLogger("Sync.Tracker." + name); this._log = Log.repository.getLogger("Sync.Tracker." + name);
let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug"); let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug");
this._log.level = Log4Moz.Level[level]; this._log.level = Log.Level[level];
this._score = 0; this._score = 0;
this._ignored = []; this._ignored = [];
@ -197,9 +197,9 @@ this.Store = function Store(name, engine) {
this.name = name.toLowerCase(); this.name = name.toLowerCase();
this.engine = engine; this.engine = engine;
this._log = Log4Moz.repository.getLogger("Sync.Store." + name); this._log = Log.repository.getLogger("Sync.Store." + name);
let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug"); let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug");
this._log.level = Log4Moz.Level[level]; this._log.level = Log.Level[level];
XPCOMUtils.defineLazyGetter(this, "_timer", function() { XPCOMUtils.defineLazyGetter(this, "_timer", function() {
return Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); return Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
@ -383,8 +383,8 @@ this.EngineManager = function EngineManager(service) {
this.service = service; this.service = service;
this._engines = {}; this._engines = {};
this._log = Log4Moz.repository.getLogger("Sync.EngineManager"); this._log = Log.repository.getLogger("Sync.EngineManager");
this._log.level = Log4Moz.Level[Svc.Prefs.get( this._log.level = Log.Level[Svc.Prefs.get(
"log.logger.service.engines", "Debug")]; "log.logger.service.engines", "Debug")];
} }
EngineManager.prototype = { EngineManager.prototype = {
@ -476,9 +476,9 @@ this.Engine = function Engine(name, service) {
this.service = service; this.service = service;
this._notify = Utils.notify("weave:engine:"); this._notify = Utils.notify("weave:engine:");
this._log = Log4Moz.repository.getLogger("Sync.Engine." + this.Name); this._log = Log.repository.getLogger("Sync.Engine." + this.Name);
let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug"); let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug");
this._log.level = Log4Moz.Level[level]; this._log.level = Log.Level[level];
this._tracker; // initialize tracker to load previously changed IDs this._tracker; // initialize tracker to load previously changed IDs
this._log.debug("Engine initialized"); this._log.debug("Engine initialized");
@ -1056,7 +1056,7 @@ SyncEngine.prototype = {
* Truthy if incoming record should be applied. False if not. * Truthy if incoming record should be applied. False if not.
*/ */
_reconcile: function _reconcile(item) { _reconcile: function _reconcile(item) {
if (this._log.level <= Log4Moz.Level.Trace) { if (this._log.level <= Log.Level.Trace) {
this._log.trace("Incoming: " + item); this._log.trace("Incoming: " + item);
} }
@ -1273,7 +1273,7 @@ SyncEngine.prototype = {
for each (let id in modifiedIDs) { for each (let id in modifiedIDs) {
try { try {
let out = this._createRecord(id); let out = this._createRecord(id);
if (this._log.level <= Log4Moz.Level.Trace) if (this._log.level <= Log.Level.Trace)
this._log.trace("Outgoing: " + out); this._log.trace("Outgoing: " + out);
out.encrypt(this.service.collectionKeys.keyForCollection(this.name)); out.encrypt(this.service.collectionKeys.keyForCollection(this.name));

Просмотреть файл

@ -14,7 +14,7 @@ Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-common/async.js"); Cu.import("resource://services-common/async.js");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
const FORMS_TTL = 5184000; // 60 days const FORMS_TTL = 5184000; // 60 days
@ -31,7 +31,7 @@ Utils.deferGetSet(FormRec, "cleartext", ["name", "value"]);
let FormWrapper = { let FormWrapper = {
_log: Log4Moz.repository.getLogger("Sync.Engine.Forms"), _log: Log.repository.getLogger("Sync.Engine.Forms"),
_getEntryCols: ["fieldname", "value"], _getEntryCols: ["fieldname", "value"],
_guidCols: ["guid"], _guidCols: ["guid"],

Просмотреть файл

@ -13,7 +13,7 @@ const HISTORY_TTL = 5184000; // 60 days
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-common/async.js"); Cu.import("resource://services-common/async.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/record.js");

Просмотреть файл

@ -10,7 +10,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
// Lazy import to prevent unnecessary load on startup. // Lazy import to prevent unnecessary load on startup.
@ -57,8 +57,8 @@ for (let symbol of ["BulkKeyBundle", "SyncKeyBundle"]) {
* and any other function that involves the built-in functionality. * and any other function that involves the built-in functionality.
*/ */
this.IdentityManager = function IdentityManager() { this.IdentityManager = function IdentityManager() {
this._log = Log4Moz.repository.getLogger("Sync.Identity"); this._log = Log.repository.getLogger("Sync.Identity");
this._log.Level = Log4Moz.Level[Svc.Prefs.get("log.logger.identity")]; this._log.Level = Log.Level[Svc.Prefs.get("log.logger.identity")];
this._basicPassword = null; this._basicPassword = null;
this._basicPasswordAllowLookup = true; this._basicPasswordAllowLookup = true;

Просмотреть файл

@ -6,7 +6,7 @@ this.EXPORTED_SYMBOLS = ["JPAKEClient", "SendCredentialsController"];
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components; const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/rest.js"); Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
@ -114,8 +114,8 @@ const JPAKE_VERIFY_VALUE = "0123456789ABCDEF";
this.JPAKEClient = function JPAKEClient(controller) { this.JPAKEClient = function JPAKEClient(controller) {
this.controller = controller; this.controller = controller;
this._log = Log4Moz.repository.getLogger("Sync.JPAKEClient"); this._log = Log.repository.getLogger("Sync.JPAKEClient");
this._log.level = Log4Moz.Level[Svc.Prefs.get( this._log.level = Log.Level[Svc.Prefs.get(
"log.logger.service.jpakeclient", "Debug")]; "log.logger.service.jpakeclient", "Debug")];
this._serverURL = Svc.Prefs.get("jpake.serverURL"); this._serverURL = Svc.Prefs.get("jpake.serverURL");
@ -700,8 +700,8 @@ JPAKEClient.prototype = {
*/ */
this.SendCredentialsController = this.SendCredentialsController =
function SendCredentialsController(jpakeclient, service) { function SendCredentialsController(jpakeclient, service) {
this._log = Log4Moz.repository.getLogger("Sync.SendCredentialsController"); this._log = Log.repository.getLogger("Sync.SendCredentialsController");
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")]; this._log.level = Log.Level[Svc.Prefs.get("log.logger.service.main")];
this._log.trace("Loading."); this._log.trace("Loading.");
this.jpakeclient = jpakeclient; this.jpakeclient = jpakeclient;

Просмотреть файл

@ -12,7 +12,7 @@ this.EXPORTED_SYMBOLS = [
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
/** /**
@ -120,7 +120,7 @@ KeyBundle.prototype = {
* This is just a KeyBundle with a collection attached. * This is just a KeyBundle with a collection attached.
*/ */
this.BulkKeyBundle = function BulkKeyBundle(collection) { this.BulkKeyBundle = function BulkKeyBundle(collection) {
let log = Log4Moz.repository.getLogger("Sync.BulkKeyBundle"); let log = Log.repository.getLogger("Sync.BulkKeyBundle");
log.info("BulkKeyBundle being created for " + collection); log.info("BulkKeyBundle being created for " + collection);
KeyBundle.call(this); KeyBundle.call(this);
@ -177,7 +177,7 @@ BulkKeyBundle.prototype = {
* If the username or Sync Key is invalid, an Error will be thrown. * If the username or Sync Key is invalid, an Error will be thrown.
*/ */
this.SyncKeyBundle = function SyncKeyBundle(username, syncKey) { this.SyncKeyBundle = function SyncKeyBundle(username, syncKey) {
let log = Log4Moz.repository.getLogger("Sync.SyncKeyBundle"); let log = Log.repository.getLogger("Sync.SyncKeyBundle");
log.info("SyncKeyBundle being created."); log.info("SyncKeyBundle being created.");
KeyBundle.call(this); KeyBundle.call(this);

Просмотреть файл

@ -10,7 +10,7 @@ const Cr = Components.results;
const Cu = Components.utils; const Cu = Components.utils;
Cu.import("resource://services-common/observers.js"); Cu.import("resource://services-common/observers.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
this.Notifications = { this.Notifications = {
@ -115,7 +115,7 @@ this.NotificationButton =
try { try {
callback.apply(this, arguments); callback.apply(this, arguments);
} catch (e) { } catch (e) {
let logger = Log4Moz.repository.getLogger("Sync.Notifications"); let logger = Log.repository.getLogger("Sync.Notifications");
logger.error("An exception occurred: " + Utils.exceptionStr(e)); logger.error("An exception occurred: " + Utils.exceptionStr(e));
logger.info(Utils.stackTrace(e)); logger.info(Utils.stackTrace(e));
throw e; throw e;

Просмотреть файл

@ -9,7 +9,7 @@ this.EXPORTED_SYMBOLS = [
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/status.js"); Cu.import("resource://services-sync/status.js");
@ -20,7 +20,7 @@ this.SyncScheduler = function SyncScheduler(service) {
this.init(); this.init();
} }
SyncScheduler.prototype = { SyncScheduler.prototype = {
_log: Log4Moz.repository.getLogger("Sync.SyncScheduler"), _log: Log.repository.getLogger("Sync.SyncScheduler"),
_fatalLoginStatus: [LOGIN_FAILED_NO_USERNAME, _fatalLoginStatus: [LOGIN_FAILED_NO_USERNAME,
LOGIN_FAILED_NO_PASSWORD, LOGIN_FAILED_NO_PASSWORD,
@ -67,7 +67,7 @@ SyncScheduler.prototype = {
set numClients(value) Svc.Prefs.set("numClients", value), set numClients(value) Svc.Prefs.set("numClients", value),
init: function init() { init: function init() {
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")]; this._log.level = Log.Level[Svc.Prefs.get("log.logger.service.main")];
this.setDefaults(); this.setDefaults();
Svc.Obs.add("weave:engine:score:updated", this); Svc.Obs.add("weave:engine:score:updated", this);
Svc.Obs.add("network:offline-status-changed", this); Svc.Obs.add("network:offline-status-changed", this);
@ -500,24 +500,24 @@ ErrorHandler.prototype = {
}, },
initLogs: function initLogs() { initLogs: function initLogs() {
this._log = Log4Moz.repository.getLogger("Sync.ErrorHandler"); this._log = Log.repository.getLogger("Sync.ErrorHandler");
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")]; this._log.level = Log.Level[Svc.Prefs.get("log.logger.service.main")];
this._cleaningUpFileLogs = false; this._cleaningUpFileLogs = false;
let root = Log4Moz.repository.getLogger("Sync"); let root = Log.repository.getLogger("Sync");
root.level = Log4Moz.Level[Svc.Prefs.get("log.rootLogger")]; root.level = Log.Level[Svc.Prefs.get("log.rootLogger")];
let formatter = new Log4Moz.BasicFormatter(); let formatter = new Log.BasicFormatter();
let capp = new Log4Moz.ConsoleAppender(formatter); let capp = new Log.ConsoleAppender(formatter);
capp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.console")]; capp.level = Log.Level[Svc.Prefs.get("log.appender.console")];
root.addAppender(capp); root.addAppender(capp);
let dapp = new Log4Moz.DumpAppender(formatter); let dapp = new Log.DumpAppender(formatter);
dapp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.dump")]; dapp.level = Log.Level[Svc.Prefs.get("log.appender.dump")];
root.addAppender(dapp); root.addAppender(dapp);
let fapp = this._logAppender = new Log4Moz.StorageStreamAppender(formatter); let fapp = this._logAppender = new Log.StorageStreamAppender(formatter);
fapp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.file.level")]; fapp.level = Log.Level[Svc.Prefs.get("log.appender.file.level")];
root.addAppender(fapp); root.addAppender(fapp);
}, },

Просмотреть файл

@ -18,7 +18,7 @@ const Cu = Components.utils;
const CRYPTO_COLLECTION = "crypto"; const CRYPTO_COLLECTION = "crypto";
const KEYS_WBO = "keys"; const KEYS_WBO = "keys";
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/keys.js"); Cu.import("resource://services-sync/keys.js");
Cu.import("resource://services-sync/resource.js"); Cu.import("resource://services-sync/resource.js");
@ -111,7 +111,7 @@ Utils.deferGetSet(WBORecord, "data", ["id", "modified", "sortindex", "payload"])
this.RecordManager = function RecordManager(service) { this.RecordManager = function RecordManager(service) {
this.service = service; this.service = service;
this._log = Log4Moz.repository.getLogger(this._logName); this._log = Log.repository.getLogger(this._logName);
this._records = {}; this._records = {};
} }
RecordManager.prototype = { RecordManager.prototype = {
@ -281,7 +281,7 @@ this.CollectionKeyManager = function CollectionKeyManager() {
this._collections = {}; this._collections = {};
this._default = null; this._default = null;
this._log = Log4Moz.repository.getLogger("Sync.CollectionKeyManager"); this._log = Log.repository.getLogger("Sync.CollectionKeyManager");
} }
// TODO: persist this locally as an Identity. Bug 610913. // TODO: persist this locally as an Identity. Bug 610913.

Просмотреть файл

@ -14,7 +14,7 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://services-common/async.js"); Cu.import("resource://services-common/async.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/observers.js"); Cu.import("resource://services-common/observers.js");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
@ -50,9 +50,9 @@ const DEFAULT_LOAD_FLAGS =
* the status of the HTTP response. * the status of the HTTP response.
*/ */
this.AsyncResource = function AsyncResource(uri) { this.AsyncResource = function AsyncResource(uri) {
this._log = Log4Moz.repository.getLogger(this._logName); this._log = Log.repository.getLogger(this._logName);
this._log.level = this._log.level =
Log4Moz.Level[Svc.Prefs.get("log.logger.network.resources")]; Log.Level[Svc.Prefs.get("log.logger.network.resources")];
this.uri = uri; this.uri = uri;
this._headers = {}; this._headers = {};
this._onComplete = Utils.bind2(this, this._onComplete); this._onComplete = Utils.bind2(this, this._onComplete);
@ -265,7 +265,7 @@ AsyncResource.prototype = {
this._log.debug(mesg); this._log.debug(mesg);
// Additionally give the full response body when Trace logging. // Additionally give the full response body when Trace logging.
if (this._log.level <= Log4Moz.Level.Trace) if (this._log.level <= Log.Level.Trace)
this._log.trace(action + " body: " + data); this._log.trace(action + " body: " + data);
} catch(ex) { } catch(ex) {
@ -588,8 +588,8 @@ ChannelListener.prototype = {
function ChannelNotificationListener(headersToCopy) { function ChannelNotificationListener(headersToCopy) {
this._headersToCopy = headersToCopy; this._headersToCopy = headersToCopy;
this._log = Log4Moz.repository.getLogger(this._logName); this._log = Log.repository.getLogger(this._logName);
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.network.resources")]; this._log.level = Log.Level[Svc.Prefs.get("log.logger.network.resources")];
} }
ChannelNotificationListener.prototype = { ChannelNotificationListener.prototype = {
_logName: "Sync.Resource", _logName: "Sync.Resource",
@ -609,7 +609,7 @@ ChannelNotificationListener.prototype = {
}, },
notifyCertProblem: function certProblem(socketInfo, sslStatus, targetHost) { notifyCertProblem: function certProblem(socketInfo, sslStatus, targetHost) {
let log = Log4Moz.repository.getLogger("Sync.CertListener"); let log = Log.repository.getLogger("Sync.CertListener");
log.warn("Invalid HTTPS certificate encountered!"); log.warn("Invalid HTTPS certificate encountered!");
// This suppresses the UI warning only. The request is still cancelled. // This suppresses the UI warning only. The request is still cancelled.

Просмотреть файл

@ -4,7 +4,7 @@
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/rest.js"); Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");

Просмотреть файл

@ -20,7 +20,7 @@ const KEYS_WBO = "keys";
Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines.js");
@ -317,9 +317,9 @@ Sync11Service.prototype = {
this.errorHandler = new ErrorHandler(this); this.errorHandler = new ErrorHandler(this);
this._log = Log4Moz.repository.getLogger("Sync.Service"); this._log = Log.repository.getLogger("Sync.Service");
this._log.level = this._log.level =
Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")]; Log.Level[Svc.Prefs.get("log.logger.service.main")];
this._log.info("Loading Weave " + WEAVE_VERSION); this._log.info("Loading Weave " + WEAVE_VERSION);

Просмотреть файл

@ -6,7 +6,7 @@ this.EXPORTED_SYMBOLS = ["ClusterManager"];
const {utils: Cu} = Components; const {utils: Cu} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/policies.js"); Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/util.js");
@ -15,8 +15,8 @@ Cu.import("resource://services-sync/util.js");
* Contains code for managing the Sync cluster we are in. * Contains code for managing the Sync cluster we are in.
*/ */
this.ClusterManager = function ClusterManager(service) { this.ClusterManager = function ClusterManager(service) {
this._log = Log4Moz.repository.getLogger("Sync.Service"); this._log = Log.repository.getLogger("Sync.Service");
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")]; this._log.level = Log.Level[Svc.Prefs.get("log.logger.service.main")];
this.service = service; this.service = service;
} }

Просмотреть файл

@ -10,7 +10,7 @@ this.EXPORTED_SYMBOLS = ["EngineSynchronizer"];
const {utils: Cu} = Components; const {utils: Cu} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/policies.js"); Cu.import("resource://services-sync/policies.js");
@ -22,8 +22,8 @@ Cu.import("resource://services-sync/util.js");
* This was originally split out of service.js. The API needs lots of love. * This was originally split out of service.js. The API needs lots of love.
*/ */
this.EngineSynchronizer = function EngineSynchronizer(service) { this.EngineSynchronizer = function EngineSynchronizer(service) {
this._log = Log4Moz.repository.getLogger("Sync.Synchronizer"); this._log = Log.repository.getLogger("Sync.Synchronizer");
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.synchronizer")]; this._log.level = Log.Level[Svc.Prefs.get("log.logger.synchronizer")];
this.service = service; this.service = service;

Просмотреть файл

@ -10,12 +10,12 @@ const Cr = Components.results;
const Cu = Components.utils; const Cu = Components.utils;
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/identity.js");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
this.Status = { this.Status = {
_log: Log4Moz.repository.getLogger("Sync.Status"), _log: Log.repository.getLogger("Sync.Status"),
_authManager: new IdentityManager(), _authManager: new IdentityManager(),
ready: false, ready: false,
@ -114,7 +114,7 @@ this.Status = {
} catch (ex) { } catch (ex) {
// Use default. // Use default.
} }
this._log.level = Log4Moz.Level[logLevel]; this._log.level = Log.Level[logLevel];
this._log.info("Resetting Status."); this._log.info("Resetting Status.");
this.service = STATUS_OK; this.service = STATUS_OK;

Просмотреть файл

@ -10,7 +10,7 @@ this.EXPORTED_SYMBOLS = [
const {utils: Cu} = Components; const {utils: Cu} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/rest.js"); Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/identity.js");
@ -24,8 +24,8 @@ Cu.import("resource://services-sync/util.js");
* Instances are constructed with the base URI of the service. * Instances are constructed with the base URI of the service.
*/ */
this.UserAPI10Client = function UserAPI10Client(baseURI) { this.UserAPI10Client = function UserAPI10Client(baseURI) {
this._log = Log4Moz.repository.getLogger("Sync.UserAPI"); this._log = Log.repository.getLogger("Sync.UserAPI");
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.userapi")]; this._log.level = Log.Level[Svc.Prefs.get("log.logger.userapi")];
this.baseURI = baseURI; this.baseURI = baseURI;
} }

Просмотреть файл

@ -7,7 +7,7 @@ this.EXPORTED_SYMBOLS = ["XPCOMUtils", "Services", "NetUtil", "PlacesUtils",
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components; const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/observers.js"); Cu.import("resource://services-common/observers.js");
Cu.import("resource://services-common/stringbundle.js"); Cu.import("resource://services-common/stringbundle.js");
Cu.import("resource://services-common/utils.js"); Cu.import("resource://services-common/utils.js");

Просмотреть файл

@ -1,7 +1,7 @@
const Cm = Components.manager; const Cm = Components.manager;
// Shared logging for all HTTP server functions. // Shared logging for all HTTP server functions.
Cu.import("resource://services-common/log4moz.js"); Cu.import("resource://gre/modules/Log.jsm");
const SYNC_HTTP_LOGGER = "Sync.Test.Server"; const SYNC_HTTP_LOGGER = "Sync.Test.Server";
const SYNC_API_VERSION = "1.1"; const SYNC_API_VERSION = "1.1";
@ -163,7 +163,7 @@ function ServerCollection(wbos, acceptNew, timestamp) {
* has a modified time. * has a modified time.
*/ */
this.timestamp = timestamp || new_timestamp(); this.timestamp = timestamp || new_timestamp();
this._log = Log4Moz.repository.getLogger(SYNC_HTTP_LOGGER); this._log = Log.repository.getLogger(SYNC_HTTP_LOGGER);
} }
ServerCollection.prototype = { ServerCollection.prototype = {
@ -527,7 +527,7 @@ function SyncServer(callback) {
this.server = new HttpServer(); this.server = new HttpServer();
this.started = false; this.started = false;
this.users = {}; this.users = {};
this._log = Log4Moz.repository.getLogger(SYNC_HTTP_LOGGER); this._log = Log.repository.getLogger(SYNC_HTTP_LOGGER);
// Install our own default handler. This allows us to mess around with the // Install our own default handler. This allows us to mess around with the
// whole URL space. // whole URL space.

Просмотреть файл

@ -240,13 +240,13 @@ add_test(function cleanup() {
function run_test() { function run_test() {
initTestLogging("Trace"); initTestLogging("Trace");
Log4Moz.repository.getLogger("Sync.Engine.Addons").level = Log.repository.getLogger("Sync.Engine.Addons").level =
Log4Moz.Level.Trace; Log.Level.Trace;
Log4Moz.repository.getLogger("Sync.Store.Addons").level = Log4Moz.Level.Trace; Log.repository.getLogger("Sync.Store.Addons").level = Log.Level.Trace;
Log4Moz.repository.getLogger("Sync.Tracker.Addons").level = Log.repository.getLogger("Sync.Tracker.Addons").level =
Log4Moz.Level.Trace; Log.Level.Trace;
Log4Moz.repository.getLogger("Sync.AddonsRepository").level = Log.repository.getLogger("Sync.AddonsRepository").level =
Log4Moz.Level.Trace; Log.Level.Trace;
reconciler.startListening(); reconciler.startListening();

Просмотреть файл

@ -14,9 +14,9 @@ startupManager();
function run_test() { function run_test() {
initTestLogging("Trace"); initTestLogging("Trace");
Log4Moz.repository.getLogger("Sync.AddonsReconciler").level = Log4Moz.Level.Trace; Log.repository.getLogger("Sync.AddonsReconciler").level = Log.Level.Trace;
Log4Moz.repository.getLogger("Sync.AddonsReconciler").level = Log.repository.getLogger("Sync.AddonsReconciler").level =
Log4Moz.Level.Trace; Log.Level.Trace;
Svc.Prefs.set("engine.addons", true); Svc.Prefs.set("engine.addons", true);
Service.engineManager.register(AddonsEngine); Service.engineManager.register(AddonsEngine);

Просмотреть файл

@ -67,9 +67,9 @@ function createAndStartHTTPServer(port) {
function run_test() { function run_test() {
initTestLogging("Trace"); initTestLogging("Trace");
Log4Moz.repository.getLogger("Sync.Engine.Addons").level = Log4Moz.Level.Trace; Log.repository.getLogger("Sync.Engine.Addons").level = Log.Level.Trace;
Log4Moz.repository.getLogger("Sync.AddonsRepository").level = Log.repository.getLogger("Sync.AddonsRepository").level =
Log4Moz.Level.Trace; Log.Level.Trace;
reconciler.startListening(); reconciler.startListening();

Просмотреть файл

@ -43,9 +43,9 @@ function cleanup_and_advance() {
function run_test() { function run_test() {
initTestLogging("Trace"); initTestLogging("Trace");
Log4Moz.repository.getLogger("Sync.Engine.Addons").level = Log4Moz.Level.Trace; Log.repository.getLogger("Sync.Engine.Addons").level = Log.Level.Trace;
Log4Moz.repository.getLogger("Sync.AddonsReconciler").level = Log.repository.getLogger("Sync.AddonsReconciler").level =
Log4Moz.Level.Trace; Log.Level.Trace;
cleanup_and_advance(); cleanup_and_advance();
} }

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше