Merge mozilla-central to mozilla-inbound

This commit is contained in:
Matt Brubeck 2012-03-08 16:27:40 -08:00
Родитель d25c224c40 beb0053f42
Коммит 2ff1acb70e
77 изменённых файлов: 1505 добавлений и 231 удалений

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

@ -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%&currentAppVersion=%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%&currentAppVersion=%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%&currentAppVersion=%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%&currentAppVersion=%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%&currentAppVersion=%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%&currentAppVersion=%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": [