merge fx-team to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-04-21 12:06:04 +02:00
commit f8be499db0
74 changed files with 790 additions and 642 deletions

View File

@ -371,29 +371,30 @@ exports.testTabMove = function(assert, done) {
};
exports.testIgnoreClosing = function(assert, done) {
let originalWindow = browserWindows.activeWindow;
let originalWindow = viewFor(browserWindows.activeWindow);
openBrowserWindow(function(window, browser) {
let url = "data:text/html;charset=utf-8,foobar";
onFocus(window).then(() => {
let url = "data:text/html;charset=utf-8,foobar";
assert.equal(tabs.length, 2, "should be two windows open each with one tab");
assert.equal(tabs.length, 2, "should be two windows open each with one tab");
tabs.on('ready', function onReady(tab) {
tabs.removeListener('ready', onReady);
tabs.on('ready', function onReady(tab) {
tabs.removeListener('ready', onReady);
let win = tab.window;
assert.equal(win.tabs.length, 2, "should be two tabs in the new window");
assert.equal(tabs.length, 3, "should be three tabs in total");
let win = tab.window;
assert.equal(win.tabs.length, 2, "should be two tabs in the new window");
assert.equal(tabs.length, 3, "should be three tabs in total");
tab.close(function() {
assert.equal(win.tabs.length, 1, "should be one tab in the new window");
assert.equal(tabs.length, 2, "should be two tabs in total");
tab.close(function() {
assert.equal(win.tabs.length, 1, "should be one tab in the new window");
assert.equal(tabs.length, 2, "should be two tabs in total");
originalWindow.once("activate", done);
close(window);
close(window).then(onFocus(originalWindow)).then(done).then(null, assert.fail);
});
});
});
tabs.open(url);
tabs.open(url);
});
});
};

View File

@ -252,7 +252,7 @@ pref("browser.uitour.requireSecure", true);
pref("browser.uitour.themeOrigin", "https://addons.mozilla.org/%LOCALE%/firefox/themes/");
pref("browser.uitour.url", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/tour/");
// This is used as a regexp match against the page's URL.
pref("browser.uitour.readerViewTrigger", "^https:\/\/www\.mozilla\.org\/[^\/]+\/firefox\/reading\/start");
pref("browser.uitour.readerViewTrigger", "^https:\\/\\/www\\.mozilla\\.org\\/[^\\/]+\\/firefox\\/reading\\/start");
pref("browser.customizemode.tip0.shown", false);
pref("browser.customizemode.tip0.learnMoreUrl", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/customize");
@ -1880,12 +1880,9 @@ pref("dom.ipc.reportProcessHangs", false);
pref("dom.ipc.reportProcessHangs", true);
#endif
// Enable ReadingList browser UI by default.
pref("browser.readinglist.enabled", true);
pref("browser.readinglist.enabled", false);
pref("browser.readinglist.sidebarEverOpened", false);
// Enable the readinglist engine by default.
pref("readinglist.scheduler.enabled", true);
pref("readinglist.scheduler.enabled", false);
pref("readinglist.server", "https://readinglist.services.mozilla.com/v1");
// Don't limit how many nodes we care about on desktop:

View File

@ -8,9 +8,16 @@
* Tests that we build a working leftpane in various corruption situations.
*/
function run_test() {
// Used to store the original leftPaneFolderId getter.
let gLeftPaneFolderIdGetter;
let gAllBookmarksFolderIdGetter;
// Used to store the original left Pane status as a JSON string.
let gReferenceHierarchy;
let gLeftPaneFolderId;
add_task(function* () {
// We want empty roots.
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
// Sanity check.
Assert.ok(!!PlacesUIUtils);
@ -21,17 +28,8 @@ function run_test() {
gAllBookmarksFolderIdGetter = Object.getOwnPropertyDescriptor(PlacesUIUtils, "allBookmarksFolderId");
Assert.equal(typeof(gAllBookmarksFolderIdGetter.get), "function");
run_next_test();
}
do_register_cleanup(remove_all_bookmarks);
// Used to store the original leftPaneFolderId getter.
let gLeftPaneFolderIdGetter;
let gAllBookmarksFolderIdGetter;
// Used to store the original left Pane status as a JSON string.
let gReferenceHierarchy;
let gLeftPaneFolderId;
do_register_cleanup(() => PlacesUtils.bookmarks.eraseEverything());
});
add_task(function* () {
// Add a third party bogus annotated item. Should not be removed.

View File

@ -15,6 +15,7 @@ Cu.import("resource://gre/modules/Timer.jsm");
do_get_profile();
let prefs = new Preferences("readinglist.scheduler.");
prefs.set("enabled", true);
function promiseObserver(topic) {
return new Promise(resolve => {

View File

@ -1829,6 +1829,7 @@ MarkupContainer.prototype = {
this.hovered = false;
this.markup.navigate(this);
event.stopPropagation();
event.preventDefault();
// Start dragging the container after a delay.
this.markup._dragStartEl = target;
@ -2145,7 +2146,7 @@ MarkupElementContainer.prototype = Heritage.extend(MarkupContainer.prototype, {
this.tooltipData.data = promise.resolve(res);
});
}, () => {
this.tooltipData.data = promise.reject();
this.tooltipData.data = promise.resolve({});
});
}
},
@ -2165,9 +2166,11 @@ MarkupElementContainer.prototype = Heritage.extend(MarkupContainer.prototype, {
}
return this.tooltipData.data.then(({data, size}) => {
tooltip.setImageContent(data, size);
}, () => {
tooltip.setBrokenImageContent();
if (data && size) {
tooltip.setImageContent(data, size);
} else {
tooltip.setBrokenImageContent();
}
});
},

View File

@ -68,12 +68,14 @@ skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markupview_events_jquery_2.1.1.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markupview_load_01.js]
[browser_markupview_html_edit_01.js]
[browser_markupview_html_edit_02.js]
[browser_markupview_html_edit_03.js]
[browser_markupview_image_tooltip.js]
[browser_markupview_keybindings_01.js]
[browser_markupview_keybindings_02.js]
[browser_markupview_keybindings_03.js]
[browser_markupview_mutation_01.js]
[browser_markupview_mutation_02.js]
[browser_markupview_navigation.js]

View File

@ -21,7 +21,8 @@ add_task(function*() {
target: el.tagLine,
pageX: rect.x,
pageY: rect.y,
stopPropagation: function() {}
stopPropagation: function() {},
preventDefault: function() {}
});
is(el.isDragging, false, "isDragging should not be set to true immedietly");

View File

@ -64,7 +64,8 @@ function* dragContainer(selector, targetOffset, inspector) {
target: container.tagLine,
pageX: rect.x,
pageY: rect.y,
stopPropagation: function() {}
stopPropagation: function() {},
preventDefault: function() {}
});
let targetX = rect.x + targetOffset.x,

View File

@ -157,16 +157,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":894",
@ -197,6 +187,16 @@ const TEST_DATA = [
" return returnValue;\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":894",

View File

@ -171,16 +171,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":1224",
@ -221,6 +211,16 @@ const TEST_DATA = [
" return returnValue;\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":1224",

View File

@ -103,16 +103,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
@ -124,6 +114,16 @@ const TEST_DATA = [
" return typeof m === K || a && m.event.triggered === a.type ? void 0 : m.event.dispatch.apply(k.elem, arguments)\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
@ -141,17 +141,6 @@ const TEST_DATA = [
{
selector: "#livediv",
expected: [
{
type: "dragleave",
filename: TEST_URL + ":30",
attributes: [
"jQuery",
"Live"
],
handler: "var handler3 = function liveDivDragLeave() {\n" +
" alert(3);\n" +
"}"
},
{
type: "dragend",
filename: TEST_URL + ":31",
@ -164,14 +153,14 @@ const TEST_DATA = [
"}"
},
{
type: "drop",
filename: TEST_URL + ":32",
type: "dragleave",
filename: TEST_URL + ":30",
attributes: [
"jQuery",
"Live"
],
handler: "var handler5 = function liveDivDrop() {\n" +
" alert(5);\n" +
handler: "var handler3 = function liveDivDragLeave() {\n" +
" alert(3);\n" +
"}"
},
{
@ -184,6 +173,17 @@ const TEST_DATA = [
handler: "var handler6 = function liveDivDragOver() {\n" +
" alert(6);\n" +
"}"
},
{
type: "drop",
filename: TEST_URL + ":32",
attributes: [
"jQuery",
"Live"
],
handler: "var handler5 = function liveDivDrop() {\n" +
" alert(5);\n" +
"}"
}
]
},

View File

@ -142,16 +142,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":24",
@ -166,6 +156,16 @@ const TEST_DATA = [
" return val;\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":24",

View File

@ -16,17 +16,6 @@ const TEST_DATA = [
{
selector: "html",
expected: [
{
type: "unload",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
attributes: [
"jQuery"
],
handler: "function(H) {\n" +
" n(this).unbind(H, D);\n" +
" return (E || G).apply(this, arguments)\n" +
"}"
},
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
@ -108,7 +97,7 @@ const TEST_DATA = [
"}"
},
{
type: "unload",
type: "load",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
attributes: [
"Bubbling",
@ -119,7 +108,18 @@ const TEST_DATA = [
"}"
},
{
type: "load",
type: "unload",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
attributes: [
"jQuery"
],
handler: "function(H) {\n" +
" n(this).unbind(H, D);\n" +
" return (E || G).apply(this, arguments)\n" +
"}"
},
{
type: "unload",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
attributes: [
"Bubbling",
@ -154,16 +154,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
@ -175,6 +165,16 @@ const TEST_DATA = [
" return typeof n !== \"undefined\" && !n.event.triggered ? n.event.handle.apply(arguments.callee.elem, arguments) : g\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":19",

View File

@ -121,16 +121,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":48",
@ -142,6 +132,16 @@ const TEST_DATA = [
" return typeof c !== \"undefined\" && !c.event.triggered ? c.event.handle.apply(j.elem, arguments) : w\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":48",
@ -169,17 +169,6 @@ const TEST_DATA = [
" alert(1);\n" +
"}"
},
{
type: "dragstart",
filename: TEST_URL + ":29",
attributes: [
"jQuery",
"Live"
],
handler: "var handler2 = function liveDivDragStart() {\n" +
" alert(2);\n" +
"}"
},
{
type: "dblclick",
filename: TEST_URL_ROOT + TEST_LIB + ":17",
@ -228,6 +217,17 @@ const TEST_DATA = [
" return b\n" +
"}"
},
{
type: "dragstart",
filename: TEST_URL + ":29",
attributes: [
"jQuery",
"Live"
],
handler: "var handler2 = function liveDivDragStart() {\n" +
" alert(2);\n" +
"}"
},
{
type: "dragstart",
filename: TEST_URL_ROOT + TEST_LIB + ":17",

View File

@ -118,16 +118,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
@ -139,6 +129,16 @@ const TEST_DATA = [
" return typeof f != \"undefined\" && (!a || f.event.triggered !== a.type) ? f.event.handle.apply(k.elem, arguments) : b\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
@ -166,39 +166,6 @@ const TEST_DATA = [
" alert(1);\n" +
"}"
},
{
type: "dragstart",
filename: TEST_URL + ":29",
attributes: [
"jQuery",
"Live"
],
handler: "var handler2 = function liveDivDragStart() {\n" +
" alert(2);\n" +
"}"
},
{
type: "dragleave",
filename: TEST_URL + ":30",
attributes: [
"jQuery",
"Live"
],
handler: "var handler3 = function liveDivDragLeave() {\n" +
" alert(3);\n" +
"}"
},
{
type: "dragend",
filename: TEST_URL + ":31",
attributes: [
"jQuery",
"Live"
],
handler: "var handler4 = function liveDivDragEnd() {\n" +
" alert(4);\n" +
"}"
},
{
type: "dblclick",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
@ -244,7 +211,18 @@ const TEST_DATA = [
"}"
},
{
type: "dragstart",
type: "dragend",
filename: TEST_URL + ":31",
attributes: [
"jQuery",
"Live"
],
handler: "var handler4 = function liveDivDragEnd() {\n" +
" alert(4);\n" +
"}"
},
{
type: "dragend",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
attributes: [
"jQuery",
@ -287,6 +265,17 @@ const TEST_DATA = [
" }\n" +
"}"
},
{
type: "dragleave",
filename: TEST_URL + ":30",
attributes: [
"jQuery",
"Live"
],
handler: "var handler3 = function liveDivDragLeave() {\n" +
" alert(3);\n" +
"}"
},
{
type: "dragleave",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
@ -332,7 +321,18 @@ const TEST_DATA = [
"}"
},
{
type: "dragend",
type: "dragstart",
filename: TEST_URL + ":29",
attributes: [
"jQuery",
"Live"
],
handler: "var handler2 = function liveDivDragStart() {\n" +
" alert(2);\n" +
"}"
},
{
type: "dragstart",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
attributes: [
"jQuery",

View File

@ -118,16 +118,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
@ -139,6 +129,16 @@ const TEST_DATA = [
" return typeof f != \"undefined\" && (!a || f.event.triggered !== a.type) ? f.event.dispatch.apply(i.elem, arguments) : b\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
@ -167,14 +167,14 @@ const TEST_DATA = [
"}"
},
{
type: "dragstart",
filename: TEST_URL + ":29",
type: "dragend",
filename: TEST_URL + ":31",
attributes: [
"jQuery",
"Live"
],
handler: "var handler2 = function liveDivDragStart() {\n" +
" alert(2);\n" +
handler: "var handler4 = function liveDivDragEnd() {\n" +
" alert(4);\n" +
"}"
},
{
@ -189,14 +189,25 @@ const TEST_DATA = [
"}"
},
{
type: "dragend",
filename: TEST_URL + ":31",
type: "dragover",
filename: TEST_URL + ":33",
attributes: [
"jQuery",
"Live"
],
handler: "var handler4 = function liveDivDragEnd() {\n" +
" alert(4);\n" +
handler: "var handler6 = function liveDivDragOver() {\n" +
" alert(6);\n" +
"}"
},
{
type: "dragstart",
filename: TEST_URL + ":29",
attributes: [
"jQuery",
"Live"
],
handler: "var handler2 = function liveDivDragStart() {\n" +
" alert(2);\n" +
"}"
},
{
@ -209,17 +220,6 @@ const TEST_DATA = [
handler: "var handler5 = function liveDivDrop() {\n" +
" alert(5);\n" +
"}"
},
{
type: "dragover",
filename: TEST_URL + ":33",
attributes: [
"jQuery",
"Live"
],
handler: "var handler6 = function liveDivDragOver() {\n" +
" alert(6);\n" +
"}"
}
]
},

View File

@ -102,16 +102,6 @@ const TEST_DATA = [
" alert(8);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
@ -123,6 +113,16 @@ const TEST_DATA = [
" return typeof n !== U && n.event.triggered !== b.type ? n.event.dispatch.apply(a, arguments) : void 0\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL + ":36",
attributes: [
"jQuery"
],
handler: "var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
"}"
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
@ -139,17 +139,6 @@ const TEST_DATA = [
{
selector: "#livediv",
expected: [
{
type: "dragleave",
filename: TEST_URL + ":30",
attributes: [
"jQuery",
"Live"
],
handler: "var handler3 = function liveDivDragLeave() {\n" +
" alert(3);\n" +
"}"
},
{
type: "dragend",
filename: TEST_URL + ":31",
@ -162,14 +151,14 @@ const TEST_DATA = [
"}"
},
{
type: "drop",
filename: TEST_URL + ":32",
type: "dragleave",
filename: TEST_URL + ":30",
attributes: [
"jQuery",
"Live"
],
handler: "var handler5 = function liveDivDrop() {\n" +
" alert(5);\n" +
handler: "var handler3 = function liveDivDragLeave() {\n" +
" alert(3);\n" +
"}"
},
{
@ -182,6 +171,17 @@ const TEST_DATA = [
handler: "var handler6 = function liveDivDragOver() {\n" +
" alert(6);\n" +
"}"
},
{
type: "drop",
filename: TEST_URL + ":32",
attributes: [
"jQuery",
"Live"
],
handler: "var handler5 = function liveDivDrop() {\n" +
" alert(5);\n" +
"}"
}
]
},

View File

@ -0,0 +1,34 @@
/* 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";
// Tests that selecting a node with the mouse (by clicking on the line) focuses
// the first focusable element in the corresponding MarkupContainer so that the
// keyboard can be used immediately.
const TEST_URL = "data:text/html;charset=utf8,<div></div>Text node";
add_task(function*() {
let {inspector, toolbox} = yield addTab(TEST_URL).then(openInspector);
let {walker} = inspector;
info("Select the test node to have the 2 test containers visible");
yield selectNode("div", inspector);
let divFront = yield walker.querySelector(walker.rootNode, "div");
let textFront = yield walker.nextSibling(divFront);
info("Click on the MarkupContainer element for the text node");
yield clickContainer(textFront, inspector);
is(inspector.markup.doc.activeElement,
getContainerForNodeFront(textFront, inspector).editor.value,
"The currently focused element is the node's text content");
info("Click on the MarkupContainer element for the <div> node");
yield clickContainer(divFront, inspector);
is(inspector.markup.doc.activeElement,
getContainerForNodeFront(divFront, inspector).editor.tag,
"The currently focused element is the div's tagname");
});

View File

@ -0,0 +1,70 @@
/* 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";
// Tests that selecting an element with the 'Inspect Element' context
// menu during a page reload doesn't cause the markup view to become empty.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1036324
const server = createTestHTTPServer();
// Register a slow image handler so we can simulate a long time between
// a reload and the load event firing.
server.registerContentType("gif", "image/gif");
server.registerPathHandler("/slow.gif", function (metadata, response) {
info ("Image has been requested");
response.processAsync();
setTimeout(() => {
info ("Image is responding");
response.finish();
}, 500);
});
// Test page load events.
const TEST_URL = "data:text/html," +
"<!DOCTYPE html>" +
"<head><meta charset='utf-8' /></head>" +
"<body>" +
"<p>Slow script</p>" +
"<img src='http://localhost:" + server.identity.primaryPort + "/slow.gif' /></script>" +
"</body>" +
"</html>";
add_task(function*() {
let tab = yield addTab(TEST_URL);
let {inspector} = yield openInspector();
let domContentLoaded = waitForLinkedBrowserEvent(tab, "DOMContentLoaded");
let pageLoaded = waitForLinkedBrowserEvent(tab, "load");
ok (inspector.markup, "There is a markup view");
// Select an element while the tab is in the middle of a slow reload.
reloadTab();
yield domContentLoaded;
yield chooseWithInspectElementContextMenu("img");
yield pageLoaded;
yield inspector.once("markuploaded");
ok (inspector.markup, "There is a markup view");
is (inspector.markup._elt.children.length, 1, "The markup view is rendering");
});
function* chooseWithInspectElementContextMenu(selector) {
yield executeInContent("Test:SynthesizeMouse", {
center: true,
selector: selector,
options: {type: "contextmenu", button: 2}
});
executeInContent("Test:SynthesizeKey", {key: "Q", options: {}});
}
function waitForLinkedBrowserEvent(tab, event) {
let def = promise.defer();
tab.linkedBrowser.addEventListener(event, function cb() {
tab.linkedBrowser.removeEventListener(event, cb, true);
def.resolve();
}, true);
return def.promise;
}

View File

@ -172,6 +172,13 @@ function executeInContent(name, data={}, objects={}, expectResponse=true) {
}
}
/**
* Reload the current tab location.
*/
function reloadTab() {
return executeInContent("devtools:test:reload", {}, {}, false);
}
/**
* Simple DOM node accesor function that takes either a node or a string css
* selector as argument and returns the corresponding node
@ -647,3 +654,34 @@ function* waitForMultipleChildrenUpdates(inspector) {
return yield waitForMultipleChildrenUpdates(inspector);
}
}
/**
* Create an HTTP server that can be used to simulate custom requests within
* a test. It is automatically cleaned up when the test ends, so no need to
* call `destroy`.
*
* See https://developer.mozilla.org/en-US/docs/Httpd.js/HTTP_server_for_unit_tests
* for more information about how to register handlers.
*
* The server can be accessed like:
*
* const server = createTestHTTPServer();
* let url = "http://localhost: " + server.identity.primaryPort + "/path";
*
* @returns {HttpServer}
*/
function createTestHTTPServer() {
const {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
let server = new HttpServer();
registerCleanupFunction(function* cleanup() {
let destroyed = promise.defer();
server.stop(() => {
destroyed.resolve();
});
yield destroyed.promise;
});
server.start(-1);
return server;
}

View File

@ -1230,6 +1230,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
break;
case "remoteAddress":
requestItem.attachment.remoteAddress = value;
this.updateMenuView(requestItem, key, value);
break;
case "remotePort":
requestItem.attachment.remotePort = value;
@ -1382,6 +1383,11 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
domain.setAttribute("tooltiptext", hostPort);
break;
}
case "remoteAddress":
let domain = $(".requests-menu-domain", target);
let tooltip = domain.getAttribute("value") + " (" + aValue + ")";
domain.setAttribute("tooltiptext", tooltip);
break;
case "securityState": {
let tooltip = L10N.getStr("netmonitor.security.state." + aValue);
let icon = $(".requests-security-state-icon", target);

View File

@ -275,34 +275,37 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
let name = uri.fileName || "/";
let query = uri.query;
let hostPort = uri.hostPort;
let remoteAddress = attachment.remoteAddress;
if (fuzzyUrl) {
ok(attachment.method.startsWith(aMethod), "The attached method is incorrect.");
ok(attachment.url.startsWith(aUrl), "The attached url is incorrect.");
ok(attachment.method.startsWith(aMethod), "The attached method is correct.");
ok(attachment.url.startsWith(aUrl), "The attached url is correct.");
} else {
is(attachment.method, aMethod, "The attached method is incorrect.");
is(attachment.url, aUrl, "The attached url is incorrect.");
is(attachment.method, aMethod, "The attached method is correct.");
is(attachment.url, aUrl, "The attached url is correct.");
}
is(target.querySelector(".requests-menu-method").getAttribute("value"),
aMethod, "The displayed method is incorrect.");
aMethod, "The displayed method is correct.");
if (fuzzyUrl) {
ok(target.querySelector(".requests-menu-file").getAttribute("value").startsWith(
name + (query ? "?" + query : "")), "The displayed file is incorrect.");
name + (query ? "?" + query : "")), "The displayed file is correct.");
ok(target.querySelector(".requests-menu-file").getAttribute("tooltiptext").startsWith(
name + (query ? "?" + query : "")), "The tooltip file is incorrect.");
name + (query ? "?" + query : "")), "The tooltip file is correct.");
} else {
is(target.querySelector(".requests-menu-file").getAttribute("value"),
name + (query ? "?" + query : ""), "The displayed file is incorrect.");
name + (query ? "?" + query : ""), "The displayed file is correct.");
is(target.querySelector(".requests-menu-file").getAttribute("tooltiptext"),
name + (query ? "?" + query : ""), "The tooltip file is incorrect.");
name + (query ? "?" + query : ""), "The tooltip file is correct.");
}
is(target.querySelector(".requests-menu-domain").getAttribute("value"),
hostPort, "The displayed domain is incorrect.");
hostPort, "The displayed domain is correct.");
let domainTooltip = hostPort + (remoteAddress ? " (" + remoteAddress + ")" : "");
is(target.querySelector(".requests-menu-domain").getAttribute("tooltiptext"),
hostPort, "The tooltip domain is incorrect.");
domainTooltip, "The tooltip domain is correct.");
if (status !== undefined) {
let value = target.querySelector(".requests-menu-status").getAttribute("code");
@ -311,54 +314,54 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
info("Displayed status: " + value);
info("Displayed code: " + codeValue);
info("Tooltip status: " + tooltip);
is(value, status, "The displayed status is incorrect.");
is(codeValue, status, "The displayed status code is incorrect.");
is(tooltip, status + " " + statusText, "The tooltip status is incorrect.");
is(value, status, "The displayed status is correct.");
is(codeValue, status, "The displayed status code is correct.");
is(tooltip, status + " " + statusText, "The tooltip status is correct.");
}
if (type !== undefined) {
let value = target.querySelector(".requests-menu-type").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-type").getAttribute("tooltiptext");
info("Displayed type: " + value);
info("Tooltip type: " + tooltip);
is(value, type, "The displayed type is incorrect.");
is(tooltip, fullMimeType, "The tooltip type is incorrect.");
is(value, type, "The displayed type is correct.");
is(tooltip, fullMimeType, "The tooltip type is correct.");
}
if (transferred !== undefined) {
let value = target.querySelector(".requests-menu-transferred").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-transferred").getAttribute("tooltiptext");
info("Displayed transferred size: " + value);
info("Tooltip transferred size: " + tooltip);
is(value, transferred, "The displayed transferred size is incorrect.");
is(tooltip, transferred, "The tooltip transferred size is incorrect.");
is(value, transferred, "The displayed transferred size is correct.");
is(tooltip, transferred, "The tooltip transferred size is correct.");
}
if (size !== undefined) {
let value = target.querySelector(".requests-menu-size").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-size").getAttribute("tooltiptext");
info("Displayed size: " + value);
info("Tooltip size: " + tooltip);
is(value, size, "The displayed size is incorrect.");
is(tooltip, size, "The tooltip size is incorrect.");
is(value, size, "The displayed size is correct.");
is(tooltip, size, "The tooltip size is correct.");
}
if (time !== undefined) {
let value = target.querySelector(".requests-menu-timings-total").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-timings-total").getAttribute("tooltiptext");
info("Displayed time: " + value);
info("Tooltip time: " + tooltip);
ok(~~(value.match(/[0-9]+/)) >= 0, "The displayed time is incorrect.");
ok(~~(tooltip.match(/[0-9]+/)) >= 0, "The tooltip time is incorrect.");
ok(~~(value.match(/[0-9]+/)) >= 0, "The displayed time is correct.");
ok(~~(tooltip.match(/[0-9]+/)) >= 0, "The tooltip time is correct.");
}
if (visibleIndex != -1) {
if (visibleIndex % 2 == 0) {
ok(aRequestItem.target.hasAttribute("even"),
"Unexpected 'even' attribute for " + aRequestItem.value);
aRequestItem.value + " should have 'even' attribute.");
ok(!aRequestItem.target.hasAttribute("odd"),
"Unexpected 'odd' attribute for " + aRequestItem.value);
aRequestItem.value + " shouldn't have 'odd' attribute.");
} else {
ok(!aRequestItem.target.hasAttribute("even"),
"Unexpected 'even' attribute for " + aRequestItem.value);
aRequestItem.value + " shouldn't have 'even' attribute.");
ok(aRequestItem.target.hasAttribute("odd"),
"Unexpected 'odd' attribute for " + aRequestItem.value);
aRequestItem.value + " should have 'odd' attribute.");
}
}
}

View File

@ -3,11 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Cu = Components.utils;
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
devtools.lazyImporter(this, "promise", "resource://gre/modules/Promise.jsm", "Promise");
devtools.lazyImporter(this, "Task", "resource://gre/modules/Task.jsm", "Task");
const loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
let EventUtils = {};
loader.loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
addMessageListener("devtools:test:history", function ({ data }) {
content.history[data.direction]();
@ -189,6 +192,55 @@ addMessageListener("devtools:test:setAttribute", function(msg) {
sendAsyncMessage("devtools:test:setAttribute");
});
/**
* Synthesize a mouse event on an element. This handler doesn't send a message
* back. Consumers should listen to specific events on the inspector/highlighter
* to know when the event got synthesized.
* @param {Object} msg The msg.data part expects the following properties:
* - {Number} x
* - {Number} y
* - {Boolean} center If set to true, x/y will be ignored and
* synthesizeMouseAtCenter will be used instead
* - {Object} options Other event options
* - {String} selector An optional selector that will be used to find the node to
* synthesize the event on, if msg.objects doesn't contain the CPOW.
* The msg.objects part should be the element.
* @param {Object} data Event detail properties:
*/
addMessageListener("Test:SynthesizeMouse", function(msg) {
let {x, y, center, options, selector} = msg.data;
let {node} = msg.objects;
if (!node && selector) {
node = superQuerySelector(selector);
}
if (center) {
EventUtils.synthesizeMouseAtCenter(node, options, node.ownerDocument.defaultView);
} else {
EventUtils.synthesizeMouse(node, x, y, options, node.ownerDocument.defaultView);
}
// Most consumers won't need to listen to this message, unless they want to
// wait for the mouse event to be synthesized and don't have another event
// to listen to instead.
sendAsyncMessage("Test:SynthesizeMouse");
});
/**
* Synthesize a key event for an element. This handler doesn't send a message
* back. Consumers should listen to specific events on the inspector/highlighter
* to know when the event got synthesized.
* @param {Object} msg The msg.data part expects the following properties:
* - {String} key
* - {Object} options
*/
addMessageListener("Test:SynthesizeKey", function(msg) {
let {key, options} = msg.data;
EventUtils.synthesizeKey(key, options, content);
});
/**
* Like document.querySelector but can go into iframes too.
* ".container iframe || .sub-container div" will first try to find the node

View File

@ -307,7 +307,6 @@ skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug intermittent)
[browser_webconsole_certificate_messages.js]
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
[browser_webconsole_show_subresource_security_errors.js]
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
[browser_webconsole_cached_autocomplete.js]
[browser_webconsole_change_font_size.js]
[browser_webconsole_chrome.js]

View File

@ -990,7 +990,7 @@ nsBidiPresUtils::TraverseFrames(nsBlockFrame* aBlockFrame,
if (frame->IsFrameOfType(nsIFrame::eBidiInlineContainer)) {
if (!(frame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
nsContainerFrame* c = static_cast<nsContainerFrame*>(frame);
MOZ_ASSERT(c = do_QueryFrame(frame),
MOZ_ASSERT(c == do_QueryFrame(frame),
"eBidiInlineContainer must be a nsContainerFrame subclass");
c->DrainSelfOverflowList();
}

View File

@ -205,7 +205,7 @@ nsHTMLCSSStyleSheet::EvictStyleAttr(const nsAString& aSerialized,
{
#ifdef DEBUG
{
NS_ASSERTION(aValue = mCachedStyleAttrs.Get(aSerialized),
NS_ASSERTION(aValue == mCachedStyleAttrs.Get(aSerialized),
"Cached value does not match?!");
}
#endif

View File

@ -13,11 +13,9 @@ import java.util.Set;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.R;
import org.mozilla.gecko.background.ReadingListConstants;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.fxa.FxAccountUtils;
import org.mozilla.gecko.background.preferences.PreferenceFragment;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.fxa.FirefoxAccounts;
import org.mozilla.gecko.fxa.FxAccountConstants;
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
@ -31,7 +29,6 @@ import org.mozilla.gecko.sync.SyncConfiguration;
import org.mozilla.gecko.util.HardwareUtils;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@ -178,9 +175,6 @@ public class FxAccountStatusFragment
historyPreference = (CheckBoxPreference) ensureFindPreference("history");
tabsPreference = (CheckBoxPreference) ensureFindPreference("tabs");
passwordsPreference = (CheckBoxPreference) ensureFindPreference("passwords");
// The Reading List toggle appears with the other Firefox Sync toggles but
// controls a separate Android authority.
readingListPreference = (CheckBoxPreference) ensureFindPreference("reading_list");
if (!FxAccountUtils.LOG_PERSONAL_INFORMATION) {
removeDebugButtons();
@ -200,7 +194,6 @@ public class FxAccountStatusFragment
historyPreference.setOnPreferenceClickListener(this);
tabsPreference.setOnPreferenceClickListener(this);
passwordsPreference.setOnPreferenceClickListener(this);
readingListPreference.setOnPreferenceClickListener(this);
deviceNamePreference = (EditTextPreference) ensureFindPreference("device_name");
deviceNamePreference.setOnPreferenceChangeListener(this);
@ -288,14 +281,6 @@ public class FxAccountStatusFragment
return true;
}
if (preference == readingListPreference) {
final boolean syncAutomatically = readingListPreference.isChecked();
ContentResolver.setIsSyncable(fxAccount.getAndroidAccount(), BrowserContract.READING_LIST_AUTHORITY, 1);
ContentResolver.setSyncAutomatically(fxAccount.getAndroidAccount(), BrowserContract.READING_LIST_AUTHORITY, syncAutomatically);
FxAccountUtils.pii(LOG_TAG, (syncAutomatically ? "En" : "Dis") + "abling Reading List sync automatically.");
return true;
}
if (preference == morePreference) {
getActivity().openOptionsMenu();
return true;
@ -330,11 +315,6 @@ public class FxAccountStatusFragment
// Since we can't sync, we can't update our remote client record.
deviceNamePreference.setEnabled(enabled);
syncNowPreference.setEnabled(enabled);
// The checkboxes are a set of global settings: they reflect the account
// state and not the underlying Sync state. In the future, each checkbox
// will reflect its own piece of the account state.
readingListPreference.setEnabled(enabled);
}
/**
@ -556,7 +536,6 @@ public class FxAccountStatusFragment
} finally {
// No matter our state, we should update the checkboxes.
updateSelectedEngines();
updateReadingList();
}
final String clientName = clientsDataDelegate.getClientName();
@ -668,19 +647,6 @@ public class FxAccountStatusFragment
}
}
/**
* Query the current reading list automatic sync state, and update the UI
* accordingly.
*/
protected void updateReadingList() {
if (AppConstants.MOZ_ANDROID_READING_LIST_SERVICE) {
final boolean syncAutomatically = ContentResolver.getSyncAutomatically(fxAccount.getAndroidAccount(), BrowserContract.READING_LIST_AUTHORITY);
readingListPreference.setChecked(syncAutomatically);
} else {
syncCategory.removePreference(readingListPreference);
}
}
/**
* Persist engine selections to local shared preferences, and request a sync
* to persist selections to remote storage.
@ -790,16 +756,6 @@ public class FxAccountStatusFragment
Logger.info(LOG_TAG, "Force syncing.");
fxAccount.requestSync(FirefoxAccounts.FORCE);
// No sense refreshing, since the sync will complete in the future.
} else if ("debug_forget_reading_list_oauth_token".equals(key)) {
final Account account = fxAccount.getAndroidAccount();
final AccountManager accountManager = AccountManager.get(getActivity());
final String authToken = accountManager.peekAuthToken(account, ReadingListConstants.AUTH_TOKEN_TYPE);
if (authToken != null) {
Logger.info(LOG_TAG, "Forgetting reading list oauth token: " + authToken);
accountManager.invalidateAuthToken(account.type, authToken);
} else {
Logger.warn(LOG_TAG, "No reading list oauth token to forget!");
}
} else if ("debug_forget_certificate".equals(key)) {
State state = fxAccount.getState();
try {

View File

@ -63,13 +63,6 @@ public class AndroidFxAccount {
public static final String ACCOUNT_KEY_TOKEN_SERVER = "tokenServerURI"; // Sync-specific.
public static final String ACCOUNT_KEY_DESCRIPTOR = "descriptor";
// The set of authorities to sync automatically changes over time. The first
// new authority is the Reading List. This tracks if we've enabled syncing,
// and opted in (or out) of syncing automatically, for the new Reading List
// authority. This happens either on when the account is created or when
// upgrading.
public static final String ACCOUNT_KEY_READING_LIST_AUTHORITY_INITIALIZED = "readingListAuthorityInitialized";
public static final int CURRENT_BUNDLE_VERSION = 2;
public static final String BUNDLE_KEY_BUNDLE_VERSION = "version";
public static final String BUNDLE_KEY_STATE_LABEL = "stateLabel";
@ -93,10 +86,6 @@ public class AndroidFxAccount {
final HashMap<String, Boolean> m = new HashMap<String, Boolean>();
// By default, Firefox Sync is enabled.
m.put(BrowserContract.AUTHORITY, true);
if (AppConstants.MOZ_ANDROID_READING_LIST_SERVICE) {
// Sync the Reading List.
m.put(BrowserContract.READING_LIST_AUTHORITY, true);
}
DEFAULT_AUTHORITIES_TO_SYNC_AUTOMATICALLY_MAP = Collections.unmodifiableMap(m);
}
@ -430,10 +419,6 @@ public class AndroidFxAccount {
userdata.putString(ACCOUNT_KEY_IDP_SERVER, idpServerURI);
userdata.putString(ACCOUNT_KEY_TOKEN_SERVER, tokenServerURI);
userdata.putString(ACCOUNT_KEY_PROFILE, profile);
if (DEFAULT_AUTHORITIES_TO_SYNC_AUTOMATICALLY_MAP.containsKey(BrowserContract.READING_LIST_AUTHORITY)) {
// Have we initialized the Reading List authority?
userdata.putString(ACCOUNT_KEY_READING_LIST_AUTHORITY_INITIALIZED, "1");
}
if (bundle == null) {
bundle = new ExtendedJSONObject();

View File

@ -11,7 +11,6 @@ import java.util.concurrent.Executors;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.fxa.FxAccountUtils;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.fxa.FirefoxAccounts;
import org.mozilla.gecko.fxa.FxAccountConstants;
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
@ -20,9 +19,7 @@ import org.mozilla.gecko.fxa.login.State.StateLabel;
import org.mozilla.gecko.sync.Utils;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@ -48,7 +45,6 @@ public class FxAccountUpgradeReceiver extends BroadcastReceiver {
// Recovering accounts that are in the Doghouse should happen *after* we
// unpickle any accounts saved to disk.
runnables.add(new AdvanceFromDoghouseRunnable(context));
runnables.add(new MaybeInitializeReadingListAuthority(context));
return runnables;
}
@ -134,68 +130,4 @@ public class FxAccountUpgradeReceiver extends BroadcastReceiver {
}
}
}
/**
* A Runnable that initializes the Reading List authority (specifically, set
* the sync automatically flag) for existing Firefox Accounts that have not
* yet seen the authority. That is, if a new authority (Reading List) is added
* to the set of defaults, existing Firefox Accounts won't be syncing it
* automatically. This tries to set the sync automatically flag for such
* existing accounts.
*
* Public for testing only.
*/
public static class MaybeInitializeReadingListAuthority implements Runnable {
protected final Context context;
public MaybeInitializeReadingListAuthority(Context context) {
this.context = context;
}
@Override
public void run() {
final String authority = BrowserContract.READING_LIST_AUTHORITY;
Boolean enabledByDefault = AndroidFxAccount.DEFAULT_AUTHORITIES_TO_SYNC_AUTOMATICALLY_MAP.get(authority);
if (enabledByDefault == null || !enabledByDefault.booleanValue()) {
Logger.info(LOG_TAG, "Reading List authority is not enabled by default; not trying to initialize Reading List authority for any accounts.");
}
final AccountManager accountManager = AccountManager.get(context);
final Account[] accounts = FirefoxAccounts.getFirefoxAccounts(context);
Logger.info(LOG_TAG, "Trying to initialize Reading List authority for " + accounts.length + " existing Firefox Accounts (if necessary).");
for (Account account : accounts) {
try {
final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account);
// For great debugging.
if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
fxAccount.dump();
}
final boolean readingListAuthorityInitialized =
"1".equals(accountManager.getUserData(account, AndroidFxAccount.ACCOUNT_KEY_READING_LIST_AUTHORITY_INITIALIZED));
if (readingListAuthorityInitialized) {
Logger.debug(LOG_TAG, "Reading List authority has already been initialized.");
continue;
}
// The Reading List authority has not been seen. This happens when an
// authority is added after the Firefox Account has been added (and
// the package last upgraded). If Firefox Sync is not syncing
// automatically, Reading List should not start syncing
// automatically: the user has elected not to upload data to Mozilla
// servers; we shouldn't opt them in.
final boolean syncAutomatically = ContentResolver.getSyncAutomatically(account, BrowserContract.AUTHORITY);
Logger.debug(LOG_TAG, "Setting Reading List authority " +
(syncAutomatically ? " to " : " to not ") + "sync automatically.");
ContentResolver.setSyncAutomatically(account, BrowserContract.READING_LIST_AUTHORITY, syncAutomatically);
// Update the account record.
accountManager.setUserData(account, AndroidFxAccount.ACCOUNT_KEY_READING_LIST_AUTHORITY_INITIALIZED, "1");
} catch (Exception e) {
Logger.warn(LOG_TAG, "Got exception trying to set authoritities to sync automatically for account named like " +
Utils.obfuscateEmail(account.name) + "; ignoring.", e);
}
}
}
}
}

View File

@ -192,10 +192,10 @@
<!ENTITY pref_donottrack_title "Do not track">
<!ENTITY pref_donottrack_summary "&brandShortName; will tell sites that you do not want to be tracked">
<!ENTITY tab_queue_toast_message "Open later">
<!ENTITY tab_queue_toast_message2 "Tab queued in &brandShortName;">
<!ENTITY tab_queue_toast_action "Open now">
<!ENTITY tab_queue_prompt_title "Opening multiple links?">
<!ENTITY tab_queue_prompt_text "Open them without switching to Firefox each time.">
<!ENTITY tab_queue_prompt_text2 "Open them without switching to &brandShortName; each time.">
<!ENTITY tab_queue_prompt_tip_text "you can change this later in Settings">
<!ENTITY tab_queue_prompt_positive_action_button "Enable">
<!ENTITY tab_queue_prompt_negative_action_button "Not now">
@ -397,8 +397,8 @@ size. -->
<!ENTITY pref_scroll_title_bar2 "Full-screen browsing">
<!ENTITY pref_scroll_title_bar_summary "Hide the &brandShortName; title bar when scrolling down a page">
<!ENTITY pref_tab_queue_title "Open later">
<!ENTITY pref_tab_queue_summary "Prevent tabs from opening immediately, but open all queued tabs the next time &brandShortName; loads.">
<!ENTITY pref_tab_queue_title2 "Open multiple links">
<!ENTITY pref_tab_queue_summary2 "Queue links for later instead of switching to &brandShortName; each time">
<!-- Localization note (page_removed): This string appears in a toast message when
any page is removed frome about:home. This includes pages that are in history,

View File

@ -15,7 +15,7 @@
<view class="org.mozilla.gecko.tabs.TabsPanel$TabsPanelToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="@dimen/browser_toolbar_height"
android:background="@color/background_tabs">
<ViewStub android:id="@+id/nav_back_stub"

View File

@ -10,4 +10,5 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_tabs"
android:orientation="vertical"
android:visibility="invisible"/>

View File

@ -79,10 +79,6 @@
android:key="passwords"
android:persistent="false"
android:title="@string/fxaccount_status_passwords" />
<CheckBoxPreference
android:key="reading_list"
android:persistent="false"
android:title="@string/fxaccount_status_reading_list" />
<EditTextPreference
android:singleLine="true"
@ -127,7 +123,6 @@
<Preference android:key="debug_dump" />
<Preference android:key="debug_force_sync" />
<Preference android:key="debug_invalidate_certificate" />
<Preference android:key="debug_forget_reading_list_oauth_token" />
<Preference android:key="debug_forget_certificate" />
<Preference android:key="debug_require_password" />
<Preference android:key="debug_require_upgrade" />

View File

@ -239,14 +239,14 @@
<string name="pref_update_autodownload_disabled">&pref_update_autodownload_never;</string>
<string name="pref_update_autodownload_enabled">&pref_update_autodownload_always;</string>
<string name="pref_tab_queue_title">&pref_tab_queue_title;</string>
<string name="pref_tab_queue_summary">&pref_tab_queue_summary;</string>
<string name="pref_tab_queue_title">&pref_tab_queue_title2;</string>
<string name="pref_tab_queue_summary">&pref_tab_queue_summary2;</string>
<string name="tab_queue_prompt_title">&tab_queue_prompt_title;</string>
<string name="tab_queue_prompt_text">&tab_queue_prompt_text;</string>
<string name="tab_queue_prompt_text">&tab_queue_prompt_text2;</string>
<string name="tab_queue_prompt_tip_text">&tab_queue_prompt_tip_text;</string>
<string name="tab_queue_prompt_positive_action_button">&tab_queue_prompt_positive_action_button;</string>
<string name="tab_queue_prompt_negative_action_button">&tab_queue_prompt_negative_action_button;</string>
<string name="tab_queue_toast_message">&tab_queue_toast_message;</string>
<string name="tab_queue_toast_message">&tab_queue_toast_message2;</string>
<string name="tab_queue_toast_action">&tab_queue_toast_action;</string>
<string name="tab_queue_notification_text_singular">&tab_queue_notification_text_singular;</string>
<string name="tab_queue_notification_text_plural">&tab_queue_notification_text_plural;</string>

View File

@ -138,6 +138,7 @@ public class TabQueueService extends Service {
startActivity(forwardIntent);
removeView();
stopSelfResult(startId);
}
});

View File

@ -102,10 +102,6 @@ public class TabsPanel extends LinearLayout
mActivity = (GeckoApp) context;
mTheme = ((GeckoApplication) context.getApplicationContext()).getLightweightTheme();
setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
setOrientation(LinearLayout.VERTICAL);
mCurrentPanel = Panel.NORMAL_TABS;
mPopupMenu = new GeckoPopupMenu(context);
@ -332,11 +328,6 @@ public class TabsPanel extends LinearLayout
public TabsPanelToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
mTheme = ((GeckoApplication) context.getApplicationContext()).getLightweightTheme();
setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
(int) context.getResources().getDimension(R.dimen.browser_toolbar_height)));
setOrientation(LinearLayout.HORIZONTAL);
}
@Override

View File

@ -207,7 +207,8 @@ public class testSettingsMenuItems extends PixelTest {
// Tab Queue
if (AppConstants.NIGHTLY_BUILD && AppConstants.MOZ_ANDROID_TAB_QUEUE) {
String[] tabQueue = { mStringHelper.TAB_QUEUE_LABEL, "Prevent tabs from opening immediately, but open all queued tabs the next time " + mStringHelper.BRAND_NAME + " loads." };
final String expected = "Queue links for later instead of switching to " + mStringHelper.BRAND_NAME + " each time";
String[] tabQueue = { mStringHelper.TAB_QUEUE_LABEL, expected };
settingsMap.get(PATH_CUSTOMIZE).add(tabQueue);
}

View File

@ -127,6 +127,11 @@ abstract class BrowserToolbarTabletBase extends BrowserToolbar {
}
}
@Override
public View getDoorHangerAnchor() {
return backButton;
}
protected boolean canDoBack(final Tab tab) {
return (tab.canDoBack() && !isEditing());
}

View File

@ -100,13 +100,15 @@ public abstract class AnchoredPopup extends PopupWindow {
return;
}
// If the anchor is null or out of the window bounds, just show the popup at the top of the
// root view.
if (mAnchor == null || anchorLocation[1] < 0) {
showAtLocation(decorView, Gravity.NO_GRAVITY, 0, offsetY);
return;
}
if (HardwareUtils.isTablet()) {
showAsDropDown(mAnchor, 0, 0);
} else {
// If the anchor is null or out of the window bounds, just show the popup at the top of the
// root view.
final boolean validAnchor = (mAnchor != null) && (anchorLocation[1] > 0);
final View anchor = validAnchor ? mAnchor : decorView;
showAtLocation(mAnchor, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, offsetY);
showAtLocation(anchor, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, offsetY);
}
}
}

View File

@ -55,9 +55,6 @@ MOZ_PAY=1
# Enable UI for healthreporter
MOZ_SERVICES_HEALTHREPORT=1
# Enable reading list service integration.
MOZ_ANDROID_READING_LIST_SERVICE=1
# Enable runtime locale switching.
MOZ_LOCALE_SWITCHER=1

View File

@ -26,19 +26,4 @@
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/fxaccount_syncadapter" />
</service>
<!-- Reading List. -->
#ifdef MOZ_ANDROID_READING_LIST_SERVICE
<service
android:exported="false"
android:name="org.mozilla.gecko.reading.ReadingListSyncService" >
<intent-filter >
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/readinglist_syncadapter" />
</service>
#endif
</service>

View File

@ -182,7 +182,7 @@ public:
NS_IMETHOD GetAllowAltSvc(bool *aAllowAltSvc) override;
NS_IMETHOD SetAllowAltSvc(bool aAllowAltSvc) override;
NS_IMETHOD GetApiRedirectToURI(nsIURI * *aApiRedirectToURI) override;
nsresult AddSecurityMessage(const nsAString &aMessageTag, const nsAString &aMessageCategory);
virtual nsresult AddSecurityMessage(const nsAString &aMessageTag, const nsAString &aMessageCategory);
NS_IMETHOD TakeAllSecurityMessages(nsCOMArray<nsISecurityConsoleMessage> &aMessages) override;
NS_IMETHOD GetResponseTimeoutEnabled(bool *aEnable) override;
NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable) override;

View File

@ -991,6 +991,14 @@ HttpChannelChild::DeleteSelf()
Send__delete__(this);
}
bool
HttpChannelChild::RecvReportSecurityMessage(const nsString& messageTag,
const nsString& messageCategory)
{
AddSecurityMessage(messageTag, messageCategory);
return true;
}
class Redirect1Event : public ChannelEvent
{
public:

View File

@ -140,6 +140,9 @@ protected:
bool RecvDivertMessages() override;
bool RecvDeleteSelf() override;
bool RecvReportSecurityMessage(const nsString& messageTag,
const nsString& messageCategory) override;
bool GetAssociatedContentSecurity(nsIAssociatedContentSecurity** res = nullptr);
virtual void DoNotifyListenerCleanup() override;

View File

@ -330,6 +330,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
return SendFailedAsyncOpen(rv);
mChannel = static_cast<nsHttpChannel *>(channel.get());
mChannel->SetWarningReporter(this);
mChannel->SetTimingEnabled(true);
if (mPBOverride != kPBOverride_Unset) {
mChannel->SetPrivate(mPBOverride == kPBOverride_Private ? true : false);
@ -1265,4 +1266,19 @@ HttpChannelParent::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelSecurityWarningReporter
//-----------------------------------------------------------------------------
nsresult
HttpChannelParent::ReportSecurityMessage(const nsAString& aMessageTag,
const nsAString& aMessageCategory)
{
if (NS_WARN_IF(!SendReportSecurityMessage(nsString(aMessageTag),
nsString(aMessageCategory)))) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
}} // mozilla::net

View File

@ -44,6 +44,7 @@ class HttpChannelParent final : public PHttpChannelParent
, public nsIAuthPromptProvider
, public nsINetworkInterceptController
, public DisconnectableParent
, public HttpChannelSecurityWarningReporter
{
virtual ~HttpChannelParent();
@ -154,6 +155,9 @@ protected:
void OfflineDisconnect() override;
uint32_t GetAppId() override;
nsresult ReportSecurityMessage(const nsAString& aMessageTag,
const nsAString& aMessageCategory) override;
private:
nsRefPtr<nsHttpChannel> mChannel;
nsCOMPtr<nsICacheEntry> mCacheEntry;

View File

@ -139,6 +139,10 @@ child:
// OnDataAvailable and OnStopRequest messages in the queue back to the parent.
DivertMessages();
// Report a security message to the console associated with this
// channel.
ReportSecurityMessage(nsString messageTag, nsString messageCategory);
// Tell child to delete channel (all IPDL deletes must be done from child to
// avoid races: see bug 591708).
DeleteSelf();

View File

@ -245,6 +245,7 @@ nsHttpChannel::nsHttpChannel()
, mHasAutoRedirectVetoNotifier(0)
, mPushedStream(nullptr)
, mLocalBlocklist(false)
, mWarningReporter(nullptr)
, mDidReval(false)
{
LOG(("Creating nsHttpChannel [this=%p]\n", this));
@ -282,6 +283,19 @@ nsHttpChannel::Init(nsIURI *uri,
return rv;
}
nsresult
nsHttpChannel::AddSecurityMessage(const nsAString& aMessageTag,
const nsAString& aMessageCategory)
{
if (mWarningReporter) {
return mWarningReporter->ReportSecurityMessage(aMessageTag,
aMessageCategory);
}
return HttpBaseChannel::AddSecurityMessage(aMessageTag,
aMessageCategory);
}
//-----------------------------------------------------------------------------
// nsHttpChannel <private>
//-----------------------------------------------------------------------------

View File

@ -33,6 +33,14 @@ class nsISSLStatus;
namespace mozilla { namespace net {
class Http2PushedStream;
class HttpChannelSecurityWarningReporter
{
public:
virtual nsresult ReportSecurityMessage(const nsAString& aMessageTag,
const nsAString& aMessageCategory) = 0;
};
//-----------------------------------------------------------------------------
// nsHttpChannel
//-----------------------------------------------------------------------------
@ -141,6 +149,12 @@ public:
NS_IMETHOD GetResponseStart(mozilla::TimeStamp *aResponseStart) override;
NS_IMETHOD GetResponseEnd(mozilla::TimeStamp *aResponseEnd) override;
nsresult AddSecurityMessage(const nsAString& aMessageTag,
const nsAString& aMessageCategory) override;
void SetWarningReporter(HttpChannelSecurityWarningReporter* aReporter)
{ mWarningReporter = aReporter; }
public: /* internal necko use only */
void InternalSetUploadStream(nsIInputStream *uploadStream)
@ -477,6 +491,9 @@ private:
nsCString mUsername;
// If non-null, warnings should be reported to this object.
HttpChannelSecurityWarningReporter* mWarningReporter;
protected:
virtual void DoNotifyListenerCleanup() override;

View File

@ -127,7 +127,7 @@ add_task(function() {
test.validate(false);
// cleanup
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
// manually remove the excluded root
PlacesUtils.bookmarks.removeItem(test._excludeRootId);
// restore json file

View File

@ -330,20 +330,6 @@ function visits_in_database(aURI)
}
}
/**
* Removes all bookmarks and checks for correct cleanup
*/
function remove_all_bookmarks() {
let PU = PlacesUtils;
// Clear all bookmarks
PU.bookmarks.removeFolderChildren(PU.bookmarks.bookmarksMenuFolder);
PU.bookmarks.removeFolderChildren(PU.bookmarks.toolbarFolder);
PU.bookmarks.removeFolderChildren(PU.bookmarks.unfiledBookmarksFolder);
// Check for correct cleanup
check_no_bookmarks();
}
/**
* Checks that we don't have any bookmark
*/

View File

@ -140,8 +140,10 @@ function ensure_results(aSearchString, aExpectedValue) {
}
// Cleanup.
remove_all_bookmarks();
PlacesTestUtils.clearHistory().then(resolve);
Promise.all([
PlacesUtils.bookmarks.eraseEverything(),
PlacesTestUtils.clearHistory()
]).then(resolve);
};
});

View File

@ -353,7 +353,7 @@ function run_test()
add_task(function* test_async()
{
for (let [, test] in Iterator(tests)) {
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
test.__proto__ = new Test();
yield test.setup();
@ -362,6 +362,6 @@ add_task(function* test_async()
yield test.run();
}
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
print("All tests done, exiting");
});

View File

@ -187,7 +187,7 @@ function run_test()
*/
add_task(function test_add_visits_to_database()
{
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
// We don't really bother on this, but we need a time to add visits.
let timeInMicroseconds = Date.now() * 1000;
@ -298,7 +298,7 @@ add_task(function test_redirects()
cartProd([includeHidden_options, maxResults_options, sorting_options],
check_results_callback);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});

View File

@ -1278,7 +1278,7 @@ add_task(function test_sorting()
// sorting reversed, usually SORT_BY have ASC and DESC
test.check_reverse();
// Execute cleanup tasks
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
}
});

View File

@ -554,7 +554,7 @@ function addBookmark(aURI) {
* Asynchronous task that removes all pages from history and bookmarks.
*/
function* task_cleanDatabase(aCallback) {
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
}

View File

@ -32,7 +32,7 @@ function* cleanup() {
for (let type of ["history", "bookmark", "history.onlyTyped", "openpage"]) {
Services.prefs.clearUserPref("browser.urlbar.suggest." + type);
}
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
}
do_register_cleanup(cleanup);

View File

@ -33,7 +33,7 @@ add_task(function changeuri_unvisited_bookmark()
do_print("Unvisited URI no longer bookmarked => frecency should = 0");
do_check_eq(frecencyForUrl(TEST_URI), 0);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});
@ -63,7 +63,7 @@ add_task(function changeuri_visited_bookmark()
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});
@ -94,7 +94,7 @@ add_task(function changeuri_bookmark_still_bookmarked()
do_print("URI still bookmarked => frecency should != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});
@ -126,7 +126,7 @@ add_task(function changeuri_nonexistent_bookmark()
PlacesUtils.bookmarks.removeItem(id);
tryChange(id);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});

View File

@ -89,9 +89,10 @@ function check_results() {
Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH);
do_check_eq(controller.matchCount, 0);
remove_all_bookmarks();
cleanup();
do_test_finished();
PlacesUtils.bookmarks.eraseEverything().then(() => {
cleanup();
do_test_finished();
});
};
controller.startSearch(SEARCH_STRING);

View File

@ -88,9 +88,8 @@ function run_next_test() {
return;
}
let test = tests.shift();
PlacesTestUtils.clearHistory().then(function() {
remove_all_bookmarks();
do_execute_soon(test);
});
Promise.all([
PlacesTestUtils.clearHistory(),
PlacesUtils.bookmarks.eraseEverything()
]).then(tests.shift());
}

View File

@ -104,7 +104,7 @@ add_task(function* setup() {
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
yield PlacesTestUtils.promiseAsyncUpdates();
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function* test_import_new()
@ -118,7 +118,7 @@ add_task(function* test_import_new()
yield testImportedBookmarks();
yield PlacesTestUtils.promiseAsyncUpdates();
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function* test_emptytitle_export()
@ -146,7 +146,7 @@ add_task(function* test_emptytitle_export()
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
yield PlacesTestUtils.promiseAsyncUpdates();
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
yield PlacesTestUtils.promiseAsyncUpdates();
@ -158,7 +158,7 @@ add_task(function* test_emptytitle_export()
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
yield PlacesTestUtils.promiseAsyncUpdates();
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function* test_import_chromefavicon()
@ -214,7 +214,7 @@ add_task(function* test_import_chromefavicon()
deferred.resolve);
yield deferred.promise;
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
yield PlacesTestUtils.promiseAsyncUpdates();
@ -226,7 +226,7 @@ add_task(function* test_import_chromefavicon()
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
yield PlacesTestUtils.promiseAsyncUpdates();
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function* test_import_ontop()
@ -248,7 +248,7 @@ add_task(function* test_import_ontop()
yield PlacesTestUtils.promiseAsyncUpdates();
yield testImportedBookmarks();
yield PlacesTestUtils.promiseAsyncUpdates();
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
function* testImportedBookmarks()

View File

@ -41,7 +41,7 @@ add_task(function* test_corrupt_database() {
yield BookmarkHTMLUtils.exportToFile(bookmarksFile);
// Import again and check for correctness.
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield BookmarkHTMLUtils.importFromFile(bookmarksFile, true);
yield PlacesTestUtils.promiseAsyncUpdates();
yield database_check();

View File

@ -90,14 +90,14 @@ add_task(function test_export_bookmarks() {
});
add_task(function test_import_exported_bookmarks() {
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield BookmarkJSONUtils.importFromFile(bookmarksExportedFile, true);
yield PlacesTestUtils.promiseAsyncUpdates();
yield testImportedBookmarks();
});
add_task(function test_import_ontop() {
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield BookmarkJSONUtils.importFromFile(bookmarksExportedFile, true);
yield PlacesTestUtils.promiseAsyncUpdates();
yield BookmarkJSONUtils.exportToFile(bookmarksExportedFile);
@ -108,7 +108,7 @@ add_task(function test_import_ontop() {
});
add_task(function test_clean() {
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
function testImportedBookmarks() {

View File

@ -53,7 +53,7 @@ var tests = [
addBookmarks();
yield BookmarkJSONUtils.exportToFile(this.file);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
try {
yield BookmarkJSONUtils.importFromFile(this.file, true);
}
@ -114,7 +114,7 @@ var tests = [
this.file = yield promiseFile("bookmarks-test_restoreNotification.html");
addBookmarks();
yield BookmarkHTMLUtils.exportToFile(this.file);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
try {
BookmarkHTMLUtils.importFromFile(this.file, false)
.then(null, do_report_unexpected_exception);
@ -174,7 +174,7 @@ var tests = [
this.file = yield promiseFile("bookmarks-test_restoreNotification.init.html");
addBookmarks();
yield BookmarkHTMLUtils.exportToFile(this.file);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
try {
BookmarkHTMLUtils.importFromFile(this.file, true)
.then(null, do_report_unexpected_exception);
@ -269,8 +269,7 @@ var successAndFailedObserver = {
else
do_check_eq(test.folderId, null);
remove_all_bookmarks();
do_execute_soon(doNextTest);
PlacesUtils.bookmarks.eraseEverything().then(doNextTest);
}
};

View File

@ -286,7 +286,7 @@ add_task(function test_frecency()
prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
prefs.setBoolPref("browser.urlbar.suggest.openpage", false);
for (let [, test] in Iterator(tests)) {
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
deferEnsureResults = Promise.defer();

View File

@ -56,7 +56,7 @@ add_task(function test_addBookmarksAndCheckGuids() {
root.containerOpen = false;
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function test_updateBookmarksAndCheckGuids() {
@ -85,7 +85,7 @@ add_task(function test_updateBookmarksAndCheckGuids() {
root.containerOpen = false;
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function test_addVisitAndCheckGuid() {
@ -133,7 +133,7 @@ add_task(function test_addItemsWithInvalidGUIDsFails() {
}
catch(ex) { }
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function test_addItemsWithGUIDs() {
@ -154,7 +154,7 @@ add_task(function test_addItemsWithGUIDs() {
do_check_eq(root.getChild(1).bookmarkGuid, SEPARATOR_GUID);
root.containerOpen = false;
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function test_emptyGUIDIgnored() {
@ -162,7 +162,7 @@ add_task(function test_emptyGUIDIgnored() {
bmsvc.DEFAULT_INDEX, "");
do_check_valid_places_guid(PlacesUtils.getFolderContents(folder)
.root.bookmarkGuid);
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});
add_task(function test_usingSameGUIDFails() {
@ -176,5 +176,5 @@ add_task(function test_usingSameGUIDFails() {
}
catch(ex) { }
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
});

View File

@ -10,7 +10,7 @@ const PLACE_URI = uri("place:queryType=0&sort=8&maxResults=10");
function* cleanup() {
yield PlacesTestUtils.clearHistory();
remove_all_bookmarks();
yield PlacesUtils.bookmarks.eraseEverything();
// This is needed to remove place: entries.
DBConn().executeSimpleSQL("DELETE FROM moz_places");
}

View File

@ -12,148 +12,140 @@
* bookmark is deleted.
*/
add_test(function removed_bookmark()
{
add_task(function* removed_bookmark() {
do_print("After removing bookmark, frecency of bookmark's URI should be " +
"zero if URI is unvisited and no longer bookmarked.");
const TEST_URI = NetUtil.newURI("http://example.com/1");
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
TEST_URI,
PlacesUtils.bookmarks.DEFAULT_INDEX,
"bookmark title");
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
PlacesUtils.bookmarks.removeItem(id);
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("Unvisited URI no longer bookmarked => frecency should = 0");
do_check_eq(frecencyForUrl(TEST_URI), 0);
remove_all_bookmarks();
PlacesTestUtils.clearHistory().then(run_next_test);
});
let bm = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "bookmark title",
url: TEST_URI
});
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesUtils.bookmarks.remove(bm);
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("Unvisited URI no longer bookmarked => frecency should = 0");
do_check_eq(frecencyForUrl(TEST_URI), 0);
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});
add_test(function removed_but_visited_bookmark()
{
add_task(function* removed_but_visited_bookmark() {
do_print("After removing bookmark, frecency of bookmark's URI should " +
"not be zero if URI is visited.");
const TEST_URI = NetUtil.newURI("http://example.com/1");
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
TEST_URI,
PlacesUtils.bookmarks.DEFAULT_INDEX,
"bookmark title");
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
PlacesTestUtils.addVisits(TEST_URI).then(function () {
PlacesUtils.bookmarks.removeItem(id);
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
remove_all_bookmarks();
PlacesTestUtils.clearHistory().then(run_next_test);
});
});
let bm = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "bookmark title",
url: TEST_URI
});
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesTestUtils.addVisits(TEST_URI);
yield PlacesUtils.bookmarks.remove(bm);
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});
add_test(function remove_bookmark_still_bookmarked()
{
add_task(function* remove_bookmark_still_bookmarked() {
do_print("After removing bookmark, frecency of bookmark's URI should " +
"not be zero if URI is still bookmarked.");
const TEST_URI = NetUtil.newURI("http://example.com/1");
let id1 = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
TEST_URI,
PlacesUtils.bookmarks.DEFAULT_INDEX,
"bookmark 1 title");
let id2 = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
TEST_URI,
PlacesUtils.bookmarks.DEFAULT_INDEX,
"bookmark 2 title");
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
PlacesUtils.bookmarks.removeItem(id1);
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("URI still bookmarked => frecency should != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
remove_all_bookmarks();
PlacesTestUtils.clearHistory().then(run_next_test);
});
let bm1 = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "bookmark 1 title",
url: TEST_URI
});
let bm2 = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "bookmark 2 title",
url: TEST_URI
});
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesUtils.bookmarks.remove(bm1);
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("URI still bookmarked => frecency should != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});
add_test(function cleared_parent_of_visited_bookmark()
{
add_task(function* cleared_parent_of_visited_bookmark() {
do_print("After removing all children from bookmark's parent, frecency " +
"of bookmark's URI should not be zero if URI is visited.");
const TEST_URI = NetUtil.newURI("http://example.com/1");
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
TEST_URI,
PlacesUtils.bookmarks.DEFAULT_INDEX,
"bookmark title");
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
PlacesTestUtils.addVisits(TEST_URI).then(function () {
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
remove_all_bookmarks();
PlacesTestUtils.clearHistory().then(run_next_test);
});
});
let bm = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "bookmark title",
url: TEST_URI
});
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesTestUtils.addVisits(TEST_URI);
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});
add_test(function cleared_parent_of_bookmark_still_bookmarked()
{
add_task(function* cleared_parent_of_bookmark_still_bookmarked() {
do_print("After removing all children from bookmark's parent, frecency " +
"of bookmark's URI should not be zero if URI is still " +
"bookmarked.");
const TEST_URI = NetUtil.newURI("http://example.com/1");
let id1 = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId,
TEST_URI,
PlacesUtils.bookmarks.DEFAULT_INDEX,
"bookmark 1 title");
let id2 = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
TEST_URI,
PlacesUtils.bookmarks.DEFAULT_INDEX,
"bookmark 2 title");
PlacesTestUtils.promiseAsyncUpdates().then(() => {
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
PlacesTestUtils.promiseAsyncUpdates().then(() => {
// URI still bookmarked => frecency should != 0.
do_check_neq(frecencyForUrl(TEST_URI), 0);
remove_all_bookmarks();
PlacesTestUtils.clearHistory().then(run_next_test);
});
let bm1 = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
title: "bookmark 1 title",
url: TEST_URI
});
let folder = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER,
title: "bookmark 2 folder"
});
let bm2 = yield PlacesUtils.bookmarks.insert({
title: "bookmark 2 title",
parentGuid: folder.guid,
url: TEST_URI
});
yield PlacesTestUtils.promiseAsyncUpdates();
do_print("Bookmarked => frecency of URI should be != 0");
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesUtils.bookmarks.remove(folder);
yield PlacesTestUtils.promiseAsyncUpdates();
// URI still bookmarked => frecency should != 0.
do_check_neq(frecencyForUrl(TEST_URI), 0);
yield PlacesUtils.bookmarks.eraseEverything();
yield PlacesTestUtils.clearHistory();
});
///////////////////////////////////////////////////////////////////////////////
function run_test()
{
run_next_test();
}

View File

@ -169,11 +169,12 @@ function check_uri_nodes(aQuery, aOptions, aExpectedURINodes) {
root.containerOpen = false;
}
function run_test() {
tests.forEach(function(aTest) {
remove_all_bookmarks();
aTest();
});
add_task(function* () {
for (let test of tests) {
yield PlacesUtils.bookmarks.eraseEverything();
test();
}
// Cleanup.
remove_all_bookmarks();
}
yield PlacesUtils.bookmarks.eraseEverything();
});

View File

@ -316,10 +316,25 @@ DevToolsLoader.prototype = {
*/
lazyRequireGetter: function (obj, property, module, destructure) {
Object.defineProperty(obj, property, {
get: () => destructure
? this.require(module)[property]
: this.require(module || property),
configurable: true
get: () => {
// Redefine this accessor property as a data property.
// Delete it first, to rule out "too much recursion" in case obj is
// a proxy whose defineProperty handler might unwittingly trigger this
// getter again.
delete obj[property];
let value = destructure
? this.require(module)[property]
: this.require(module || property);
Object.defineProperty(obj, property, {
value,
writable: true,
configurable: true,
enumerable: true
});
return value;
},
configurable: true,
enumerable: true
});
},

View File

@ -413,6 +413,10 @@ var NodeActor = exports.NodeActor = protocol.ActorClass({
}
}
events.sort((a, b) => {
return a.type.localeCompare(b.type);
});
return events;
},
@ -1406,6 +1410,8 @@ var WalkerActor = protocol.ActorClass({
* Named options, including:
* `sameDocument`: If true, parents will be restricted to the same
* document as the node.
* `sameTypeRootTreeItem`: If true, this will not traverse across
* different types of docshells.
*/
parents: method(function(node, options={}) {
if (isNodeDead(node)) {
@ -1416,16 +1422,23 @@ var WalkerActor = protocol.ActorClass({
let parents = [];
let cur;
while((cur = walker.parentNode())) {
if (options.sameDocument && cur.ownerDocument != node.rawNode.ownerDocument) {
if (options.sameDocument && nodeDocument(cur) != nodeDocument(node.rawNode)) {
break;
}
if (options.sameTypeRootTreeItem &&
nodeDocshell(cur).sameTypeRootTreeItem != nodeDocshell(node.rawNode).sameTypeRootTreeItem) {
break;
}
parents.push(this._ref(cur));
}
return parents;
}, {
request: {
node: Arg(0, "domnode"),
sameDocument: Option(1)
sameDocument: Option(1),
sameTypeRootTreeItem: Option(1)
},
response: {
nodes: RetVal("array:domnode")
@ -3222,7 +3235,7 @@ var WalkerFront = exports.WalkerFront = protocol.FrontClass(WalkerActor, {
let nodeType = types.getType("domnode");
let returnNode = nodeType.read(nodeType.write(nodeActor, walkerActor), this);
let top = returnNode;
let extras = walkerActor.parents(nodeActor);
let extras = walkerActor.parents(nodeActor, {sameTypeRootTreeItem: true});
for (let extraActor of extras) {
top = nodeType.read(nodeType.write(extraActor, walkerActor), this);
}
@ -3515,6 +3528,16 @@ function nodeDocument(node) {
return node.ownerDocument || (node.nodeType == Ci.nsIDOMNode.DOCUMENT_NODE ? node : null);
}
function nodeDocshell(node) {
let doc = node ? nodeDocument(node) : null;
let win = doc ? doc.defaultView : null;
if (win) {
return win.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDocShell);
}
}
function isNodeDead(node) {
return !node || !node.rawNode || Cu.isDeadWrapper(node.rawNode);
}

View File

@ -1020,7 +1020,8 @@ var StyleRuleActor = protocol.ActorClass({
// Elements don't have a parent stylesheet, and therefore
// don't have an associated URI. Provide a URI for
// those.
form.href = this.rawNode.ownerDocument.location.href;
let doc = this.rawNode.ownerDocument;
form.href = doc.location ? doc.location.href : "";
form.cssText = this.rawStyle.cssText || "";
break;
case Ci.nsIDOMCSSRule.CHARSET_RULE:
@ -1231,7 +1232,7 @@ var StyleRuleFront = protocol.FrontClass(StyleRuleActor, {
return this._form.href;
}
let sheet = this.parentStyleSheet;
return sheet.href;
return sheet ? sheet.href : "";
},
get nodeHref() {

View File

@ -1,10 +1,16 @@
const Services = require("Services");
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Ci, Cu } = require("chrome");
const Services = require("Services");
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
const { dbg_assert, fetch } = DevToolsUtils;
const EventEmitter = require("devtools/toolkit/event-emitter");
const { dbg_assert, fetch } = require("devtools/toolkit/DevToolsUtils");
const { OriginalLocation, GeneratedLocation, getOffsetColumn } = require("devtools/server/actors/common");
const { resolve } = require("promise");
const { resolve } = Promise;
loader.lazyRequireGetter(this, "SourceActor", "devtools/server/actors/script", true);
loader.lazyRequireGetter(this, "isEvalSource", "devtools/server/actors/script", true);

View File

@ -8,6 +8,7 @@
let { Ci, Cu } = require("chrome");
let Services = require("Services");
let promise = require("promise");
let { ActorPool, createExtraActors, appendExtraActors } = require("devtools/server/actors/common");
let { DebuggerServer } = require("devtools/server/main");
let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
@ -15,7 +16,6 @@ let { dbg_assert } = DevToolsUtils;
let { TabSources, isHiddenSource } = require("./utils/TabSources");
let makeDebugger = require("./utils/make-debugger");
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
loader.lazyRequireGetter(this, "RootActor", "devtools/server/actors/root", true);