зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
2ff1acb70e
|
@ -66,7 +66,7 @@ pref("extensions.getAddons.cache.enabled", true);
|
|||
pref("extensions.getAddons.maxResults", 15);
|
||||
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%");
|
||||
pref("extensions.getAddons.getWithPerformance.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
|
||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%");
|
||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%&platform=%OS%&appver=%VERSION%");
|
||||
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%/%COMPATIBILITY_MODE%?src=firefox");
|
||||
pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%/%COMPATIBILITY_MODE%");
|
||||
|
||||
|
@ -214,6 +214,7 @@ pref("app.update.service.enabled", true);
|
|||
//
|
||||
pref("extensions.update.enabled", true);
|
||||
pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
pref("extensions.update.interval", 86400); // Check for updates to Extensions and
|
||||
// Themes every day
|
||||
// Non-symmetric (not shared by extensions) extension-specific [update] preferences
|
||||
|
@ -1041,6 +1042,9 @@ pref("devtools.debugger.enabled", false);
|
|||
// The default Debugger UI height
|
||||
pref("devtools.debugger.ui.height", 250);
|
||||
|
||||
// Disable remote debugging protocol logging
|
||||
pref("devtools.debugger.log", false);
|
||||
|
||||
// Enable the style inspector
|
||||
pref("devtools.styleinspector.enabled", true);
|
||||
|
||||
|
|
|
@ -40,10 +40,12 @@ let gDropTargetShim = {
|
|||
* @param aEvent The 'dragstart' event.
|
||||
*/
|
||||
_start: function DropTargetShim_start(aEvent) {
|
||||
gGrid.lock();
|
||||
if (aEvent.target.classList.contains("site")) {
|
||||
gGrid.lock();
|
||||
|
||||
// XXX bug 505521 - Listen for dragover on the document.
|
||||
document.documentElement.addEventListener("dragover", this._dragover, false);
|
||||
// XXX bug 505521 - Listen for dragover on the document.
|
||||
document.documentElement.addEventListener("dragover", this._dragover, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@ _BROWSER_FILES = \
|
|||
browser_newtab_tabsync.js \
|
||||
browser_newtab_unpin.js \
|
||||
browser_newtab_bug723102.js \
|
||||
browser_newtab_bug723121.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function runTests() {
|
||||
setLinks("0,1,2,3,4,5,6,7,8");
|
||||
setPinnedLinks("");
|
||||
|
||||
yield addNewTabPageTab();
|
||||
checkGridLocked(false, "grid is unlocked");
|
||||
|
||||
let cell = cells[0].node;
|
||||
let site = cells[0].site.node;
|
||||
|
||||
sendDragEvent(site, "dragstart");
|
||||
checkGridLocked(true, "grid is now locked");
|
||||
|
||||
sendDragEvent(site, "dragend");
|
||||
checkGridLocked(false, "grid isn't locked anymore");
|
||||
|
||||
sendDragEvent(cell, "dragstart");
|
||||
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
|
||||
}
|
||||
|
||||
function checkGridLocked(aLocked, aMessage) {
|
||||
is(cw.gGrid.node.hasAttribute("locked"), aLocked, aMessage);
|
||||
}
|
||||
|
||||
function sendDragEvent(aNode, aType) {
|
||||
let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let dataTransfer = {
|
||||
mozUserCancelled: false,
|
||||
setData: function () null,
|
||||
setDragImage: function () null,
|
||||
getData: function () "about:blank"
|
||||
};
|
||||
|
||||
let event = cw.document.createEvent("DragEvents");
|
||||
event.initDragEvent(aType, true, true, cw, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, null, dataTransfer);
|
||||
|
||||
windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
|
||||
}
|
|
@ -411,18 +411,20 @@ BrowserGlue.prototype = {
|
|||
|
||||
// For any add-ons that were installed disabled and can be enabled offer
|
||||
// them to the user
|
||||
var win = this.getMostRecentBrowserWindow();
|
||||
var browser = win.gBrowser;
|
||||
var changedIDs = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_INSTALLED);
|
||||
AddonManager.getAddonsByIDs(changedIDs, function(aAddons) {
|
||||
aAddons.forEach(function(aAddon) {
|
||||
// If the add-on isn't user disabled or can't be enabled then skip it
|
||||
if (!aAddon.userDisabled || !(aAddon.permissions & AddonManager.PERM_CAN_ENABLE))
|
||||
return;
|
||||
if (changedIDs.length > 0) {
|
||||
AddonManager.getAddonsByIDs(changedIDs, function(aAddons) {
|
||||
var win = this.getMostRecentBrowserWindow();
|
||||
var browser = win.gBrowser;
|
||||
aAddons.forEach(function(aAddon) {
|
||||
// If the add-on isn't user disabled or can't be enabled then skip it.
|
||||
if (!aAddon.userDisabled || !(aAddon.permissions & AddonManager.PERM_CAN_ENABLE))
|
||||
return;
|
||||
|
||||
browser.selectedTab = browser.addTab("about:newaddon?id=" + aAddon.id);
|
||||
})
|
||||
});
|
||||
browser.selectedTab = browser.addTab("about:newaddon?id=" + aAddon.id);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
|
||||
Services.telemetry.getHistogramById("FX_KEYWORD_URL_USERSET").add(keywordURLUserSet);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* Dave Camp <dcamp@mozilla.com> (original author)
|
||||
* Panos Astithas <past@mozilla.com>
|
||||
* Victor Porof <vporof@mozilla.com>
|
||||
* Mihai Sucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -60,9 +61,37 @@ function DebuggerPane(aTab) {
|
|||
this._tab = aTab;
|
||||
this._close = this.close.bind(this);
|
||||
this._debugTab = this.debugTab.bind(this);
|
||||
this.breakpoints = {};
|
||||
}
|
||||
|
||||
DebuggerPane.prototype = {
|
||||
/**
|
||||
* Skip editor breakpoint change events.
|
||||
*
|
||||
* This property tells the source editor event handler to skip handling of
|
||||
* the BREAKPOINT_CHANGE events. This is used when the debugger adds/removes
|
||||
* breakpoints from the editor. Typically, the BREAKPOINT_CHANGE event handler
|
||||
* adds/removes events from the debugger, but when breakpoints are added from
|
||||
* the public debugger API, we need to do things in reverse.
|
||||
*
|
||||
* This implementation relies on the fact that the source editor fires the
|
||||
* BREAKPOINT_CHANGE events synchronously.
|
||||
*
|
||||
* @private
|
||||
* @type boolean
|
||||
*/
|
||||
_skipEditorBreakpointChange: false,
|
||||
|
||||
/**
|
||||
* The list of breakpoints in the debugger as tracked by the current
|
||||
* DebuggerPane instance. This an object where the values are BreakpointActor
|
||||
* objects received from the client, while the keys are actor names, for
|
||||
* example "conn0.breakpoint3".
|
||||
*
|
||||
* @type object
|
||||
*/
|
||||
breakpoints: null,
|
||||
|
||||
/**
|
||||
* Creates and initializes the widgets contained in the debugger UI.
|
||||
*/
|
||||
|
@ -87,11 +116,15 @@ DebuggerPane.prototype = {
|
|||
self.frame.removeEventListener("DOMContentLoaded", initPane, true);
|
||||
// Initialize the source editor.
|
||||
self.frame.contentWindow.editor = self.editor = new SourceEditor();
|
||||
self.frame.contentWindow.updateEditorBreakpoints =
|
||||
self._updateEditorBreakpoints.bind(self);
|
||||
|
||||
let config = {
|
||||
mode: SourceEditor.MODES.JAVASCRIPT,
|
||||
showLineNumbers: true,
|
||||
readOnly: true
|
||||
readOnly: true,
|
||||
showAnnotationRuler: true,
|
||||
showOverviewRuler: true,
|
||||
};
|
||||
|
||||
let editorPlaceholder = self.frame.contentDocument.getElementById("editor");
|
||||
|
@ -107,14 +140,217 @@ DebuggerPane.prototype = {
|
|||
* editor initialization.
|
||||
*/
|
||||
_onEditorLoad: function DP__onEditorLoad() {
|
||||
this.editor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
this._onEditorBreakpointChange.bind(this));
|
||||
// Connect to the debugger server.
|
||||
this.connect();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for breakpoint changes that happen in the editor. This
|
||||
* function syncs the breakpoint changes in the editor to those in the
|
||||
* debugger.
|
||||
*
|
||||
* @private
|
||||
* @param object aEvent
|
||||
* The SourceEditor.EVENTS.BREAKPOINT_CHANGE event object.
|
||||
*/
|
||||
_onEditorBreakpointChange: function DP__onEditorBreakpointChange(aEvent) {
|
||||
if (this._skipEditorBreakpointChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
aEvent.added.forEach(this._onEditorBreakpointAdd, this);
|
||||
aEvent.removed.forEach(this._onEditorBreakpointRemove, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the URL of the selected script in the debugger view.
|
||||
*
|
||||
* @private
|
||||
* @return string
|
||||
* The URL of the selected script.
|
||||
*/
|
||||
_selectedScript: function DP__selectedScript() {
|
||||
return this.debuggerWindow ?
|
||||
this.debuggerWindow.DebuggerView.Scripts.selected : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for new breakpoints that come from the editor.
|
||||
*
|
||||
* @private
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint object coming from the editor.
|
||||
*/
|
||||
_onEditorBreakpointAdd: function DP__onEditorBreakpointAdd(aBreakpoint) {
|
||||
let location = {
|
||||
url: this._selectedScript(),
|
||||
line: aBreakpoint.line + 1,
|
||||
};
|
||||
|
||||
if (location.url) {
|
||||
let callback = function (aClient, aError) {
|
||||
if (aError) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
let result = this.editor.removeBreakpoint(aBreakpoint.line);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}.bind(this);
|
||||
this.addBreakpoint(location, callback, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for breakpoints that are removed from the editor.
|
||||
*
|
||||
* @private
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint object that was removed from the editor.
|
||||
*/
|
||||
_onEditorBreakpointRemove: function DP__onEditorBreakpointRemove(aBreakpoint) {
|
||||
let url = this._selectedScript();
|
||||
let line = aBreakpoint.line + 1;
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
let breakpoint = this.getBreakpoint(url, line);
|
||||
if (breakpoint) {
|
||||
this.removeBreakpoint(breakpoint, null, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the breakpoints in the editor view. This function takes the list of
|
||||
* breakpoints in the debugger and adds them back into the editor view. This
|
||||
* is invoked when the selected script is changed.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_updateEditorBreakpoints: function DP__updateEditorBreakpoints()
|
||||
{
|
||||
let url = this._selectedScript();
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._skipEditorBreakpointChange = true;
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
if (breakpoint.location.url == url) {
|
||||
this.editor.addBreakpoint(breakpoint.location.line - 1);
|
||||
}
|
||||
}
|
||||
this._skipEditorBreakpointChange = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a breakpoint.
|
||||
*
|
||||
* @param object aLocation
|
||||
* The location where you want the breakpoint. This object must have
|
||||
* two properties:
|
||||
* - url - the URL of the script.
|
||||
* - line - the line number (starting from 1).
|
||||
* @param function [aCallback]
|
||||
* Optional function to invoke once the breakpoint is added. The
|
||||
* callback is invoked with two arguments:
|
||||
* - aBreakpointClient - the BreakpointActor client object, if the
|
||||
* breakpoint has been added successfully.
|
||||
* - aResponseError - if there was any error.
|
||||
* @param boolean [aNoEditorUpdate=false]
|
||||
* Tells if you want to skip editor updates. Typically the editor is
|
||||
* updated to visually indicate that a breakpoint has been added.
|
||||
*/
|
||||
addBreakpoint:
|
||||
function DP_addBreakpoint(aLocation, aCallback, aNoEditorUpdate) {
|
||||
let breakpoint = this.getBreakpoint(aLocation.url, aLocation.line);
|
||||
if (breakpoint) {
|
||||
aCallback && aCallback(breakpoint);
|
||||
return;
|
||||
}
|
||||
|
||||
this.activeThread.setBreakpoint(aLocation, function(aResponse, aBpClient) {
|
||||
if (!aResponse.error) {
|
||||
this.breakpoints[aBpClient.actor] = aBpClient;
|
||||
|
||||
if (!aNoEditorUpdate) {
|
||||
let url = this._selectedScript();
|
||||
if (url == aLocation.url) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
this.editor.addBreakpoint(aLocation.line - 1);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aCallback && aCallback(aBpClient, aResponse.error);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a breakpoint.
|
||||
*
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint you want to remove.
|
||||
* @param function [aCallback]
|
||||
* Optional function to invoke once the breakpoint is removed. The
|
||||
* callback is invoked with one argument: the breakpoint location
|
||||
* object which holds the url and line properties.
|
||||
* @param boolean [aNoEditorUpdate=false]
|
||||
* Tells if you want to skip editor updates. Typically the editor is
|
||||
* updated to visually indicate that a breakpoint has been removed.
|
||||
*/
|
||||
removeBreakpoint:
|
||||
function DP_removeBreakpoint(aBreakpoint, aCallback, aNoEditorUpdate) {
|
||||
if (!(aBreakpoint.actor in this.breakpoints)) {
|
||||
aCallback && aCallback(aBreakpoint.location);
|
||||
return;
|
||||
}
|
||||
|
||||
aBreakpoint.remove(function() {
|
||||
delete this.breakpoints[aBreakpoint.actor];
|
||||
|
||||
if (!aNoEditorUpdate) {
|
||||
let url = this._selectedScript();
|
||||
if (url == aBreakpoint.location.url) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
this.editor.removeBreakpoint(aBreakpoint.location.line - 1);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}
|
||||
|
||||
aCallback && aCallback(aBreakpoint.location);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the breakpoint object at the given location.
|
||||
*
|
||||
* @param string aUrl
|
||||
* The URL of where the breakpoint is.
|
||||
* @param number aLine
|
||||
* The line number where the breakpoint is.
|
||||
* @return object
|
||||
* The BreakpointActor object.
|
||||
*/
|
||||
getBreakpoint: function DP_getBreakpoint(aUrl, aLine) {
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
if (breakpoint.location.url == aUrl && breakpoint.location.line == aLine) {
|
||||
return breakpoint;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes the debugger UI removing child nodes and event listeners.
|
||||
*/
|
||||
close: function DP_close() {
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
this.removeBreakpoint(breakpoint);
|
||||
}
|
||||
|
||||
if (this._tab) {
|
||||
this._tab._scriptDebugger = null;
|
||||
this._tab = null;
|
||||
|
@ -192,7 +428,7 @@ DebuggerPane.prototype = {
|
|||
},
|
||||
|
||||
get debuggerWindow() {
|
||||
return this.frame.contentWindow;
|
||||
return this.frame ? this.frame.contentWindow : null;
|
||||
},
|
||||
|
||||
get debuggerClient() {
|
||||
|
@ -340,6 +576,7 @@ DebuggerUI.prototype = {
|
|||
script.text = aSourceText;
|
||||
script.contentType = aContentType;
|
||||
elt.setUserData("sourceScript", script, null);
|
||||
dbg._updateEditorBreakpoints();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Victor Porof <vporof@mozilla.com> (original author)
|
||||
* Mihai Sucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -199,7 +200,6 @@ DebuggerView.Stackframes = {
|
|||
|
||||
// the list item wasn't found in the stackframe container
|
||||
if (!frame) {
|
||||
dump("The frame list item wasn't found in the stackframes container.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,6 @@ DebuggerView.Properties = {
|
|||
|
||||
// make sure the element was created successfully
|
||||
if (!element) {
|
||||
dump("The debugger scope container wasn't created properly: " + aId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -398,7 +397,6 @@ DebuggerView.Properties = {
|
|||
|
||||
// make sure the element was created successfully
|
||||
if (!element) {
|
||||
dump("The debugger variable container wasn't created properly: " + aId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -466,7 +464,6 @@ DebuggerView.Properties = {
|
|||
|
||||
// make sure the info node exists
|
||||
if (!info) {
|
||||
dump("Could not set the grip for the corresponding variable: " + aVar.id);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -569,7 +566,6 @@ DebuggerView.Properties = {
|
|||
|
||||
// make sure the element was created successfully
|
||||
if (!element) {
|
||||
dump("The debugger property container wasn't created properly.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -710,11 +706,9 @@ DebuggerView.Properties = {
|
|||
_createPropertyElement: function DVP__createPropertyElement(aName, aId, aClass, aParent) {
|
||||
// make sure we don't duplicate anything and the parent exists
|
||||
if (document.getElementById(aId)) {
|
||||
dump("Duplicating a property element id is not allowed.");
|
||||
return null;
|
||||
}
|
||||
if (!aParent) {
|
||||
dump("A property element must have a valid parent node specified.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1127,6 +1121,15 @@ DebuggerView.Scripts = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the URL of the selected script.
|
||||
* @return string|null
|
||||
*/
|
||||
get selected() {
|
||||
return this._scripts.selectedItem ?
|
||||
this._scripts.selectedItem.value : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a script to the scripts container.
|
||||
* If the script already exists (was previously added), null is returned.
|
||||
|
|
|
@ -78,7 +78,8 @@ function startDebuggingTab(aClient, aTabGrip)
|
|||
gTabClient = aTabClient;
|
||||
gClient.attachThread(aResponse.threadActor, function(aResponse, aThreadClient) {
|
||||
if (!aThreadClient) {
|
||||
dump("Couldn't attach to thread: "+aResponse.error+"\n");
|
||||
Components.utils.reportError("Couldn't attach to thread: " +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
ThreadState.connect(aThreadClient, function() {
|
||||
|
@ -612,6 +613,7 @@ var SourceScripts = {
|
|||
window.editor.setText(DebuggerView.getStr("loadingText"));
|
||||
} else {
|
||||
window.editor.setText(aScript.text);
|
||||
window.updateEditorBreakpoints();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -73,6 +73,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_dbg_update-editor-mode.js \
|
||||
browser_dbg_select-line.js \
|
||||
browser_dbg_clean-exit.js \
|
||||
browser_dbg_bug723069_editor-breakpoints.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,274 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 723069: test the debugger breakpoint API and connection to the source
|
||||
* editor.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gScripts = null;
|
||||
let gEditor = null;
|
||||
let gBreakpoints = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
||||
let SourceEditor = tempScope.SourceEditor;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
gPane.activeThread.addOneTimeListener("scriptsadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: onScriptsAdded }, 0);
|
||||
});
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
|
||||
function onScriptsAdded()
|
||||
{
|
||||
gScripts = gDebugger.DebuggerView.Scripts;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gScripts._scripts.itemCount, 2, "Found the expected number of scripts.");
|
||||
|
||||
gEditor = gDebugger.editor;
|
||||
|
||||
isnot(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The correct script was loaded initially.");
|
||||
isnot(gScripts.selected, gScripts.scriptLocations()[0],
|
||||
"the correct sccript is selected");
|
||||
|
||||
gBreakpoints = gPane.breakpoints;
|
||||
is(Object.keys(gBreakpoints), 0, "no breakpoints");
|
||||
ok(!gPane.getBreakpoint("foo", 3), "getBreakpoint('foo', 3) returns falsey");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0, "no breakpoints in the editor");
|
||||
|
||||
|
||||
info("add the first breakpoint");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddFirst);
|
||||
let location = {url: gScripts.selected, line: 6};
|
||||
executeSoon(function() {
|
||||
gPane.addBreakpoint(location, onBreakpointAddFirst);
|
||||
});
|
||||
}
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
let breakpointsRemoved = 0;
|
||||
let editorBreakpointChanges = 0;
|
||||
|
||||
function onEditorBreakpointAddFirst(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddFirst);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint1 added to the editor");
|
||||
is(aEvent.added.length, 1, "one breakpoint added to the editor");
|
||||
is(aEvent.removed.length, 0, "no breakpoint was removed from the editor");
|
||||
is(aEvent.added[0].line, 5, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function onBreakpointAddFirst(aBreakpointClient, aResponseError)
|
||||
{
|
||||
breakpointsAdded++;
|
||||
|
||||
ok(aBreakpointClient, "breakpoint1 added, client received");
|
||||
ok(!aResponseError, "breakpoint1 added without errors");
|
||||
is(aBreakpointClient.location.url, gScripts.selected,
|
||||
"breakpoint1 client url is correct");
|
||||
is(aBreakpointClient.location.line, 6,
|
||||
"breakpoint1 client line is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(aBreakpointClient.actor in gBreakpoints,
|
||||
"breakpoint1 client found in the list of debugger breakpoints");
|
||||
is(Object.keys(gBreakpoints).length, 1,
|
||||
"the list of debugger breakpoints holds only one breakpoint");
|
||||
is(gPane.getBreakpoint(gScripts.selected, 6), aBreakpointClient,
|
||||
"getBreakpoint(selectedScript, 2) returns the correct breakpoint");
|
||||
|
||||
info("remove the first breakpoint");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointRemoveFirst);
|
||||
gPane.removeBreakpoint(aBreakpointClient, onBreakpointRemoveFirst);
|
||||
});
|
||||
}
|
||||
|
||||
function onBreakpointRemoveFirst(aLocation)
|
||||
{
|
||||
breakpointsRemoved++;
|
||||
|
||||
ok(aLocation, "breakpoint1 removed");
|
||||
is(aLocation.url, gScripts.selected, "breakpoint1 remove: url is correct");
|
||||
is(aLocation.line, 6, "breakpoint1 remove: line is correct");
|
||||
|
||||
executeSoon(testBreakpointAddBackground);
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveFirst(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointRemoveFirst);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint1 removed from the editor");
|
||||
is(aEvent.added.length, 0, "no breakpoint was added to the editor");
|
||||
is(aEvent.removed.length, 1, "one breakpoint was removed from the editor");
|
||||
is(aEvent.removed[0].line, 5, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0, "editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function testBreakpointAddBackground()
|
||||
{
|
||||
info("add a breakpoint to the second script which is not selected");
|
||||
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoints in the debugger");
|
||||
ok(!gPane.getBreakpoint(gScripts.selected, 6),
|
||||
"getBreakpoint(selectedScript, 6) returns no breakpoint");
|
||||
|
||||
let script0 = gScripts.scriptLocations()[0];
|
||||
isnot(script0, gScripts.selected,
|
||||
"first script location is not the currently selected script");
|
||||
|
||||
let location = {url: script0, line: 5};
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddBackgroundTrap);
|
||||
gPane.addBreakpoint(location, onBreakpointAddBackground);
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddBackgroundTrap(aEvent)
|
||||
{
|
||||
// trap listener: no breakpoint must be added to the editor when a breakpoint
|
||||
// is added to a script that is not currently selected.
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddBackgroundTrap);
|
||||
editorBreakpointChanges++;
|
||||
ok(false, "breakpoint2 must not be added to the editor");
|
||||
}
|
||||
|
||||
function onBreakpointAddBackground(aBreakpointClient, aResponseError)
|
||||
{
|
||||
breakpointsAdded++;
|
||||
|
||||
ok(aBreakpointClient, "breakpoint2 added, client received");
|
||||
ok(!aResponseError, "breakpoint2 added without errors");
|
||||
is(aBreakpointClient.location.url, gScripts.scriptLocations()[0],
|
||||
"breakpoint2 client url is correct");
|
||||
is(aBreakpointClient.location.line, 5,
|
||||
"breakpoint2 client line is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(aBreakpointClient.actor in gBreakpoints,
|
||||
"breakpoint2 client found in the list of debugger breakpoints");
|
||||
is(Object.keys(gBreakpoints).length, 1, "one breakpoint in the debugger");
|
||||
is(gPane.getBreakpoint(gScripts.scriptLocations()[0], 5), aBreakpointClient,
|
||||
"getBreakpoint(scriptLocations[0], 5) returns the correct breakpoint");
|
||||
|
||||
// remove the trap listener
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddBackgroundTrap);
|
||||
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddSwitch);
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
|
||||
onEditorTextChanged);
|
||||
|
||||
info("switch to the second script");
|
||||
|
||||
gScripts._scripts.selectedIndex = 0;
|
||||
gDebugger.SourceScripts.onChange({ target: gScripts._scripts });
|
||||
});
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddSwitch(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddSwitch);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint2 added to the editor");
|
||||
is(aEvent.added.length, 1, "one breakpoint added to the editor");
|
||||
is(aEvent.removed.length, 0, "no breakpoint was removed from the editor");
|
||||
is(aEvent.added[0].line, 4, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function onEditorTextChanged()
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
|
||||
onEditorTextChanged);
|
||||
|
||||
is(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The second script is no longer displayed.");
|
||||
|
||||
isnot(gEditor.getText().indexOf("firstCall"), -1,
|
||||
"The first script is displayed.");
|
||||
|
||||
executeSoon(function() {
|
||||
info("remove the second breakpoint using the mouse");
|
||||
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointRemoveSecond);
|
||||
|
||||
let testWin = gEditor.editorElement.ownerDocument.defaultView;
|
||||
EventUtils.synthesizeMouse(gEditor.editorElement, 10, 70, {}, testWin);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveSecond(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointRemoveSecond);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint2 removed from the editor");
|
||||
is(aEvent.added.length, 0, "no breakpoint was added to the editor");
|
||||
is(aEvent.removed.length, 1, "one breakpoint was removed from the editor");
|
||||
is(aEvent.removed[0].line, 4, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0, "editor.getBreakpoints().length is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
gDebugger.StackFrames.activeThread.resume(finish);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
|
||||
ok(!gPane.getBreakpoint(gScripts.scriptLocations()[0], 5),
|
||||
"getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
|
||||
|
||||
removeTab(gTab);
|
||||
is(breakpointsAdded, 2, "correct number of breakpoints have been added");
|
||||
is(breakpointsRemoved, 1, "correct number of breakpoints have been removed");
|
||||
is(editorBreakpointChanges, 4, "correct number of editor breakpoint changes");
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gScripts = null;
|
||||
gEditor = null;
|
||||
gBreakpoints = null;
|
||||
});
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
const DEBUGGER_TAB_URL = EXAMPLE_URL + "browser_dbg_debuggerstatement.html";
|
||||
|
@ -15,7 +14,6 @@ const DEBUGGER_TAB_URL = EXAMPLE_URL + "browser_dbg_debuggerstatement.html";
|
|||
function test() {
|
||||
debug_tab_pane(DEBUGGER_TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
|
@ -29,12 +27,16 @@ function testCleanExit() {
|
|||
is(gDebugger.StackFrames.activeThread.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
|
||||
gPane._client.addOneTimeListener("tabDetached", function () {
|
||||
finish();
|
||||
});
|
||||
removeTab(gTab);
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -55,10 +55,17 @@ function testLocationChange()
|
|||
gPane._client.addOneTimeListener("tabAttached", function(aEvent, aPacket) {
|
||||
ok(true, "Successfully reattached to the tab again.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
content.location = TAB1_URL;
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
|
@ -63,8 +61,7 @@ function testResume() {
|
|||
is(button.label, gDebugger.DebuggerView.getStr("pauseLabel"),
|
||||
"Button label should be pause when running.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
|
@ -72,3 +69,9 @@ function testResume() {
|
|||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
});
|
||||
|
|
|
@ -134,9 +134,15 @@ function resumeAndFinish() {
|
|||
is(vs._scripts.itemCount, 6,
|
||||
"Got too many script items in the list!");
|
||||
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -116,16 +116,19 @@ function testSimpleCall() {
|
|||
ok(!testScope.expanded,
|
||||
"Clicking again the testScope tilte should collapse it.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -118,16 +118,19 @@ function testSimpleCall() {
|
|||
is(gDebugger.DebuggerView.Properties._vars.childNodes.length, 4,
|
||||
"The scope should have been removed from the parent container tree.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -73,16 +73,19 @@ function testSimpleCall() {
|
|||
is(testScope.querySelector(".details").childNodes.length, 0,
|
||||
"The var should have been removed from the parent container tree.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -81,16 +81,19 @@ function testSimpleCall() {
|
|||
is(testScope.querySelector(".details").childNodes.length, 0,
|
||||
"The var should have been removed from the parent container tree.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -117,17 +117,19 @@ function testSimpleCall() {
|
|||
is(localVar5.querySelector(".info").textContent, "[object Object]",
|
||||
"The grip information for the localVar5 wasn't set correctly.");
|
||||
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -10,14 +10,12 @@ const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
|
|||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
|
@ -87,10 +85,16 @@ function resumeAndFinish() {
|
|||
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"Should have no frames.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -10,14 +10,12 @@ const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
|
|||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
|
@ -103,10 +101,16 @@ function resumeAndFinish() {
|
|||
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"Should have no frames.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -103,6 +103,13 @@ function testSwitchRunning()
|
|||
ok(gDebugger.editor.getText().search(/firstCall/) == -1,
|
||||
"The first script is no longer displayed.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -68,14 +68,22 @@ function testSelectLine() {
|
|||
"The correct line is selected.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Scroll all the way down to ensure stackframe-3 is visible.
|
||||
let stackframes = gDebugger.document.getElementById("stackframes");
|
||||
stackframes.scrollTop = stackframes.scrollHeight;
|
||||
|
||||
// Click the oldest stack frame.
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 4,
|
||||
"Should have four frames.");
|
||||
|
||||
let element = gDebugger.document.getElementById("stackframe-3");
|
||||
isnot(element, null, "Found the third stack frame.");
|
||||
EventUtils.synthesizeMouseAtCenter(element, {}, gDebugger);
|
||||
});
|
||||
}}, 0);
|
||||
|
@ -83,3 +91,11 @@ function testSelectLine() {
|
|||
|
||||
gDebuggee.firstCall();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -36,16 +36,19 @@ function testSimpleCall() {
|
|||
is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
|
||||
"All children should be frames.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -67,17 +67,19 @@ function testEvalCall() {
|
|||
ok(!frames.querySelector("#stackframe-1").classList.contains("selected"),
|
||||
"Second frame should not be selected after click inside the first frame.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.evalCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -47,7 +47,9 @@ function testRecurse() {
|
|||
is(frames.querySelectorAll(".dbg-stackframe").length, recurseLimit,
|
||||
"Should have reached the recurse limit.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
|
||||
frames.scrollTop = frames.scrollHeight;
|
||||
|
@ -60,9 +62,10 @@ function testRecurse() {
|
|||
gDebuggee.recurse();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -48,8 +48,7 @@ function testEvalCallResume() {
|
|||
is(frames.querySelectorAll(".empty").length, 1,
|
||||
"Should have the empty list explanation.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
|
||||
gPane.activeThread.resume();
|
||||
|
@ -58,3 +57,11 @@ function testEvalCallResume() {
|
|||
|
||||
gDebuggee.evalCall();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -72,7 +72,15 @@ function testSwitchPaused()
|
|||
"Found the expected editor mode.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gScripts = null;
|
||||
});
|
||||
|
|
|
@ -49,6 +49,14 @@ function removeTab(aTab) {
|
|||
gBrowser.removeTab(aTab);
|
||||
}
|
||||
|
||||
function closeDebuggerAndFinish(aTab) {
|
||||
DebuggerUI.aWindow.addEventListener("Debugger:Shutdown", function cleanup() {
|
||||
DebuggerUI.aWindow.removeEventListener("Debugger:Shutdown", cleanup, false);
|
||||
finish();
|
||||
}, false);
|
||||
DebuggerUI.getDebugger(aTab).close();
|
||||
}
|
||||
|
||||
function get_tab_actor_for_url(aClient, aURL, aCallback) {
|
||||
aClient.listTabs(function(aResponse) {
|
||||
for each (let tab in aResponse.tabs) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* Mihai Sucan <mihai.sucan@gmail.com> (original author)
|
||||
* Kenny Heaton <kennyheaton@gmail.com>
|
||||
* Spyros Livathinos <livathinos.spyros@gmail.com>
|
||||
* Allen Eubank <adeubank@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -124,6 +125,18 @@ const DEFAULT_KEYBINDINGS = [
|
|||
code: Ci.nsIDOMKeyEvent.DOM_VK_TAB,
|
||||
shift: true,
|
||||
},
|
||||
{
|
||||
action: "Move Lines Up",
|
||||
code: Ci.nsIDOMKeyEvent.DOM_VK_UP,
|
||||
ctrl: Services.appinfo.OS == "Darwin",
|
||||
alt: true,
|
||||
},
|
||||
{
|
||||
action: "Move Lines Down",
|
||||
code: Ci.nsIDOMKeyEvent.DOM_VK_DOWN,
|
||||
ctrl: Services.appinfo.OS == "Darwin",
|
||||
alt: true,
|
||||
},
|
||||
];
|
||||
|
||||
var EXPORTED_SYMBOLS = ["SourceEditor"];
|
||||
|
@ -367,6 +380,7 @@ SourceEditor.prototype = {
|
|||
"Find Next Occurrence": [this.ui.findNext, this.ui],
|
||||
"Find Previous Occurrence": [this.ui.findPrevious, this.ui],
|
||||
"Goto Line...": [this.ui.gotoLine, this.ui],
|
||||
"Move Lines Down": [this._moveLines, this],
|
||||
};
|
||||
|
||||
for (let name in actions) {
|
||||
|
@ -374,9 +388,17 @@ SourceEditor.prototype = {
|
|||
this._view.setAction(name, action[0].bind(action[1]));
|
||||
}
|
||||
|
||||
this._view.setAction("Move Lines Up", this._moveLines.bind(this, true));
|
||||
|
||||
let keys = (config.keys || []).concat(DEFAULT_KEYBINDINGS);
|
||||
keys.forEach(function(aKey) {
|
||||
let binding = new KeyBinding(aKey.code, aKey.accel, aKey.shift, aKey.alt);
|
||||
// In Orion mod1 refers to Cmd on Macs and Ctrl on Windows and Linux.
|
||||
// So, if ctrl is in aKey we use it on Windows and Linux, otherwise
|
||||
// we use aKey.accel for mod1.
|
||||
let mod1 = Services.appinfo.OS != "Darwin" &&
|
||||
"ctrl" in aKey ? aKey.ctrl : aKey.accel;
|
||||
let binding = new KeyBinding(aKey.code, mod1, aKey.shift, aKey.alt,
|
||||
aKey.ctrl);
|
||||
this._view.setKeyBinding(binding, aKey.action);
|
||||
|
||||
if (aKey.callback) {
|
||||
|
@ -578,6 +600,78 @@ SourceEditor.prototype = {
|
|||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Move lines upwards or downwards, relative to the current caret location.
|
||||
*
|
||||
* @private
|
||||
* @param boolean aLineAbove
|
||||
* True if moving lines up, false to move lines down.
|
||||
*/
|
||||
_moveLines: function SE__moveLines(aLineAbove)
|
||||
{
|
||||
if (this.readOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let model = this._model;
|
||||
let selection = this.getSelection();
|
||||
let firstLine = model.getLineAtOffset(selection.start);
|
||||
if (firstLine == 0 && aLineAbove) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let lastLine = model.getLineAtOffset(selection.end);
|
||||
let firstLineStart = model.getLineStart(firstLine);
|
||||
let lastLineStart = model.getLineStart(lastLine);
|
||||
if (selection.start != selection.end && lastLineStart == selection.end) {
|
||||
lastLine--;
|
||||
}
|
||||
if (!aLineAbove && (lastLine + 1) == this.getLineCount()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let lastLineEnd = model.getLineEnd(lastLine, true);
|
||||
let text = this.getText(firstLineStart, lastLineEnd);
|
||||
|
||||
if (aLineAbove) {
|
||||
let aboveLine = firstLine - 1;
|
||||
let aboveLineStart = model.getLineStart(aboveLine);
|
||||
|
||||
this.startCompoundChange();
|
||||
if (lastLine == (this.getLineCount() - 1)) {
|
||||
let delimiterStart = model.getLineEnd(aboveLine);
|
||||
let delimiterEnd = model.getLineEnd(aboveLine, true);
|
||||
let lineDelimiter = this.getText(delimiterStart, delimiterEnd);
|
||||
text += lineDelimiter;
|
||||
this.setText("", firstLineStart - lineDelimiter.length, lastLineEnd);
|
||||
} else {
|
||||
this.setText("", firstLineStart, lastLineEnd);
|
||||
}
|
||||
this.setText(text, aboveLineStart, aboveLineStart);
|
||||
this.endCompoundChange();
|
||||
this.setSelection(aboveLineStart, aboveLineStart + text.length);
|
||||
} else {
|
||||
let belowLine = lastLine + 1;
|
||||
let belowLineEnd = model.getLineEnd(belowLine, true);
|
||||
|
||||
let insertAt = belowLineEnd - lastLineEnd + firstLineStart;
|
||||
let lineDelimiter = "";
|
||||
if (belowLine == this.getLineCount() - 1) {
|
||||
let delimiterStart = model.getLineEnd(lastLine);
|
||||
lineDelimiter = this.getText(delimiterStart, lastLineEnd);
|
||||
text = lineDelimiter + text.substr(0, text.length -
|
||||
lineDelimiter.length);
|
||||
}
|
||||
this.startCompoundChange();
|
||||
this.setText("", firstLineStart, lastLineEnd);
|
||||
this.setText(text, insertAt, insertAt);
|
||||
this.endCompoundChange();
|
||||
this.setSelection(insertAt + lineDelimiter.length,
|
||||
insertAt + text.length);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* The Orion Selection event handler. The current caret line is
|
||||
* highlighted and for Linux users the selected text is copied into the X11
|
||||
|
|
|
@ -192,6 +192,7 @@ SourceEditor.DEFAULTS = {
|
|||
* - action - name of the editor action to invoke.
|
||||
* - code - keyCode for the shortcut.
|
||||
* - accel - boolean for the Accel key (Cmd on Macs, Ctrl on Linux/Windows).
|
||||
* - ctrl - boolean for the Control key
|
||||
* - shift - boolean for the Shift key.
|
||||
* - alt - boolean for the Alt key.
|
||||
* - callback - optional function to invoke, if the action is not predefined
|
||||
|
|
|
@ -58,6 +58,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_bug725388_mouse_events.js \
|
||||
browser_bug707987_debugger_breakpoints.js \
|
||||
browser_bug712982_line_ruler_click.js \
|
||||
browser_bug725618_moveLines_shortcut.js \
|
||||
browser_bug700893_dirty_state.js \
|
||||
head.js \
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
||||
let SourceEditor = tempScope.SourceEditor;
|
||||
|
||||
let editor;
|
||||
let testWin;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
const windowUrl = "data:application/vnd.mozilla.xul+xml,<?xml version='1.0'?>" +
|
||||
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
|
||||
" title='test for bug 725618 - moveLines shortcut' width='300' height='500'>" +
|
||||
"<box flex='1'/></window>";
|
||||
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
|
||||
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
|
||||
testWin.addEventListener("load", function onWindowLoad() {
|
||||
testWin.removeEventListener("load", onWindowLoad, false);
|
||||
waitForFocus(initEditor, testWin);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function initEditor()
|
||||
{
|
||||
let box = testWin.document.querySelector("box");
|
||||
|
||||
let text = "target\nfoo\nbar"
|
||||
let config = {
|
||||
initialText: text,
|
||||
};
|
||||
|
||||
editor = new SourceEditor();
|
||||
editor.init(box, config, editorLoaded);
|
||||
}
|
||||
|
||||
function editorLoaded()
|
||||
{
|
||||
editor.focus();
|
||||
|
||||
editor.setCaretOffset(0);
|
||||
|
||||
let modifiers = {altKey: true, ctrlKey: Services.appinfo.OS == "Darwin"};
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "foo\ntarget\nbar", "Move lines down works");
|
||||
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "foo\nbar\ntarget", "Move lines down works");
|
||||
is(editor.getSelectedText(), "target", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "foo\nbar\ntarget", "Check for bottom of editor works");
|
||||
is(editor.getSelectedText(), "target", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "foo\ntarget\nbar", "Move lines up works");
|
||||
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar", "Move lines up works");
|
||||
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar", "Check for top of editor works");
|
||||
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||
|
||||
editor.setSelection(0, 10);
|
||||
info("text within selection =" + editor.getSelectedText());
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "bar\ntarget\nfoo", "Multiple line move down works");
|
||||
is(editor.getSelectedText(), "target\nfoo", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "bar\ntarget\nfoo",
|
||||
"Check for bottom of editor works with multiple line selection");
|
||||
is(editor.getSelectedText(), "target\nfoo", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar", "Multiple line move up works");
|
||||
is(editor.getSelectedText(), "target\nfoo\n", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar",
|
||||
"Check for top of editor works with multiple line selection");
|
||||
is(editor.getSelectedText(), "target\nfoo\n", "selection is correct");
|
||||
|
||||
editor.readOnly = true;
|
||||
|
||||
editor.setCaretOffset(0);
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar",
|
||||
"Check for readOnly mode works with move lines up");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar",
|
||||
"Check for readOnly mode works with move lines down");
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function()
|
||||
{
|
||||
editor.destroy();
|
||||
testWin.close();
|
||||
testWin = editor = null;
|
||||
});
|
|
@ -1198,11 +1198,19 @@ function CssRule(aCssSheet, aDomRule, aElement)
|
|||
this._cssSheet = aCssSheet;
|
||||
this._domRule = aDomRule;
|
||||
|
||||
let parentRule = aDomRule.parentRule;
|
||||
if (parentRule && parentRule.type == Ci.nsIDOMCSSRule.MEDIA_RULE) {
|
||||
this.mediaText = parentRule.media.mediaText;
|
||||
}
|
||||
|
||||
if (this._cssSheet) {
|
||||
// parse _domRule.selectorText on call to this.selectors
|
||||
this._selectors = null;
|
||||
this.line = this._cssSheet._cssLogic.domUtils.getRuleLine(this._domRule);
|
||||
this.source = this._cssSheet.shortSource + ":" + this.line;
|
||||
if (this.mediaText) {
|
||||
this.source += " @media " + this.mediaText;
|
||||
}
|
||||
this.href = this._cssSheet.href;
|
||||
this.contentRule = this._cssSheet.contentSheet;
|
||||
} else if (aElement) {
|
||||
|
@ -1218,6 +1226,13 @@ function CssRule(aCssSheet, aDomRule, aElement)
|
|||
CssRule.prototype = {
|
||||
_passId: null,
|
||||
|
||||
mediaText: "",
|
||||
|
||||
get isMediaRule()
|
||||
{
|
||||
return !!this.mediaText;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the parent stylesheet is allowed by the CssLogic.sourceFilter.
|
||||
*
|
||||
|
|
|
@ -356,10 +356,20 @@ function Rule(aElementStyle, aOptions)
|
|||
this.style = aOptions.style || this.domRule.style;
|
||||
this.selectorText = aOptions.selectorText || this.domRule.selectorText;
|
||||
this.inherited = aOptions.inherited || null;
|
||||
|
||||
if (this.domRule) {
|
||||
let parentRule = this.domRule.parentRule;
|
||||
if (parentRule && parentRule.type == Ci.nsIDOMCSSRule.MEDIA_RULE) {
|
||||
this.mediaText = parentRule.media.mediaText;
|
||||
}
|
||||
}
|
||||
|
||||
this._getTextProperties();
|
||||
}
|
||||
|
||||
Rule.prototype = {
|
||||
mediaText: "",
|
||||
|
||||
get title()
|
||||
{
|
||||
if (this._title) {
|
||||
|
@ -380,7 +390,7 @@ Rule.prototype = {
|
|||
args, args.length);
|
||||
}
|
||||
|
||||
return this._title;
|
||||
return this._title + (this.mediaText ? " @media " + this.mediaText : "");
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -61,6 +61,8 @@ _BROWSER_TEST_FILES = \
|
|||
browser_ruleview_override.js \
|
||||
browser_ruleview_ui.js \
|
||||
browser_bug705707_is_content_stylesheet.js \
|
||||
browser_bug722196_property_view_media_queries.js \
|
||||
browser_bug722196_rule_view_media_queries.js \
|
||||
browser_bug_592743_specificity.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
@ -74,6 +76,7 @@ _BROWSER_TEST_PAGES = \
|
|||
browser_bug705707_is_content_stylesheet_script.css \
|
||||
browser_bug705707_is_content_stylesheet.xul \
|
||||
browser_bug705707_is_content_stylesheet_xul.css \
|
||||
browser_bug722196_identify_media_queries.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>test</title>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
</script>
|
||||
<style>
|
||||
div {
|
||||
width: 1000px;
|
||||
height: 100px;
|
||||
background-color: #f00;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1px) {
|
||||
div {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,68 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that we correctly display appropriate media query titles in the
|
||||
// property view.
|
||||
|
||||
let doc;
|
||||
let stylePanel;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||
"test/browser_bug722196_identify_media_queries.html";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", docLoaded, true);
|
||||
}
|
||||
|
||||
function docLoaded()
|
||||
{
|
||||
browser.removeEventListener("load", docLoaded, true);
|
||||
doc = content.document;
|
||||
stylePanel = new StyleInspector(window);
|
||||
Services.obs.addObserver(checkSheets, "StyleInspector-opened", false);
|
||||
stylePanel.createPanel(false, function() {
|
||||
stylePanel.open(doc.body);
|
||||
});
|
||||
}
|
||||
|
||||
function checkSheets()
|
||||
{
|
||||
Services.obs.removeObserver(checkSheets, "StyleInspector-opened", false);
|
||||
|
||||
ok(stylePanel.isOpen(), "style inspector is open");
|
||||
|
||||
var div = doc.querySelector("div");
|
||||
ok(div, "captain, we have the div");
|
||||
|
||||
stylePanel.selectNode(div);
|
||||
|
||||
let cssLogic = stylePanel.cssLogic;
|
||||
cssLogic.processMatchedSelectors();
|
||||
|
||||
let _strings = Services.strings
|
||||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties");
|
||||
|
||||
let inline = _strings.GetStringFromName("rule.sourceInline");
|
||||
|
||||
let source1 = inline + ":8";
|
||||
let source2 = inline + ":15 @media screen and (min-width: 1px)";
|
||||
is(cssLogic._matchedRules[0][0].source, source1,
|
||||
"rule.source gives correct output for rule 1");
|
||||
is(cssLogic._matchedRules[1][0].source, source2,
|
||||
"rule.source gives correct output for rule 2");
|
||||
|
||||
Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
|
||||
stylePanel.close();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
|
||||
doc = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that we correctly display appropriate media query titles in the
|
||||
// rule view.
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/devtools/CssRuleView.jsm", tempScope);
|
||||
let _ElementStyle = tempScope._ElementStyle;
|
||||
let doc;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||
"test/browser_bug722196_identify_media_queries.html";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", docLoaded, true);
|
||||
}
|
||||
|
||||
function docLoaded()
|
||||
{
|
||||
browser.removeEventListener("load", docLoaded, true);
|
||||
doc = content.document;
|
||||
checkSheets();
|
||||
}
|
||||
|
||||
function checkSheets()
|
||||
{
|
||||
var div = doc.querySelector("div");
|
||||
ok(div, "captain, we have the div");
|
||||
|
||||
let elementStyle = new _ElementStyle(div);
|
||||
is(elementStyle.rules.length, 3, "Should have 3 rules.");
|
||||
|
||||
let _strings = Services.strings
|
||||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties");
|
||||
|
||||
let inline = _strings.GetStringFromName("rule.sourceInline");
|
||||
|
||||
is(elementStyle.rules[0].title, inline, "check rule 0 title");
|
||||
is(elementStyle.rules[1].title, inline +
|
||||
":15 @media screen and (min-width: 1px)", "check rule 1 title");
|
||||
is(elementStyle.rules[2].title, inline + ":8", "check rule 2 title");
|
||||
finishUp();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
doc = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Joe Walker <jwalker@mozilla.com> (original author)
|
||||
* Mihai Sucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -160,8 +161,6 @@ gcli.addCommand({
|
|||
}
|
||||
});
|
||||
|
||||
let breakpoints = [];
|
||||
|
||||
/**
|
||||
* 'break' command
|
||||
*/
|
||||
|
@ -180,17 +179,25 @@ gcli.addCommand({
|
|||
description: gcli.lookup("breaklistDesc"),
|
||||
returnType: "html",
|
||||
exec: function(args, context) {
|
||||
if (breakpoints.length === 0) {
|
||||
let win = HUDService.currentContext();
|
||||
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
|
||||
if (!dbg) {
|
||||
return gcli.lookup("breakaddDebuggerStopped");
|
||||
}
|
||||
let breakpoints = dbg.breakpoints;
|
||||
|
||||
if (Object.keys(breakpoints).length === 0) {
|
||||
return gcli.lookup("breaklistNone");
|
||||
}
|
||||
|
||||
let reply = gcli.lookup("breaklistIntro");
|
||||
reply += "<ol>";
|
||||
breakpoints.forEach(function(breakpoint) {
|
||||
for each (let breakpoint in breakpoints) {
|
||||
let text = gcli.lookupFormat("breaklistLineEntry",
|
||||
[breakpoint.file, breakpoint.line]);
|
||||
[breakpoint.location.url,
|
||||
breakpoint.location.line]);
|
||||
reply += "<li>" + text + "</li>";
|
||||
});
|
||||
};
|
||||
reply += "</ol>";
|
||||
return reply;
|
||||
}
|
||||
|
@ -248,14 +255,11 @@ gcli.addCommand({
|
|||
}
|
||||
var promise = context.createPromise();
|
||||
let position = { url: args.file, line: args.line };
|
||||
dbg.activeThread.setBreakpoint(position, function(aResponse, aBpClient) {
|
||||
if (aResponse.error) {
|
||||
promise.resolve(gcli.lookupFormat("breakaddFailed",
|
||||
[ aResponse.error ]));
|
||||
dbg.addBreakpoint(position, function(aBreakpoint, aError) {
|
||||
if (aError) {
|
||||
promise.resolve(gcli.lookupFormat("breakaddFailed", [aError]));
|
||||
return;
|
||||
}
|
||||
args.client = aBpClient;
|
||||
breakpoints.push(args);
|
||||
promise.resolve(gcli.lookup("breakaddAdded"));
|
||||
});
|
||||
return promise;
|
||||
|
@ -275,19 +279,37 @@ gcli.addCommand({
|
|||
type: {
|
||||
name: "number",
|
||||
min: 0,
|
||||
max: function() { return breakpoints.length - 1; }
|
||||
max: function() {
|
||||
let win = HUDService.currentContext();
|
||||
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
|
||||
if (!dbg) {
|
||||
return gcli.lookup("breakaddDebuggerStopped");
|
||||
}
|
||||
return Object.keys(dbg.breakpoints).length - 1;
|
||||
},
|
||||
},
|
||||
description: gcli.lookup("breakdelBreakidDesc")
|
||||
}
|
||||
],
|
||||
returnType: "html",
|
||||
exec: function(args, context) {
|
||||
let breakpoint = breakpoints.splice(args.breakid, 1)[0];
|
||||
var promise = context.createPromise();
|
||||
let win = HUDService.currentContext();
|
||||
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
|
||||
if (!dbg) {
|
||||
return gcli.lookup("breakaddDebuggerStopped");
|
||||
}
|
||||
|
||||
let breakpoints = dbg.breakpoints;
|
||||
let id = Object.keys(dbg.breakpoints)[args.breakid];
|
||||
if (!id || !(id in breakpoints)) {
|
||||
return gcli.lookup("breakNotFound");
|
||||
}
|
||||
|
||||
let promise = context.createPromise();
|
||||
try {
|
||||
breakpoint.client.remove(function(aResponse) {
|
||||
promise.resolve(gcli.lookup("breakdelRemoved"));
|
||||
});
|
||||
dbg.removeBreakpoint(breakpoints[id], function() {
|
||||
promise.resolve(gcli.lookup("breakdelRemoved"));
|
||||
});
|
||||
} catch (ex) {
|
||||
// If the debugger has been closed already, don't scare the user.
|
||||
promise.resolve(gcli.lookup("breakdelRemoved"));
|
||||
|
|
|
@ -255,6 +255,10 @@ breakdelBreakidDesc=Index of breakpoint
|
|||
# command to explain that a breakpoint was removed.
|
||||
breakdelRemoved=Breakpoint removed
|
||||
|
||||
# LOCALIZATION NOTE (breakNotFound) Used in the output of the 'break del'
|
||||
# command to explain that the breakpoint was not found.
|
||||
breakNotFound=Breakpoint was not found
|
||||
|
||||
# LOCALIZATION NOTE (consolecloseDesc) A very short description of the
|
||||
# 'console close' command. This string is designed to be shown in a menu
|
||||
# alongside the command name, which is why it should be as short as possible.
|
||||
|
|
|
@ -146,6 +146,7 @@
|
|||
direction: ltr;
|
||||
padding: 0;
|
||||
-moz-padding-start: 20px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
|
|
@ -148,6 +148,7 @@
|
|||
direction: ltr;
|
||||
padding: 0;
|
||||
-moz-padding-start: 20px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
|
|
@ -146,6 +146,7 @@
|
|||
direction: ltr;
|
||||
padding: 0;
|
||||
-moz-padding-start: 20px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
|
|
@ -395,6 +395,7 @@ user_pref("browser.safebrowsing.provider.0.keyURL", "http://%(server)s/safebrows
|
|||
user_pref("browser.safebrowsing.provider.0.updateURL", "http://%(server)s/safebrowsing-dummy/update");
|
||||
// Point update checks to the local testing server for fast failures
|
||||
user_pref("extensions.update.url", "http://%(server)s/extensions-dummy/updateURL");
|
||||
user_pref("extensions.update.background.url", "http://%(server)s/extensions-dummy/updateBackgroundURL");
|
||||
user_pref("extensions.blocklist.url", "http://%(server)s/extensions-dummy/blocklistURL");
|
||||
user_pref("extensions.hotfix.url", "http://%(server)s/extensions-dummy/hotfixURL");
|
||||
// Make sure opening about:addons won't hit the network
|
||||
|
|
|
@ -326,10 +326,48 @@ is(e.view, window, "view should be window");
|
|||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
// UIEvent
|
||||
// StorageEvent
|
||||
|
||||
try {
|
||||
e = new UIEvent();
|
||||
e = new StorageEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new StorageEvent("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
is(e.key, "", "key should be ''");
|
||||
is(e.oldValue, null, "oldValue should be null");
|
||||
is(e.newValue, null, "newValue should be null");
|
||||
is(e.url, "", "url should be ''");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new StorageEvent("hello",
|
||||
{ bubbles: true, cancelable: true, key: "key",
|
||||
oldValue: "oldValue", newValue: "newValue", url: "url",
|
||||
storageArea: localStorage });
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.key, "key", "Wrong value");
|
||||
is(e.oldValue, "oldValue", "Wrong value");
|
||||
is(e.newValue, "newValue", "Wrong value");
|
||||
is(e.url, "url", "Wrong value");
|
||||
is(e.storageArea, localStorage, "Wrong value");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
// MouseEvent
|
||||
|
||||
try {
|
||||
e = new MouseEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
|
|
|
@ -691,7 +691,7 @@ ImageDocument::CheckOverflowing(bool changeState)
|
|||
{
|
||||
/* Create a scope so that the style context gets destroyed before we might
|
||||
* call RebuildStyleData. Also, holding onto pointers to the
|
||||
* presentatation through style resolution is potentially dangerous.
|
||||
* presentation through style resolution is potentially dangerous.
|
||||
*/
|
||||
{
|
||||
nsIPresShell *shell = GetShell();
|
||||
|
@ -702,23 +702,6 @@ ImageDocument::CheckOverflowing(bool changeState)
|
|||
nsPresContext *context = shell->GetPresContext();
|
||||
nsRect visibleArea = context->GetVisibleArea();
|
||||
|
||||
Element* body = GetBodyElement();
|
||||
if (!body) {
|
||||
NS_WARNING("no body on image document!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<nsStyleContext> styleContext =
|
||||
context->StyleSet()->ResolveStyleFor(body, nsnull);
|
||||
|
||||
nsMargin m;
|
||||
if (styleContext->GetStyleMargin()->GetMargin(m))
|
||||
visibleArea.Deflate(m);
|
||||
m = styleContext->GetStyleBorder()->GetActualBorder();
|
||||
visibleArea.Deflate(m);
|
||||
if (styleContext->GetStylePadding()->GetPadding(m))
|
||||
visibleArea.Deflate(m);
|
||||
|
||||
mVisibleWidth = nsPresContext::AppUnitsToIntCSSPixels(visibleArea.width);
|
||||
mVisibleHeight = nsPresContext::AppUnitsToIntCSSPixels(visibleArea.height);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=369370
|
|||
is(kidWin.innerHeight, 300, "Checking doc height");
|
||||
|
||||
// Image just loaded and is scaled to window size.
|
||||
is(img.width, 378, "image width");
|
||||
is(img.height, 284, "image height");
|
||||
is(img.width, 400, "image width");
|
||||
is(img.height, 300, "image height");
|
||||
is(kidDoc.body.scrollLeft, 0, "Checking scrollLeft");
|
||||
is(kidDoc.body.scrollTop, 0, "Checking scrollTop");
|
||||
|
||||
|
@ -61,8 +61,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=369370
|
|||
img.dispatchEvent(event);
|
||||
ok(true, "----- click 2 -----");
|
||||
|
||||
is(img.width, 378, "image width");
|
||||
is(img.height, 284, "image height");
|
||||
is(img.width, 400, "image width");
|
||||
is(img.height, 300, "image height");
|
||||
is(kidDoc.body.scrollLeft, 0, "Checking scrollLeft");
|
||||
is(kidDoc.body.scrollTop, 0, "Checking scrollTop");
|
||||
|
||||
|
@ -83,8 +83,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=369370
|
|||
img.dispatchEvent(event);
|
||||
ok(true, "----- click 4 -----");
|
||||
|
||||
is(img.width, 378, "image width");
|
||||
is(img.height, 284, "image height");
|
||||
is(img.width, 400, "image width");
|
||||
is(img.height, 300, "image height");
|
||||
is(kidDoc.body.scrollLeft, 0, "Checking scrollLeft");
|
||||
is(kidDoc.body.scrollTop, 0, "Checking scrollTop");
|
||||
|
||||
|
|
|
@ -1675,6 +1675,12 @@ NS_DEFINE_EVENT_CTOR(PageTransitionEvent)
|
|||
NS_DEFINE_EVENT_CTOR(CloseEvent)
|
||||
NS_DEFINE_EVENT_CTOR(UIEvent)
|
||||
NS_DEFINE_EVENT_CTOR(MouseEvent)
|
||||
nsresult
|
||||
NS_DOMStorageEventCtor(nsISupports** aInstancePtrResult)
|
||||
{
|
||||
nsDOMStorageEvent* e = new nsDOMStorageEvent();
|
||||
return CallQueryInterface(e, aInstancePtrResult);
|
||||
}
|
||||
|
||||
struct nsConstructorFuncMapData
|
||||
{
|
||||
|
@ -1700,6 +1706,7 @@ static const nsConstructorFuncMapData kConstructorFuncMap[] =
|
|||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(CloseEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(StorageEvent)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozSmsFilter, sms::SmsFilter::NewSmsFilter)
|
||||
};
|
||||
|
||||
|
@ -3895,6 +3902,7 @@ nsDOMClassInfo::Init()
|
|||
|
||||
DOM_CLASSINFO_MAP_BEGIN(StorageEvent, nsIDOMStorageEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorageEvent)
|
||||
DOM_CLASSINFO_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(StorageEventObsolete, nsIDOMStorageEventObsolete)
|
||||
|
|
|
@ -855,7 +855,7 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
|
|||
}
|
||||
}
|
||||
|
||||
NotifyFocusStateChange(aContent, shouldShowFocusRing, false);
|
||||
NotifyFocusStateChange(content, shouldShowFocusRing, false);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -94,3 +94,13 @@ interface nsIDOMStorageEvent : nsIDOMEvent
|
|||
in DOMString urlArg,
|
||||
in nsIDOMStorage storageAreaArg);
|
||||
};
|
||||
|
||||
[scriptable, uuid(6335e5b5-13ce-4c8a-b452-5c5895f4e90e)]
|
||||
interface nsIStorageEventInit : nsIEventInit
|
||||
{
|
||||
attribute DOMString key;
|
||||
attribute DOMString oldValue;
|
||||
attribute DOMString newValue;
|
||||
attribute DOMString url;
|
||||
attribute nsIDOMStorage storageArea;
|
||||
};
|
||||
|
|
|
@ -74,6 +74,7 @@ using mozilla::dom::StorageChild;
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
|
||||
// calls FlushAndDeleteTemporaryTables(false)
|
||||
#define NS_DOMSTORAGE_FLUSH_TIMER_TOPIC "domstorage-flush-timer"
|
||||
|
@ -2390,6 +2391,19 @@ NS_IMETHODIMP nsDOMStorageEvent::InitStorageEvent(const nsAString & typeArg,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorageEvent::InitFromCtor(const nsAString& aType,
|
||||
JSContext* aCx, jsval* aVal)
|
||||
{
|
||||
mozilla::dom::StorageEventInit d;
|
||||
d.oldValue.SetIsVoid(true);
|
||||
d.newValue.SetIsVoid(true);
|
||||
nsresult rv = d.Init(aCx, aVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return InitStorageEvent(aType, d.bubbles, d.cancelable, d.key, d.oldValue,
|
||||
d.newValue, d.url, d.storageArea);
|
||||
}
|
||||
|
||||
// Obsolete globalStorage event
|
||||
|
||||
DOMCI_DATA(StorageEventObsolete, nsDOMStorageEventObsolete)
|
||||
|
|
|
@ -600,6 +600,8 @@ public:
|
|||
NS_DECL_NSIDOMSTORAGEEVENT
|
||||
NS_FORWARD_NSIDOMEVENT(nsDOMEvent::)
|
||||
|
||||
virtual nsresult InitFromCtor(const nsAString& aType,
|
||||
JSContext* aCx, jsval* aVal);
|
||||
protected:
|
||||
nsString mKey;
|
||||
nsString mOldValue;
|
||||
|
|
|
@ -6458,10 +6458,23 @@ JS_ClearPendingException(JSContext *cx)
|
|||
JS_PUBLIC_API(JSBool)
|
||||
JS_ReportPendingException(JSContext *cx)
|
||||
{
|
||||
JSBool ok;
|
||||
bool save;
|
||||
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
return js_ReportUncaughtException(cx);
|
||||
/*
|
||||
* Set cx->generatingError to suppress the standard error-to-exception
|
||||
* conversion done by all {js,JS}_Report* functions except for OOM. The
|
||||
* cx->generatingError flag was added to suppress recursive divergence
|
||||
* under js_ErrorToException, but it serves for our purposes here too.
|
||||
*/
|
||||
save = cx->generatingError;
|
||||
cx->generatingError = JS_TRUE;
|
||||
ok = js_ReportUncaughtException(cx);
|
||||
cx->generatingError = save;
|
||||
return ok;
|
||||
}
|
||||
|
||||
struct JSExceptionState {
|
||||
|
|
|
@ -830,11 +830,11 @@ struct JSContext : js::ContextFriendFields
|
|||
bool hasVersionOverride;
|
||||
|
||||
/* Exception state -- the exception member is a GC root by definition. */
|
||||
JSBool throwing; /* is there a pending exception? */
|
||||
js::Value exception; /* most-recently-thrown exception */
|
||||
JSBool throwing; /* is there a pending exception? */
|
||||
js::Value exception; /* most-recently-thrown exception */
|
||||
|
||||
/* Per-context run options. */
|
||||
unsigned runOptions; /* see jsapi.h for JSOPTION_* */
|
||||
unsigned runOptions; /* see jsapi.h for JSOPTION_* */
|
||||
|
||||
public:
|
||||
int32_t reportGranularity; /* see jsprobes.h */
|
||||
|
@ -844,8 +844,11 @@ struct JSContext : js::ContextFriendFields
|
|||
|
||||
js::AutoResolving *resolvingList;
|
||||
|
||||
/* True if generating an error, to prevent runaway recursion. */
|
||||
bool generatingError;
|
||||
/*
|
||||
* True if generating an error, to prevent runaway recursion.
|
||||
* NB: generatingError packs with throwing below.
|
||||
*/
|
||||
bool generatingError;
|
||||
|
||||
/* GC heap compartment. */
|
||||
JSCompartment *compartment;
|
||||
|
|
|
@ -1084,7 +1084,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
|
|||
*/
|
||||
JS_ASSERT(reportp);
|
||||
if (JSREPORT_IS_WARNING(reportp->flags))
|
||||
return false;
|
||||
return JS_FALSE;
|
||||
|
||||
/* Find the exception index associated with this error. */
|
||||
errorNumber = (JSErrNum) reportp->errorNumber;
|
||||
|
@ -1107,12 +1107,19 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
|
|||
* with the given error number.
|
||||
*/
|
||||
if (exn == JSEXN_NONE)
|
||||
return false;
|
||||
return JS_FALSE;
|
||||
|
||||
/* Prevent infinite recursion. */
|
||||
/*
|
||||
* Prevent runaway recursion, via cx->generatingError. If an out-of-memory
|
||||
* error occurs, no exception object will be created, but we don't assume
|
||||
* that OOM is the only kind of error that subroutines of this function
|
||||
* called below might raise.
|
||||
*/
|
||||
if (cx->generatingError)
|
||||
return false;
|
||||
AutoScopedAssign<bool> asa(&cx->generatingError, false);
|
||||
return JS_FALSE;
|
||||
|
||||
MUST_FLOW_THROUGH("out");
|
||||
cx->generatingError = JS_TRUE;
|
||||
|
||||
/* Protect the newly-created strings below from nesting GCs. */
|
||||
PodArrayZero(tv);
|
||||
|
@ -1125,34 +1132,43 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
|
|||
*/
|
||||
ok = js_GetClassPrototype(cx, NULL, GetExceptionProtoKey(exn), &errProto);
|
||||
if (!ok)
|
||||
return false;
|
||||
goto out;
|
||||
tv[0] = OBJECT_TO_JSVAL(errProto);
|
||||
|
||||
errObject = NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL);
|
||||
if (!errObject)
|
||||
return false;
|
||||
if (!errObject) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
tv[1] = OBJECT_TO_JSVAL(errObject);
|
||||
|
||||
messageStr = JS_NewStringCopyZ(cx, message);
|
||||
if (!messageStr)
|
||||
return false;
|
||||
if (!messageStr) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
tv[2] = STRING_TO_JSVAL(messageStr);
|
||||
|
||||
filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
|
||||
if (!filenameStr)
|
||||
return false;
|
||||
if (!filenameStr) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
tv[3] = STRING_TO_JSVAL(filenameStr);
|
||||
|
||||
ok = InitExnPrivate(cx, errObject, messageStr, filenameStr,
|
||||
reportp->lineno, reportp, exn);
|
||||
if (!ok)
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
|
||||
|
||||
/* Flag the error report passed in to indicate an exception was raised. */
|
||||
reportp->flags |= JSREPORT_EXCEPTION;
|
||||
return true;
|
||||
|
||||
out:
|
||||
cx->generatingError = JS_FALSE;
|
||||
return ok;
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
|
|
@ -9,7 +9,8 @@ dictionaries = [
|
|||
[ 'nsIUIEventInit', 'nsIDOMUIEvent.idl' ],
|
||||
[ 'nsIMouseEventInit', 'nsIDOMMouseEvent.idl' ],
|
||||
[ 'nsIIDBObjectStoreParameters', 'nsIIDBDatabase.idl' ],
|
||||
[ 'nsIIDBIndexParameters', 'nsIIDBObjectStore.idl' ]
|
||||
[ 'nsIIDBIndexParameters', 'nsIIDBObjectStore.idl' ],
|
||||
[ 'nsIStorageEventInit', 'nsIDOMStorageEvent.idl' ]
|
||||
]
|
||||
|
||||
# include file names
|
||||
|
|
|
@ -320,23 +320,8 @@ def write_header(iface, fd):
|
|||
if iface.base != "nsISupports":
|
||||
fd.write(" : public %s" % dict_name(iface.base))
|
||||
fd.write("\n{\npublic:\n")
|
||||
fd.write(" %s()" % dict_name(iface.name))
|
||||
|
||||
if iface.base != "nsISupports" or len(attributes) > 0:
|
||||
fd.write(" :\n")
|
||||
|
||||
if iface.base != "nsISupports":
|
||||
fd.write(" %s()" % dict_name(iface.base))
|
||||
if len(attributes) > 0:
|
||||
fd.write(",\n")
|
||||
|
||||
for i in range(len(attributes)):
|
||||
fd.write(" %s(%s)" % (attributes[i].name, init_value(attributes[i])))
|
||||
if i < (len(attributes) - 1):
|
||||
fd.write(",")
|
||||
fd.write("\n")
|
||||
|
||||
fd.write(" {}\n\n")
|
||||
fd.write(" %s();\n" % dict_name(iface.name))
|
||||
fd.write(" ~%s();\n\n" % dict_name(iface.name))
|
||||
|
||||
fd.write(" // If aCx or aVal is null, NS_OK is returned and \n"
|
||||
" // dictionary will use the default values. \n"
|
||||
|
@ -355,6 +340,25 @@ def write_cpp(iface, fd):
|
|||
if isinstance(member, xpidl.Attribute):
|
||||
attributes.append(member)
|
||||
|
||||
fd.write("%s::%s()" % (dict_name(iface.name), dict_name(iface.name)))
|
||||
|
||||
if iface.base != "nsISupports" or len(attributes) > 0:
|
||||
fd.write(" :\n")
|
||||
|
||||
if iface.base != "nsISupports":
|
||||
fd.write(" %s()" % dict_name(iface.base))
|
||||
if len(attributes) > 0:
|
||||
fd.write(",\n")
|
||||
|
||||
for i in range(len(attributes)):
|
||||
fd.write(" %s(%s)" % (attributes[i].name, init_value(attributes[i])))
|
||||
if i < (len(attributes) - 1):
|
||||
fd.write(",")
|
||||
fd.write("\n")
|
||||
|
||||
fd.write(" {}\n\n")
|
||||
fd.write("%s::~%s() {}\n\n" % (dict_name(iface.name), dict_name(iface.name)))
|
||||
|
||||
fd.write("static nsresult\n%s_InitInternal(%s& aDict, %s* aIfaceObject, JSContext* aCx, JSObject* aObj)\n" %
|
||||
(dict_name(iface.name), dict_name(iface.name), iface.name))
|
||||
fd.write("{\n")
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">input{border: none}</style>
|
||||
</head>
|
||||
<body>
|
||||
<input id="button2" type="button"/>
|
||||
<div id="target"><div><input id="button" type="button"/></div></div>
|
||||
<script>
|
||||
document.getElementById("button2").focus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">input{border: none}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div><input id="button" type="button"/></div>
|
||||
<input id="button2" type="button"/>
|
||||
<div id="target"/>
|
||||
<script>
|
||||
var button = document.getElementById("button");
|
||||
button.focus();
|
||||
document.getElementById("target").appendChild(button.parentNode);
|
||||
document.getElementById("button2").focus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1694,3 +1694,4 @@ fuzzy-if(d2d,1,19) fuzzy-if(cocoaWidget,1,170) == 718521.html 718521-ref.html
|
|||
== 720987.html 720987-ref.html
|
||||
== 722923-1.html 722923-1-ref.html
|
||||
== 729143-1.html 729143-1-ref.html
|
||||
needs-focus == 731726-1.html 731726-1-ref.html
|
||||
|
|
|
@ -221,13 +221,14 @@ pref("extensions.strictCompatibility", false);
|
|||
pref("extensions.minCompatibleAppVersion", "11.0");
|
||||
|
||||
pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
|
||||
/* preferences for the Get Add-ons pane */
|
||||
pref("extensions.getAddons.cache.enabled", true);
|
||||
pref("extensions.getAddons.maxResults", 15);
|
||||
pref("extensions.getAddons.recommended.browseURL", "https://addons.mozilla.org/%LOCALE%/android/recommended/");
|
||||
pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/android/api/%API_VERSION%/list/featured/all/%MAX_RESULTS%/%OS%/%VERSION%");
|
||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/android/search?q=%TERMS%");
|
||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/android/search?q=%TERMS%&platform=%OS%&appver=%VERSION%");
|
||||
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/android/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%/%COMPATIBILITY_MODE%");
|
||||
pref("extensions.getAddons.browseAddons", "https://addons.mozilla.org/%LOCALE%/android/");
|
||||
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/android/api/%API_VERSION%/search/guid:%IDS%?src=mobile&appOS=%OS%&appVersion=%VERSION%");
|
||||
|
|
|
@ -216,13 +216,14 @@ pref("extensions.strictCompatibility", false);
|
|||
pref("extensions.minCompatibleAppVersion", "4.0");
|
||||
|
||||
pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
|
||||
/* preferences for the Get Add-ons pane */
|
||||
pref("extensions.getAddons.cache.enabled", true);
|
||||
pref("extensions.getAddons.maxResults", 15);
|
||||
pref("extensions.getAddons.recommended.browseURL", "https://addons.mozilla.org/%LOCALE%/mobile/recommended/");
|
||||
pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/mobile/api/%API_VERSION%/list/featured/all/%MAX_RESULTS%/%OS%/%VERSION%");
|
||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/mobile/search?q=%TERMS%");
|
||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/mobile/search?q=%TERMS%&platform=%OS%&appver=%VERSION%");
|
||||
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/mobile/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%/%COMPATIBILITY_MODE%");
|
||||
pref("extensions.getAddons.browseAddons", "https://addons.mozilla.org/%LOCALE%/mobile/");
|
||||
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/mobile/api/%API_VERSION%/search/guid:%IDS%?src=mobile&appOS=%OS%&appVersion=%VERSION%");
|
||||
|
|
|
@ -2,9 +2,5 @@
|
|||
"talos.zip": {
|
||||
"url": "http://build.mozilla.org/talos/zips/talos.bug732835.zip",
|
||||
"path": ""
|
||||
},
|
||||
"pageloader.xpi": {
|
||||
"url": "http://build.mozilla.org/talos/xpis/pageloader.xpi",
|
||||
"path": "talos/page_load_test"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,18 +44,18 @@ def main():
|
|||
# 3) download the necessary files
|
||||
print "INFO: talos.json URL: %s" % options.talos_json_url
|
||||
try:
|
||||
for key in ('talos.zip', 'pageloader.xpi',):
|
||||
entity = get_value(jsonFilename, key)
|
||||
if passesRestrictions(options.talos_json_url, entity["url"]):
|
||||
# the key is at the same time the filename e.g. talos.zip
|
||||
download_file(entity["url"], entity["path"], key)
|
||||
print "INFO: %s -> %s" % (entity["url"], os.path.join(entity["path"], key))
|
||||
else:
|
||||
print "ERROR: You have tried to download a file " + \
|
||||
"from: %s " % fileUrl + \
|
||||
"which is a location different than http://build.mozilla.org/talos/"
|
||||
print "ERROR: This is only allowed for the certain branches."
|
||||
sys.exit(1)
|
||||
key = 'talos.zip'
|
||||
entity = get_value(jsonFilename, key)
|
||||
if passesRestrictions(options.talos_json_url, entity["url"]):
|
||||
# the key is at the same time the filename e.g. talos.zip
|
||||
download_file(entity["url"], entity["path"], key)
|
||||
print "INFO: %s -> %s" % (entity["url"], os.path.join(entity["path"], key))
|
||||
else:
|
||||
print "ERROR: You have tried to download a file " + \
|
||||
"from: %s " % fileUrl + \
|
||||
"which is a location different than http://build.mozilla.org/talos/"
|
||||
print "ERROR: This is only allowed for the certain branches."
|
||||
sys.exit(1)
|
||||
except Exception, e:
|
||||
print "ERROR: %s" % str(e)
|
||||
sys.exit(1)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com> (original author)
|
||||
* Panos Astithas <past@mozilla.com>
|
||||
* Mihai Sucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -50,14 +51,19 @@ var EXPORTED_SYMBOLS = ["DebuggerTransport",
|
|||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "socketTransportService",
|
||||
"@mozilla.org/network/socket-transport-service;1",
|
||||
"nsISocketTransportService");
|
||||
|
||||
let wantLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
|
||||
function dumpn(str)
|
||||
{
|
||||
dump("DBG-CLIENT: " + str + "\n");
|
||||
if (wantLogging) {
|
||||
dump("DBG-CLIENT: " + str + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
|
@ -644,7 +650,8 @@ ThreadClient.prototype = {
|
|||
}
|
||||
return;
|
||||
}
|
||||
let bpClient = new BreakpointClient(this._client, aResponse.actor);
|
||||
let bpClient = new BreakpointClient(this._client, aResponse.actor,
|
||||
aLocation);
|
||||
if (aCallback) {
|
||||
aCallback(aOnResponse(aResponse, bpClient));
|
||||
} else {
|
||||
|
@ -951,10 +958,14 @@ GripClient.prototype = {
|
|||
* The debugger client parent.
|
||||
* @param aActor string
|
||||
* The actor ID for this breakpoint.
|
||||
* @param aLocation object
|
||||
* The location of the breakpoint. This is an object with two properties:
|
||||
* url and line.
|
||||
*/
|
||||
function BreakpointClient(aClient, aActor) {
|
||||
function BreakpointClient(aClient, aActor, aLocation) {
|
||||
this._client = aClient;
|
||||
this._actor = aActor;
|
||||
this.location = aLocation;
|
||||
}
|
||||
|
||||
BreakpointClient.prototype = {
|
||||
|
|
|
@ -97,6 +97,10 @@ BrowserRootActor.prototype = {
|
|||
while (e.hasMoreElements()) {
|
||||
let win = e.getNext();
|
||||
this.unwatchWindow(win);
|
||||
// Signal our imminent shutdown.
|
||||
let evt = win.document.createEvent("Event");
|
||||
evt.initEvent("Debugger:Shutdown", true, false);
|
||||
win.document.documentElement.dispatchEvent(evt);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -415,6 +419,10 @@ BrowserTabActor.prototype = {
|
|||
* Prepare to enter a nested event loop by disabling debuggee events.
|
||||
*/
|
||||
preNest: function BTA_preNest() {
|
||||
if (!this.browser) {
|
||||
// The tab is already closed.
|
||||
return;
|
||||
}
|
||||
let windowUtils = this.browser.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
@ -426,6 +434,10 @@ BrowserTabActor.prototype = {
|
|||
* Prepare to exit a nested event loop by enabling debuggee events.
|
||||
*/
|
||||
postNest: function BTA_postNest(aNestData) {
|
||||
if (!this.browser) {
|
||||
// The tab is already closed.
|
||||
return;
|
||||
}
|
||||
let windowUtils = this.browser.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
|
|
@ -50,6 +50,9 @@ const Cu = Components.utils;
|
|||
|
||||
var EXPORTED_SYMBOLS = ["DebuggerServer"];
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
let wantLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
|
||||
function loadSubScript(aURL)
|
||||
{
|
||||
try {
|
||||
|
@ -57,14 +60,16 @@ function loadSubScript(aURL)
|
|||
.getService(Components.interfaces.mozIJSSubScriptLoader);
|
||||
loader.loadSubScript(aURL, this);
|
||||
} catch(e) {
|
||||
dump("Error loading: " + aURL + ": " + e + " - " + e.stack + "\n");
|
||||
dumpn("Error loading: " + aURL + ": " + e + " - " + e.stack + "\n");
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
function dumpn(str) {
|
||||
dump("DBG-SERVER: " + str + "\n");
|
||||
if (wantLogging) {
|
||||
dump("DBG-SERVER: " + str + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
function dbg_assert(cond, e) {
|
||||
|
|
|
@ -42,7 +42,6 @@ function test_pause_frame()
|
|||
gDebuggee.eval("(" + function() {
|
||||
var recurseLeft = 5;
|
||||
function recurse() {
|
||||
dump(recurseLeft);
|
||||
if (--recurseLeft == 0) {
|
||||
debugger;
|
||||
return;
|
||||
|
|
|
@ -32,7 +32,6 @@ function test_pause_frame()
|
|||
|
||||
gThreadClient.getFrames(0, 1, function(aResponse) {
|
||||
let frame = aResponse.frames[0];
|
||||
dump(JSON.stringify(frame));
|
||||
do_check_eq(objActor1, frame.arguments[0].actor);
|
||||
gThreadClient.resume(function () {
|
||||
finishClient(gClient);
|
||||
|
|
|
@ -51,7 +51,7 @@ const PREF_EM_LAST_PLATFORM_VERSION = "extensions.lastPlatformVersion";
|
|||
const PREF_EM_AUTOUPDATE_DEFAULT = "extensions.update.autoUpdateDefault";
|
||||
const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility";
|
||||
const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
|
||||
const PREF_EM_UPDATE_URL = "extensions.update.url";
|
||||
const PREF_EM_UPDATE_BACKGROUND_URL = "extensions.update.background.url";
|
||||
const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
|
||||
const PREF_APP_UPDATE_AUTO = "app.update.auto";
|
||||
const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
|
||||
|
@ -902,7 +902,7 @@ var AddonManagerInternal = {
|
|||
if (Services.prefs.getPrefType(PREF_EM_HOTFIX_URL) == Ci.nsIPrefBranch.PREF_STRING)
|
||||
url = Services.prefs.getCharPref(PREF_EM_HOTFIX_URL);
|
||||
else
|
||||
url = Services.prefs.getCharPref(PREF_EM_UPDATE_URL);
|
||||
url = Services.prefs.getCharPref(PREF_EM_UPDATE_BACKGROUND_URL);
|
||||
|
||||
// Build the URI from a fake add-on data.
|
||||
url = AddonManager.escapeAddonURI({
|
||||
|
|
|
@ -65,6 +65,7 @@ const PREF_DSS_SWITCHPENDING = "extensions.dss.switchPending";
|
|||
const PREF_DSS_SKIN_TO_SELECT = "extensions.lastSelectedSkin";
|
||||
const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
|
||||
const PREF_EM_UPDATE_URL = "extensions.update.url";
|
||||
const PREF_EM_UPDATE_BACKGROUND_URL = "extensions.update.background.url";
|
||||
const PREF_EM_ENABLED_ADDONS = "extensions.enabledAddons";
|
||||
const PREF_EM_EXTENSION_FORMAT = "extensions.";
|
||||
const PREF_EM_ENABLED_SCOPES = "extensions.enabledScopes";
|
||||
|
@ -6927,8 +6928,15 @@ function UpdateChecker(aAddon, aListener, aReason, aAppVersion, aPlatformVersion
|
|||
this.platformVersion = aPlatformVersion;
|
||||
this.syncCompatibility = (aReason == AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
|
||||
|
||||
let updateURL = aAddon.updateURL ? aAddon.updateURL :
|
||||
Services.prefs.getCharPref(PREF_EM_UPDATE_URL);
|
||||
let updateURL = aAddon.updateURL;
|
||||
if (!updateURL) {
|
||||
if (aReason == AddonManager.UPDATE_WHEN_PERIODIC_UPDATE &&
|
||||
Services.prefs.getPrefType(PREF_EM_UPDATE_BACKGROUND_URL) == Services.prefs.PREF_STRING) {
|
||||
updateURL = Services.prefs.getCharPref(PREF_EM_UPDATE_BACKGROUND_URL);
|
||||
} else {
|
||||
updateURL = Services.prefs.getCharPref(PREF_EM_UPDATE_URL);
|
||||
}
|
||||
}
|
||||
|
||||
const UPDATE_TYPE_COMPATIBILITY = 32;
|
||||
const UPDATE_TYPE_NEWVERSION = 64;
|
||||
|
|
|
@ -59,6 +59,7 @@ var gUseInContentUI = !gTestInWindow && ("switchToTabHavingURI" in window);
|
|||
var gRestorePrefs = [{name: PREF_LOGGING_ENABLED},
|
||||
{name: "extensions.webservice.discoverURL"},
|
||||
{name: "extensions.update.url"},
|
||||
{name: "extensions.update.background.url"},
|
||||
{name: "extensions.getAddons.get.url"},
|
||||
{name: "extensions.getAddons.getWithPerformance.url"},
|
||||
{name: "extensions.getAddons.search.browseURL"},
|
||||
|
|
|
@ -45,5 +45,26 @@
|
|||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:addon3@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<!-- app id compatible update available -->
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>2</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>1</em:maxVersion>
|
||||
<em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
</RDF:RDF>
|
||||
|
||||
|
|
|
@ -1127,6 +1127,7 @@ Services.prefs.setBoolPref("extensions.showMismatchUI", false);
|
|||
|
||||
// Point update checks to the local machine for fast failures
|
||||
Services.prefs.setCharPref("extensions.update.url", "http://127.0.0.1/updateURL");
|
||||
Services.prefs.setCharPref("extensions.update.background.url", "http://127.0.0.1/updateBackgroundURL");
|
||||
Services.prefs.setCharPref("extensions.blocklist.url", "http://127.0.0.1/blocklistURL");
|
||||
|
||||
// By default ignore bundled add-ons
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// This verifies that background update notifications work as expected
|
||||
// This verifies that background updates & notifications work as expected
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
|
||||
|
@ -74,6 +74,20 @@ function run_test_2() {
|
|||
name: "Test Addon 2",
|
||||
}, profileDir);
|
||||
|
||||
writeInstallRDFForExtension({
|
||||
id: "addon3@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}],
|
||||
name: "Test Addon 3",
|
||||
}, profileDir);
|
||||
|
||||
// Background update uses a different pref, if set
|
||||
Services.prefs.setCharPref("extensions.update.background.url",
|
||||
"http://localhost:4444/data/test_backgroundupdate.rdf");
|
||||
restartManager();
|
||||
|
||||
// Do hotfix checks
|
||||
|
@ -87,7 +101,7 @@ function run_test_2() {
|
|||
Services.obs.addObserver(function() {
|
||||
Services.obs.removeObserver(arguments.callee, "addons-background-update-complete");
|
||||
|
||||
do_check_eq(installCount, 2);
|
||||
do_check_eq(installCount, 3);
|
||||
sawCompleteNotification = true;
|
||||
}, "addons-background-update-complete", false);
|
||||
|
||||
|
@ -98,7 +112,7 @@ function run_test_2() {
|
|||
|
||||
onDownloadFailed: function(aInstall) {
|
||||
completeCount++;
|
||||
if (completeCount == 2) {
|
||||
if (completeCount == 3) {
|
||||
do_check_true(sawCompleteNotification);
|
||||
end_test();
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ function end_test() {
|
|||
// Test that background updates find and install any available hotfix
|
||||
function run_test_1() {
|
||||
Services.prefs.setCharPref("extensions.hotfix.id", "hotfix@tests.mozilla.org");
|
||||
Services.prefs.setCharPref("extensions.update.url", "http://localhost:4444/data/test_hotfix_1.rdf");
|
||||
Services.prefs.setCharPref("extensions.update.background.url", "http://localhost:4444/data/test_hotfix_1.rdf");
|
||||
|
||||
prepare_test({
|
||||
"hotfix@tests.mozilla.org": [
|
||||
|
|
Загрузка…
Ссылка в новой задаче