merge fx-team to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-12-15 12:04:13 +01:00
commit c976c8e5eb
76 changed files with 650 additions and 285 deletions

View File

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE = 1048576; // 1 MB in bytes
const SOURCE_URL_DEFAULT_MAX_LENGTH = 64; // chars
const STACK_FRAMES_SOURCE_URL_MAX_LENGTH = 15; // chars
const STACK_FRAMES_SOURCE_URL_TRIM_SECTION = "center";
@ -47,6 +46,13 @@ var constants = require('./content/constants');
* Object defining the debugger view components.
*/
var DebuggerView = {
/**
* This is attached so tests can change it without needing to load an
* actual large file in automation
*/
LARGE_FILE_SIZE: 1048576, // 1 MB in bytes
/**
* Initializes the debugger view.
*
@ -408,12 +414,6 @@ var DebuggerView = {
* The source text content.
*/
_setEditorMode: function(aUrl, aContentType = "", aTextContent = "") {
// Avoid setting the editor mode for very large files.
// Is this still necessary? See bug 929225.
if (aTextContent.length >= SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
return void this.editor.setMode(Editor.modes.text);
}
// Use JS mode for files with .js and .jsm extensions.
if (SourceUtils.isJavaScript(aUrl, aContentType)) {
return void this.editor.setMode(Editor.modes.js);

View File

@ -446,6 +446,7 @@ skip-if = true # non-named eval sources turned off for now, bug 1124106
skip-if = e10s && debug
[browser_dbg_sources-labels.js]
skip-if = e10s && debug
[browser_dbg_sources-large.js]
[browser_dbg_sources-sorting.js]
skip-if = e10s && debug
[browser_dbg_sources-bookmarklet.js]

View File

@ -0,0 +1,75 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that large files are treated differently in the debugger:
* 1) No parsing to determine current symbol is attempted when
* starting a search
*/
const TAB_URL = EXAMPLE_URL + "doc_function-search.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
const gTab = aTab;
const gDebuggee = aDebuggee;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const Filtering = gDebugger.DebuggerView.Filtering;
// Setting max size so that code_function-search-01.js will be
// considered a large file on first load
gDebugger.DebuggerView.LARGE_FILE_SIZE = 1;
function testLargeFile() {
ok(gEditor.getText().length > gDebugger.DebuggerView.LARGE_FILE_SIZE,
"First source is considered a large file.");
is(gEditor.getMode().name, "javascript",
"Editor is syntax highlighting.");
ok(gEditor.getText().includes("First source!"),
"Editor text contents appears to be correct.");
// Press ctrl+f with the cursor in a token
gEditor.focus();
gEditor.setCursor({ line: 3, ch: 10});
synthesizeKeyFromKeyTag(gDebugger.document.getElementById("tokenSearchKey"));
is(Filtering._searchbox.value, "#",
"Search box is NOT prefilled with current token");
}
function testSmallFile() {
ok(gEditor.getText().length < gDebugger.DebuggerView.LARGE_FILE_SIZE,
"Second source is considered a small file.");
is(gEditor.getMode().name, "javascript",
"Editor is syntax highlighting.");
ok(gEditor.getText().includes("First source!"),
"Editor text contents appears to be correct.");
// Press ctrl+f with the cursor in a token
gEditor.focus();
gEditor.setCursor({ line: 3, ch: 10});
synthesizeKeyFromKeyTag(gDebugger.document.getElementById("tokenSearchKey"));
is(Filtering._searchbox.value, "#test",
"Search box is prefilled with current token");
}
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-01.js");
yield testLargeFile();
info("Making it appear as a small file and then reselecting 01.js");
gDebugger.DebuggerView.LARGE_FILE_SIZE = 1000;
gSources.selectedIndex = 1;
yield waitForSourceShown(gPanel, "-02.js");
gSources.selectedIndex = 0;
yield waitForSourceShown(gPanel, "-01.js");
yield testSmallFile();
closeDebuggerAndFinish(gPanel);
});
});
}

View File

@ -443,9 +443,11 @@ FilterView.prototype = {
this._searchbox.value = aOperator + this.DebuggerView.editor.getSelection();
return;
}
if (SEARCH_AUTOFILL.indexOf(aOperator) != -1) {
let content = this.DebuggerView.editor.getText();
if (content.length < this.DebuggerView.LARGE_FILE_SIZE &&
SEARCH_AUTOFILL.indexOf(aOperator) != -1) {
let cursor = this.DebuggerView.editor.getCursor();
let content = this.DebuggerView.editor.getText();
let location = this.DebuggerView.Sources.selectedItem.attachment.source.url;
let source = this.Parser.get(content, location);
let identifier = source.getIdentifierAt({ line: cursor.line+1, column: cursor.ch });

View File

@ -24,7 +24,7 @@
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.status2): This is the label displayed
- in the network table toolbar, above the "status" column. -->
<!ENTITY netmonitorUI.toolbar.status2 "✓">
<!ENTITY netmonitorUI.toolbar.status3 "Status">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.method): This is the label displayed
- in the network table toolbar, above the "method" column. -->

View File

@ -39,8 +39,7 @@
#details-pane-toggle,
#details-pane[pane-collapsed],
.requests-menu-waterfall,
.requests-menu-footer-label,
.requests-menu-status-code {
.requests-menu-footer-label {
display: none;
}
}

View File

@ -107,7 +107,7 @@
<button id="requests-menu-status-button"
class="requests-menu-header-button requests-menu-status"
data-key="status"
label="&netmonitorUI.toolbar.status2;"
label="&netmonitorUI.toolbar.status3;"
flex="1">
</button>
</hbox>

View File

@ -9,7 +9,7 @@ function test() {
initNetMonitor(SIMPLE_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
let { document, L10N, NetMonitorView } = aMonitor.panelWin;
let { document, L10N, NetMonitorView, NetMonitorController } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
// Disable transferred size column support for this test.
@ -31,6 +31,11 @@ function test() {
"No 2d context should be created when the frontend is opened.");
waitForNetworkEvents(aMonitor, 1).then(() => {
// Make sure the DOMContentLoaded and load markers don't interfere with
// this test by removing them and redrawing the waterfall (bug 1224088).
NetMonitorController.NetworkEventsHandler.clearMarkers();
RequestsMenu._flushWaterfallViews(true);
ok(!document.querySelector("#requests-menu-waterfall-label"),
"The timeline label should be hidden after the first request.");
ok(document.querySelectorAll(".requests-menu-timings-division").length >= 3,

View File

@ -235,7 +235,8 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
cell.className = "plain call-tree-cell";
cell.setAttribute("type", type);
cell.setAttribute("crop", "end");
cell.setAttribute("value", value);
// Add a tabulation to the cell text in case it's is selected and copied.
cell.textContent = value + "\t";
return cell;
},
@ -261,7 +262,7 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
nameNode.className = "plain call-tree-name";
nameNode.setAttribute("flex", "1");
nameNode.setAttribute("crop", "end");
nameNode.setAttribute("value", frameName);
nameNode.textContent = frameName;
cell.appendChild(nameNode);
}
@ -276,6 +277,17 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
arrowNode.setAttribute("invisible", "");
}
// Add a line break to the last description of the row in case it's selected
// and copied.
let lastDescription = cell.querySelector('description:last-of-type');
lastDescription.textContent = lastDescription.textContent + "\n";
// Add spaces as frameLevel indicators in case the row is selected and
// copied. These spaces won't be displayed in the cell content.
let firstDescription = cell.querySelector('description:first-of-type');
let levelIndicator = frameLevel > 0 ? " ".repeat(frameLevel) : "";
firstDescription.textContent = levelIndicator + firstDescription.textContent;
return cell;
},
@ -285,7 +297,7 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
urlNode.className = "plain call-tree-url";
urlNode.setAttribute("flex", "1");
urlNode.setAttribute("crop", "end");
urlNode.setAttribute("value", frameInfo.fileName);
urlNode.textContent = frameInfo.fileName;
urlNode.setAttribute("tooltiptext", URL_LABEL_TOOLTIP + " → " + frameInfo.url);
urlNode.addEventListener("mousedown", this._onUrlClick);
cell.appendChild(urlNode);
@ -294,21 +306,21 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
if (frameInfo.line) {
let lineNode = doc.createElement("description");
lineNode.className = "plain call-tree-line";
lineNode.setAttribute("value", ":" + frameInfo.line);
lineNode.textContent = ":" + frameInfo.line;
cell.appendChild(lineNode);
}
if (frameInfo.column) {
let columnNode = doc.createElement("description");
columnNode.className = "plain call-tree-column";
columnNode.setAttribute("value", ":" + frameInfo.column);
columnNode.textContent = ":" + frameInfo.column;
cell.appendChild(columnNode);
}
if (frameInfo.host) {
let hostNode = doc.createElement("description");
hostNode.className = "plain call-tree-host";
hostNode.setAttribute("value", frameInfo.host);
hostNode.textContent = frameInfo.host;
cell.appendChild(hostNode);
}
@ -320,7 +332,7 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
let categoryNode = doc.createElement("description");
categoryNode.className = "plain call-tree-category";
categoryNode.style.color = frameInfo.categoryData.color;
categoryNode.setAttribute("value", frameInfo.categoryData.label);
categoryNode.textContent = frameInfo.categoryData.label;
cell.appendChild(categoryNode);
}
},

View File

@ -7,7 +7,7 @@
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, $, DetailsView, JsCallTreeView } = panel.panelWin;
let { EVENTS, $, $$, DetailsView, JsCallTreeView } = panel.panelWin;
// Enable platform data to show the categories.
Services.prefs.setBoolPref(PLATFORM_DATA_PREF, true);
@ -22,17 +22,26 @@ function* spawnTest() {
is($(".call-tree-cells-container").hasAttribute("categories-hidden"), false,
"The call tree cells container should show the categories now.");
ok($(".call-tree-category[value=Gecko]"),
"A category node with the label `Gecko` is displayed in the tree.");
ok(geckoCategoryPresent($$),
"A category node with the text `Gecko` is displayed in the tree.");
// Disable platform data to show the categories.
Services.prefs.setBoolPref(PLATFORM_DATA_PREF, false);
is($(".call-tree-cells-container").getAttribute("categories-hidden"), "",
"The call tree cells container should hide the categories now.");
ok(!$(".call-tree-category[value=Gecko]"),
"A category node with the label `Gecko` doesn't exist in the tree anymore.");
ok(!geckoCategoryPresent($$),
"A category node with the text `Gecko` doesn't exist in the tree anymore.");
yield teardown(panel);
finish();
}
function geckoCategoryPresent($$) {
for (let elem of $$('.call-tree-category')) {
if (elem.textContent.trim() == 'Gecko') {
return true
}
}
return false
}

View File

@ -31,27 +31,27 @@ function test() {
is(container.childNodes[0].childNodes[0].getAttribute("type"), "duration",
"The root node in the tree has a duration cell.");
is(container.childNodes[0].childNodes[0].getAttribute("value"), "20 ms",
is(container.childNodes[0].childNodes[0].textContent.trim(), "20 ms",
"The root node in the tree has the correct duration cell value.");
is(container.childNodes[0].childNodes[1].getAttribute("type"), "percentage",
"The root node in the tree has a percentage cell.");
is(container.childNodes[0].childNodes[1].getAttribute("value"), "100%",
is(container.childNodes[0].childNodes[1].textContent.trim(), "100%",
"The root node in the tree has the correct percentage cell value.");
is(container.childNodes[0].childNodes[2].getAttribute("type"), "self-duration",
"The root node in the tree has a self-duration cell.");
is(container.childNodes[0].childNodes[2].getAttribute("value"), "0 ms",
is(container.childNodes[0].childNodes[2].textContent.trim(), "0 ms",
"The root node in the tree has the correct self-duration cell value.");
is(container.childNodes[0].childNodes[3].getAttribute("type"), "self-percentage",
"The root node in the tree has a self-percentage cell.");
is(container.childNodes[0].childNodes[3].getAttribute("value"), "0%",
is(container.childNodes[0].childNodes[3].textContent.trim(), "0%",
"The root node in the tree has the correct self-percentage cell value.");
is(container.childNodes[0].childNodes[4].getAttribute("type"), "samples",
"The root node in the tree has an samples cell.");
is(container.childNodes[0].childNodes[4].getAttribute("value"), "0",
is(container.childNodes[0].childNodes[4].textContent.trim(), "0",
"The root node in the tree has the correct samples cell value.");
is(container.childNodes[0].childNodes[5].getAttribute("type"), "function",

View File

@ -33,13 +33,13 @@ function test() {
is(container.childNodes[0].className, "call-tree-item",
"The root node in the tree has the correct class name.");
is($$dur(0).getAttribute("value"), "20 ms",
is($$dur(0).textContent.trim(), "20 ms",
"The root's duration cell displays the correct value.");
is($$perc(0).getAttribute("value"), "100%",
is($$perc(0).textContent.trim(), "100%",
"The root's percentage cell displays the correct value.");
is($$sampl(0).getAttribute("value"), "0",
is($$sampl(0).textContent.trim(), "0",
"The root's samples cell displays the correct value.");
is($$fun(".call-tree-name")[0].getAttribute("value"), "(root)",
is($$fun(".call-tree-name")[0].textContent.trim(), "(root)",
"The root's function cell displays the correct name.");
is($$fun(".call-tree-url")[0], null,
"The root's function cell displays no url.");
@ -59,23 +59,23 @@ function test() {
is(container.childNodes[1].className, "call-tree-item",
"The .A node in the tree has the correct class name.");
is($$dur(1).getAttribute("value"), "20 ms",
is($$dur(1).textContent.trim(), "20 ms",
"The .A node's duration cell displays the correct value.");
is($$perc(1).getAttribute("value"), "100%",
is($$perc(1).textContent.trim(), "100%",
"The .A node's percentage cell displays the correct value.");
is($$sampl(1).getAttribute("value"), "0",
is($$sampl(1).textContent.trim(), "0",
"The .A node's samples cell displays the correct value.");
is($fun(".call-tree-name", $$(".call-tree-item")[1]).getAttribute("value"), "A",
is($fun(".call-tree-name", $$(".call-tree-item")[1]).textContent.trim(), "A",
"The .A node's function cell displays the correct name.");
is($fun(".call-tree-url", $$(".call-tree-item")[1]).getAttribute("value"), "baz",
is($fun(".call-tree-url", $$(".call-tree-item")[1]).textContent.trim(), "baz",
"The .A node's function cell displays the correct url.");
ok($fun(".call-tree-url", $$(".call-tree-item")[1]).getAttribute("tooltiptext").includes("http://foo/bar/baz"),
"The .A node's function cell displays the correct url tooltiptext.");
is($fun(".call-tree-line", $$(".call-tree-item")[1]).getAttribute("value"), ":12",
is($fun(".call-tree-line", $$(".call-tree-item")[1]).textContent.trim(), ":12",
"The .A node's function cell displays the correct line.");
is($fun(".call-tree-host", $$(".call-tree-item")[1]).getAttribute("value"), "foo",
is($fun(".call-tree-host", $$(".call-tree-item")[1]).textContent.trim(), "foo",
"The .A node's function cell displays the correct host.");
is($fun(".call-tree-category", $$(".call-tree-item")[1]).getAttribute("value"), "Gecko",
is($fun(".call-tree-category", $$(".call-tree-item")[1]).textContent.trim(), "Gecko",
"The .A node's function cell displays the correct category.");
let A = treeRoot.getChild();
@ -88,42 +88,42 @@ function test() {
is(container.childNodes[3].className, "call-tree-item",
"The .E node in the tree has the correct class name.");
is($$dur(2).getAttribute("value"), "15 ms",
is($$dur(2).textContent.trim(), "15 ms",
"The .A.B node's duration cell displays the correct value.");
is($$perc(2).getAttribute("value"), "75%",
is($$perc(2).textContent.trim(), "75%",
"The .A.B node's percentage cell displays the correct value.");
is($$sampl(2).getAttribute("value"), "0",
is($$sampl(2).textContent.trim(), "0",
"The .A.B node's samples cell displays the correct value.");
is($fun(".call-tree-name", $$(".call-tree-item")[2]).getAttribute("value"), "B",
is($fun(".call-tree-name", $$(".call-tree-item")[2]).textContent.trim(), "B",
"The .A.B node's function cell displays the correct name.");
is($fun(".call-tree-url", $$(".call-tree-item")[2]).getAttribute("value"), "baz",
is($fun(".call-tree-url", $$(".call-tree-item")[2]).textContent.trim(), "baz",
"The .A.B node's function cell displays the correct url.");
ok($fun(".call-tree-url", $$(".call-tree-item")[2]).getAttribute("tooltiptext").includes("http://foo/bar/baz"),
"The .A.B node's function cell displays the correct url tooltiptext.");
is($fun(".call-tree-line", $$(".call-tree-item")[2]).getAttribute("value"), ":34",
is($fun(".call-tree-line", $$(".call-tree-item")[2]).textContent.trim(), ":34",
"The .A.B node's function cell displays the correct line.");
is($fun(".call-tree-host", $$(".call-tree-item")[2]).getAttribute("value"), "foo",
is($fun(".call-tree-host", $$(".call-tree-item")[2]).textContent.trim(), "foo",
"The .A.B node's function cell displays the correct host.");
is($fun(".call-tree-category", $$(".call-tree-item")[2]).getAttribute("value"), "Styles",
is($fun(".call-tree-category", $$(".call-tree-item")[2]).textContent.trim(), "Styles",
"The .A.B node's function cell displays the correct category.");
is($$dur(3).getAttribute("value"), "5 ms",
is($$dur(3).textContent.trim(), "5 ms",
"The .A.E node's duration cell displays the correct value.");
is($$perc(3).getAttribute("value"), "25%",
is($$perc(3).textContent.trim(), "25%",
"The .A.E node's percentage cell displays the correct value.");
is($$sampl(3).getAttribute("value"), "0",
is($$sampl(3).textContent.trim(), "0",
"The .A.E node's samples cell displays the correct value.");
is($fun(".call-tree-name", $$(".call-tree-item")[3]).getAttribute("value"), "E",
is($fun(".call-tree-name", $$(".call-tree-item")[3]).textContent.trim(), "E",
"The .A.E node's function cell displays the correct name.");
is($fun(".call-tree-url", $$(".call-tree-item")[3]).getAttribute("value"), "baz",
is($fun(".call-tree-url", $$(".call-tree-item")[3]).textContent.trim(), "baz",
"The .A.E node's function cell displays the correct url.");
ok($fun(".call-tree-url", $$(".call-tree-item")[3]).getAttribute("tooltiptext").includes("http://foo/bar/baz"),
"The .A.E node's function cell displays the correct url tooltiptext.");
is($fun(".call-tree-line", $$(".call-tree-item")[3]).getAttribute("value"), ":90",
is($fun(".call-tree-line", $$(".call-tree-item")[3]).textContent.trim(), ":90",
"The .A.E node's function cell displays the correct line.");
is($fun(".call-tree-host", $$(".call-tree-item")[3]).getAttribute("value"), "foo",
is($fun(".call-tree-host", $$(".call-tree-item")[3]).textContent.trim(), "foo",
"The .A.E node's function cell displays the correct host.");
is($fun(".call-tree-category", $$(".call-tree-item")[3]).getAttribute("value"), "GC",
is($fun(".call-tree-category", $$(".call-tree-item")[3]).textContent.trim(), "GC",
"The .A.E node's function cell displays the correct category.");
finish();

View File

@ -42,34 +42,34 @@ function test() {
is($$fun(6).style.MozMarginStart, "48px",
"The .A.E.F node's function cell has the correct indentation.");
is($$name(0).getAttribute("value"), "(root)",
is($$name(0).textContent.trim(), "(root)",
"The root node's function cell displays the correct name.");
is($$name(1).getAttribute("value"), "A",
is($$name(1).textContent.trim(), "A",
"The .A node's function cell displays the correct name.");
is($$name(2).getAttribute("value"), "B",
is($$name(2).textContent.trim(), "B",
"The .A.B node's function cell displays the correct name.");
is($$name(3).getAttribute("value"), "D",
is($$name(3).textContent.trim(), "D",
"The .A.B.D node's function cell displays the correct name.");
is($$name(4).getAttribute("value"), "C",
is($$name(4).textContent.trim(), "C",
"The .A.B.C node's function cell displays the correct name.");
is($$name(5).getAttribute("value"), "E",
is($$name(5).textContent.trim(), "E",
"The .A.E node's function cell displays the correct name.");
is($$name(6).getAttribute("value"), "F",
is($$name(6).textContent.trim(), "F",
"The .A.E.F node's function cell displays the correct name.");
is($$duration(0).getAttribute("value"), "20 ms",
is($$duration(0).textContent.trim(), "20 ms",
"The root node's function cell displays the correct duration.");
is($$duration(1).getAttribute("value"), "20 ms",
is($$duration(1).textContent.trim(), "20 ms",
"The .A node's function cell displays the correct duration.");
is($$duration(2).getAttribute("value"), "15 ms",
is($$duration(2).textContent.trim(), "15 ms",
"The .A.B node's function cell displays the correct duration.");
is($$duration(3).getAttribute("value"), "10 ms",
is($$duration(3).textContent.trim(), "10 ms",
"The .A.B.D node's function cell displays the correct duration.");
is($$duration(4).getAttribute("value"), "5 ms",
is($$duration(4).textContent.trim(), "5 ms",
"The .A.B.C node's function cell displays the correct duration.");
is($$duration(5).getAttribute("value"), "5 ms",
is($$duration(5).textContent.trim(), "5 ms",
"The .A.E node's function cell displays the correct duration.");
is($$duration(6).getAttribute("value"), "5 ms",
is($$duration(6).textContent.trim(), "5 ms",
"The .A.E.F node's function cell displays the correct duration.");
finish();
@ -108,4 +108,3 @@ var gThread = synthesizeProfileForTest([{
{ category: 256, location: "F (http://foo/bar/baz:99)" }
]
}]);

View File

@ -43,21 +43,21 @@ function test() {
"Generalized JS node has correct category");
is(JS.target.getAttribute("tooltiptext"), "JIT",
"Generalized JS node has correct category");
is(JS.target.querySelector(".call-tree-name").getAttribute("value"), "JIT",
is(JS.target.querySelector(".call-tree-name").textContent.trim(), "JIT",
"Generalized JS node has correct display value as just the category name.");
is(JS2.target.getAttribute("category"), "js",
"Generalized second JS node has correct category");
is(JS2.target.getAttribute("tooltiptext"), "JIT",
"Generalized second JS node has correct category");
is(JS2.target.querySelector(".call-tree-name").getAttribute("value"), "JIT",
is(JS2.target.querySelector(".call-tree-name").textContent.trim(), "JIT",
"Generalized second JS node has correct display value as just the category name.");
is(GC.target.getAttribute("category"), "gc",
"Generalized GC node has correct category");
is(GC.target.getAttribute("tooltiptext"), "GC",
"Generalized GC node has correct category");
is(GC.target.querySelector(".call-tree-name").getAttribute("value"), "GC",
is(GC.target.querySelector(".call-tree-name").textContent.trim(), "GC",
"Generalized GC node has correct display value as just the category name.");
finish();

View File

@ -63,9 +63,9 @@ function test() {
let [total, self, name] = def;
name = name.trim();
is($$name(i).getAttribute("value"), name, `${name} has correct name.`);
is($$percentage(i).getAttribute("value"), `${total}%`, `${name} has correct total percent.`);
is($$selfpercentage(i).getAttribute("value"), `${self}%`, `${name} has correct self percent.`);
is($$name(i).textContent.trim(), name, `${name} has correct name.`);
is($$percentage(i).textContent.trim(), `${total}%`, `${name} has correct total percent.`);
is($$selfpercentage(i).textContent.trim(), `${self}%`, `${name} has correct self percent.`);
});
finish();

View File

@ -31,7 +31,7 @@ function* spawnTest() {
let rows = $$("#js-calltree-view .call-tree-item");
is(rows.length, 4, "4 call tree rows exist");
for (let row of rows) {
let name = $(".call-tree-name", row).value;
let name = $(".call-tree-name", row).textContent.trim();
switch (name) {
case "A":
ok($(".opt-icon", row), "found an opt icon on a leaf node with opt data");

View File

@ -522,7 +522,6 @@ AbstractTreeItem.prototype = {
* Handler for the "click" event on the element displaying this tree item.
*/
_onClick: function(e) {
e.preventDefault();
e.stopPropagation();
this.focus();
},

View File

@ -116,11 +116,7 @@
/* Network requests table: specific column dimensions */
.requests-menu-status {
max-width: 4em;
width: 4vw;
}
.requests-menu-status,
.requests-menu-method-box,
.requests-menu-method {
max-width: 6em;
@ -183,10 +179,6 @@
width: 8vw;
}
.requests-menu-transferred {
width: 8vw;
}
/* Network requests table: status codes */
.requests-menu-status-code {
@ -795,11 +787,12 @@
}
.requests-menu-status {
width: 4vw;
max-width: none;
width: 12vw;
}
#requests-menu-status-button {
min-width: 26px;
.requests-menu-status-code {
width: auto;
}
.requests-menu-method,
@ -809,20 +802,20 @@
}
.requests-menu-icon-and-file {
width: 30vw;
width: 22vw;
}
.requests-menu-security-and-domain {
width: 28vw;
width: 18vw;
}
.requests-menu-type,
.requests-menu-transferred {
width: 12vw;
.requests-menu-type {
width: 10vw;
}
.requests-menu-transferred,
.requests-menu-size {
width: 16vw;
width: 12vw;
}
}

View File

@ -269,6 +269,16 @@
background-color: var(--theme-tab-toolbar-background);
}
.call-tree-item .call-tree-cell,
.call-tree-item .call-tree-cell[type=function] description {
-moz-user-select: text;
}
.call-tree-item .call-tree-cell::-moz-selection,
.call-tree-item .call-tree-cell[type=function] description::-moz-selection {
background-color: var(--theme-highlight-orange);
}
.call-tree-item:last-child {
border-bottom: 1px solid var(--cell-border-color);
}

View File

@ -28,6 +28,7 @@
#include "mozilla/StartupTimeline.h"
#include "mozilla/Telemetry.h"
#include "mozilla/unused.h"
#include "Navigator.h"
#include "URIUtils.h"
#include "nsIContent.h"
@ -3128,6 +3129,38 @@ nsDocShell::NameEquals(const char16_t* aName, bool* aResult)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetCustomUserAgent(nsAString& aCustomUserAgent)
{
aCustomUserAgent = mCustomUserAgent;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetCustomUserAgent(const nsAString& aCustomUserAgent)
{
mCustomUserAgent = aCustomUserAgent;
RefPtr<nsGlobalWindow> win = mScriptGlobal ?
mScriptGlobal->GetCurrentInnerWindowInternal() : nullptr;
if (win) {
ErrorResult ignored;
Navigator* navigator = win->GetNavigator(ignored);
ignored.SuppressException();
if (navigator) {
navigator->ClearUserAgentCache();
}
}
uint32_t childCount = mChildList.Length();
for (uint32_t i = 0; i < childCount; ++i) {
nsCOMPtr<nsIDocShell> childShell = do_QueryInterface(ChildAt(i));
if (childShell) {
childShell->SetCustomUserAgent(aCustomUserAgent);
}
}
return NS_OK;
}
/* virtual */ int32_t
nsDocShell::ItemType()
{
@ -3255,6 +3288,7 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent)
// If parent is another docshell, we inherit all their flags for
// allowing plugins, scripting etc.
bool value;
nsString customUserAgent;
nsCOMPtr<nsIDocShell> parentAsDocShell(do_QueryInterface(parent));
if (parentAsDocShell) {
if (mAllowPlugins && NS_SUCCEEDED(parentAsDocShell->GetAllowPlugins(&value))) {
@ -3284,6 +3318,10 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent)
if (parentAsDocShell->GetIsPrerendered()) {
SetIsPrerendered(true);
}
if (NS_SUCCEEDED(parentAsDocShell->GetCustomUserAgent(customUserAgent)) &&
!customUserAgent.IsEmpty()) {
SetCustomUserAgent(customUserAgent);
}
if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) {
value = false;
}

View File

@ -793,6 +793,7 @@ protected:
nsIntRect mBounds;
nsString mName;
nsString mTitle;
nsString mCustomUserAgent;
/**
* Content-Type Hint of the most-recently initiated load. Used for

View File

@ -43,7 +43,7 @@ interface nsITabParent;
typedef unsigned long nsLoadFlags;
[scriptable, builtinclass, uuid(63adb599-6dc9-4746-972e-c22e9018020b)]
[scriptable, builtinclass, uuid(bc3524bd-023c-4fc8-ace1-472bc999fb12)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
@ -237,6 +237,11 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
attribute nsIDOMEventTarget chromeEventHandler;
/**
* This allows chrome to set a custom User agent on a specific docshell
*/
attribute DOMString customUserAgent;
/**
* Whether to allow plugin execution
*/
@ -250,7 +255,7 @@ interface nsIDocShell : nsIDocShellTreeItem
/**
* Attribute stating if refresh based redirects can be allowed
*/
attribute boolean allowMetaRedirects;
attribute boolean allowMetaRedirects;
/**
* Attribute stating if it should allow subframes (framesets/iframes) or not

View File

@ -84,6 +84,7 @@ skip-if = e10s # Bug 1220927 - Test tries to do addSHistoryListener on content.
[browser_multiple_pushState.js]
[browser_onbeforeunload_navigation.js]
[browser_search_notification.js]
[browser_ua_emulation.js]
[browser_timelineMarkers-01.js]
[browser_timelineMarkers-02.js]
[browser_timelineMarkers-03.js]

View File

@ -0,0 +1,52 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the docShell UA emulation works
add_task(function*() {
yield openUrl("data:text/html;charset=utf-8,<iframe id='test-iframe'></iframe>");
let docshell = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
is(docshell.customUserAgent, "", "There should initially be no customUserAgent");
docshell.customUserAgent = "foo";
is(content.navigator.userAgent, "foo", "The user agent should be changed to foo");
let frameWin = content.document.querySelector("#test-iframe").contentWindow;
is(frameWin.navigator.userAgent, "foo", "The UA should be passed on to frames.");
let newFrame = content.document.createElement("iframe");
content.document.body.appendChild(newFrame);
let newFrameWin = newFrame.contentWindow;
is(newFrameWin.navigator.userAgent, "foo", "Newly created frames should use the new UA");
newFrameWin.location.reload();
yield waitForEvent(newFrameWin, "load");
is(newFrameWin.navigator.userAgent, "foo", "New UA should persist across reloads");
gBrowser.removeCurrentTab();
});
function waitForEvent(target, event) {
return new Promise(function(resolve) {
target.addEventListener(event, resolve);
});
}
function openUrl(url) {
return new Promise(function(resolve, reject) {
window.focus();
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
let linkedBrowser = tab.linkedBrowser;
linkedBrowser.addEventListener("load", function onload() {
linkedBrowser.removeEventListener("load", onload, true);
resolve(tab);
}, true);
});
}

View File

@ -372,11 +372,22 @@ Navigator::GetUserAgent(nsAString& aUserAgent)
nsCOMPtr<nsIURI> codebaseURI;
nsCOMPtr<nsPIDOMWindow> window;
if (mWindow && mWindow->GetDocShell()) {
if (mWindow) {
window = mWindow;
nsIDocument* doc = mWindow->GetExtantDoc();
if (doc) {
doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
nsIDocShell* docshell = window->GetDocShell();
nsString customUserAgent;
if (docshell) {
docshell->GetCustomUserAgent(customUserAgent);
if (!customUserAgent.IsEmpty()) {
aUserAgent = customUserAgent;
return NS_OK;
}
nsIDocument* doc = mWindow->GetExtantDoc();
if (doc) {
doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
}
}
}
@ -2741,6 +2752,12 @@ Navigator::AppName(nsAString& aAppName, bool aUsePrefOverriddenValue)
aAppName.AssignLiteral("Netscape");
}
void
Navigator::ClearUserAgentCache()
{
NavigatorBinding::ClearCachedUserAgentValue(this);
}
nsresult
Navigator::GetUserAgent(nsPIDOMWindow* aWindow, nsIURI* aURI,
bool aIsCallerChrome,

View File

@ -182,6 +182,10 @@ public:
bool aIsCallerChrome,
nsAString& aUserAgent);
// Clears the user agent cache by calling:
// NavigatorBinding::ClearCachedUserAgentValue(this);
void ClearUserAgentCache();
already_AddRefed<Promise> GetDataStores(const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv);

View File

@ -41,7 +41,7 @@ interface NavigatorID {
readonly attribute DOMString appVersion;
[Constant, Cached]
readonly attribute DOMString platform;
[Constant, Cached, Throws=Workers]
[Pure, Cached, Throws=Workers]
readonly attribute DOMString userAgent;
[Constant, Cached]
readonly attribute DOMString product; // constant "Gecko"

View File

@ -3031,7 +3031,6 @@ public class BrowserApp extends GeckoApp
bookmark.setVisible(!inGuestMode);
bookmark.setCheckable(true);
bookmark.setChecked(tab.isBookmark());
bookmark.setIcon(resolveBookmarkIconID(tab.isBookmark()));
bookmark.setTitle(resolveBookmarkTitleID(tab.isBookmark()));
reader.setEnabled(isAboutReader || !AboutPages.isAboutPage(tab.getURL()));
@ -3039,9 +3038,14 @@ public class BrowserApp extends GeckoApp
reader.setCheckable(true);
final boolean isPageInReadingList = tab.isInReadingList();
reader.setChecked(isPageInReadingList);
reader.setIcon(resolveReadingListIconID(isPageInReadingList));
reader.setTitle(resolveReadingListTitleID(isPageInReadingList));
if (Versions.feature11Plus) {
// We don't use icons on GB builds so not resolving icons might conserve resources.
bookmark.setIcon(resolveBookmarkIconID(tab.isBookmark()));
reader.setIcon(resolveReadingListIconID(isPageInReadingList));
}
back.setEnabled(tab.canDoBack());
forward.setEnabled(tab.canDoForward());
desktopMode.setChecked(tab.getDesktopMode());
@ -3233,13 +3237,19 @@ public class BrowserApp extends GeckoApp
if (item.isChecked()) {
Telemetry.sendUIEvent(TelemetryContract.Event.UNSAVE, TelemetryContract.Method.MENU, "bookmark");
tab.removeBookmark();
item.setIcon(resolveBookmarkIconID(false));
item.setTitle(resolveBookmarkTitleID(false));
if (Versions.feature11Plus) {
// We don't use icons on GB builds so not resolving icons might conserve resources.
item.setIcon(resolveBookmarkIconID(false));
}
} else {
Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, TelemetryContract.Method.MENU, "bookmark");
tab.addBookmark();
item.setIcon(resolveBookmarkIconID(true));
item.setTitle(resolveBookmarkTitleID(true));
if (Versions.feature11Plus) {
// We don't use icons on GB builds so not resolving icons might conserve resources.
item.setIcon(resolveBookmarkIconID(true));
}
}
}
return true;
@ -3251,13 +3261,19 @@ public class BrowserApp extends GeckoApp
if (item.isChecked()) {
Telemetry.sendUIEvent(TelemetryContract.Event.UNSAVE, TelemetryContract.Method.MENU, "reading_list");
tab.removeFromReadingList();
item.setIcon(resolveReadingListIconID(false));
item.setTitle(resolveReadingListTitleID(false));
if (Versions.feature11Plus) {
// We don't use icons on GB builds so not resolving icons might conserve resources.
item.setIcon(resolveReadingListIconID(false));
}
} else {
Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, TelemetryContract.Method.MENU, "reading_list");
tab.addToReadingList();
item.setIcon(resolveReadingListIconID(true));
item.setTitle(resolveReadingListTitleID(true));
if (Versions.feature11Plus) {
// We don't use icons on GB builds so not resolving icons might conserve resources.
item.setIcon(resolveReadingListIconID(true));
}
}
}
return true;

View File

@ -349,11 +349,7 @@ public abstract class GeckoApp
@Override
public MenuInflater getMenuInflater() {
if (Versions.feature11Plus) {
return new GeckoMenuInflater(this);
} else {
return super.getMenuInflater();
}
return new GeckoMenuInflater(this);
}
public MenuPanel getMenuPanel() {
@ -404,7 +400,7 @@ public abstract class GeckoApp
@Override
public View onCreatePanelView(int featureId) {
if (Versions.feature11Plus && featureId == Window.FEATURE_OPTIONS_PANEL) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
if (mMenuPanel == null) {
mMenuPanel = new MenuPanel(this, null);
} else {
@ -420,7 +416,7 @@ public abstract class GeckoApp
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
if (Versions.feature11Plus && featureId == Window.FEATURE_OPTIONS_PANEL) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
if (mMenuPanel == null) {
mMenuPanel = (MenuPanel) onCreatePanelView(featureId);
}
@ -439,7 +435,7 @@ public abstract class GeckoApp
@Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
if (Versions.feature11Plus && featureId == Window.FEATURE_OPTIONS_PANEL) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
return onPrepareOptionsMenu(menu);
}
@ -453,7 +449,7 @@ public abstract class GeckoApp
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FullScreen:Exit", null));
}
if (Versions.feature11Plus && featureId == Window.FEATURE_OPTIONS_PANEL) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
if (mMenu == null) {
// getMenuPanel() will force the creation of the menu as well
MenuPanel panel = getMenuPanel();
@ -518,10 +514,8 @@ public abstract class GeckoApp
@Override
public void onOptionsMenuClosed(Menu menu) {
if (Versions.feature11Plus) {
mMenuPanel.removeAllViews();
mMenuPanel.addView((GeckoMenu) mMenu);
}
mMenuPanel.removeAllViews();
mMenuPanel.addView((GeckoMenu) mMenu);
}
@Override
@ -2161,6 +2155,7 @@ public abstract class GeckoApp
"PrivateBrowsing:Data",
"Session:StatePurged",
"Share:Text",
"Snackbar:Show",
"SystemUI:Visibility",
"ToggleChrome:Focus",
"ToggleChrome:Hide",

View File

@ -137,7 +137,6 @@ OnSharedPreferenceChangeListener
private static final String PREFS_ADVANCED = NON_PREF_PREFIX + "advanced.enabled";
private static final String PREFS_ACCESSIBILITY = NON_PREF_PREFIX + "accessibility.enabled";
private static final String PREFS_CUSTOMIZE_HOME = NON_PREF_PREFIX + "customize_home";
private static final String PREFS_CUSTOMIZE_IMAGE_BLOCKING = "browser.image_blocking";
private static final String PREFS_TRACKING_PROTECTION_PRIVATE_BROWSING = "privacy.trackingprotection.pbmode.enabled";
private static final String PREFS_TRACKING_PROTECTION_LEARN_MORE = NON_PREF_PREFIX + "trackingprotection.learn_more";
private static final String PREFS_CLEAR_PRIVATE_DATA = NON_PREF_PREFIX + "privacy.clear";
@ -839,12 +838,6 @@ OnSharedPreferenceChangeListener
i--;
continue;
}
} else if (PREFS_CUSTOMIZE_IMAGE_BLOCKING.equals(key)) {
if (!AppConstants.NIGHTLY_BUILD) {
preferences.removePreference(pref);
i--;
continue;
}
} else if (PREFS_CLEAR_PRIVATE_DATA.equals(key) || PREFS_CLEAR_PRIVATE_DATA_EXIT.equals(key)) {
if (!Restrictions.isAllowed(this, Restrictable.CLEAR_HISTORY)) {
preferences.removePreference(pref);

View File

@ -367,13 +367,8 @@ public class TabsPanel extends LinearLayout
mAddTab.setVisibility(View.VISIBLE);
if (!HardwareUtils.hasMenuButton()) {
mMenuButton.setVisibility(View.VISIBLE);
mMenuButton.setEnabled(true);
mPopupMenu.setAnchor(mMenuButton);
} else {
mPopupMenu.setAnchor(mAddTab);
}
mMenuButton.setEnabled(true);
mPopupMenu.setAnchor(mMenuButton);
}
public int getVerticalPanelHeight() {

View File

@ -129,7 +129,6 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout
private OnStopEditingListener stopEditingListener;
protected final BrowserApp activity;
protected boolean hasSoftMenuButton;
protected UIMode uiMode;
protected TabHistoryController tabHistoryController;
@ -194,7 +193,6 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout
menuButton = (ThemedFrameLayout) findViewById(R.id.menu);
menuIcon = (ThemedImageView) findViewById(R.id.menu_icon);
hasSoftMenuButton = !HardwareUtils.hasMenuButton();
// The focusOrder List should be filled by sub-classes.
focusOrder = new ArrayList<View>();
@ -321,17 +319,14 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout
});
tabsButton.setImageLevel(0);
if (hasSoftMenuButton) {
menuButton.setVisibility(View.VISIBLE);
menuButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View view) {
// Drop the soft keyboard.
urlEditLayout.clearFocus();
activity.openOptionsMenu();
}
});
}
menuButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View view) {
// Drop the soft keyboard.
urlEditLayout.clearFocus();
activity.openOptionsMenu();
}
});
}
@Override
@ -660,7 +655,7 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout
public void setToolBarButtonsAlpha(float alpha) {
ViewHelper.setAlpha(tabsCounter, alpha);
if (hasSoftMenuButton && !HardwareUtils.isTablet()) {
if (!HardwareUtils.isTablet()) {
ViewHelper.setAlpha(menuIcon, alpha);
}
}
@ -855,10 +850,6 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout
}
public boolean openOptionsMenu() {
if (!hasSoftMenuButton) {
return false;
}
// Initialize the popup.
if (menuPopup == null) {
View panel = activity.getMenuPanel();
@ -882,10 +873,6 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout
}
public boolean closeOptionsMenu() {
if (!hasSoftMenuButton) {
return false;
}
if (menuPopup != null && menuPopup.isShowing()) {
menuPopup.dismiss();
}

View File

@ -118,15 +118,11 @@ class BrowserToolbarPhone extends BrowserToolbarPhoneBase {
animator.attach(tabsCounter,
PropertyAnimator.Property.TRANSLATION_X,
curveTranslation);
if (!HardwareUtils.hasMenuButton()) {
animator.attach(menuButton,
PropertyAnimator.Property.TRANSLATION_X,
curveTranslation);
animator.attach(menuIcon,
PropertyAnimator.Property.TRANSLATION_X,
curveTranslation);
}
animator.attach(menuButton,
PropertyAnimator.Property.TRANSLATION_X,
curveTranslation);
animator.attach(menuIcon,
PropertyAnimator.Property.TRANSLATION_X,
curveTranslation);
}
}

View File

@ -127,24 +127,18 @@ abstract class BrowserToolbarPhoneBase extends BrowserToolbar {
public void triggerTabsPanelTransition(final PropertyAnimator animator, final boolean areTabsShown) {
if (areTabsShown) {
ViewHelper.setAlpha(tabsCounter, 0.0f);
if (hasSoftMenuButton) {
ViewHelper.setAlpha(menuIcon, 0.0f);
}
ViewHelper.setAlpha(menuIcon, 0.0f);
return;
}
final PropertyAnimator buttonsAnimator =
new PropertyAnimator(animator.getDuration(), buttonsInterpolator);
buttonsAnimator.attach(tabsCounter,
PropertyAnimator.Property.ALPHA,
1.0f);
if (hasSoftMenuButton) {
buttonsAnimator.attach(menuIcon,
PropertyAnimator.Property.ALPHA,
1.0f);
}
buttonsAnimator.attach(menuIcon,
PropertyAnimator.Property.ALPHA,
1.0f);
buttonsAnimator.start();
}

View File

@ -54,17 +54,12 @@ class BrowserToolbarPreHC extends BrowserToolbarPhoneBase {
// Prevent taps through the editing mode cancel button (bug 1001243).
tabsButton.setEnabled(!isEditing);
menuButton.setEnabled(!isEditing);
ViewHelper.setTranslationX(urlBarTranslatingEdge, entryTranslation);
ViewHelper.setTranslationX(tabsButton, curveTranslation);
ViewHelper.setTranslationX(tabsCounter, curveTranslation);
if (!HardwareUtils.hasMenuButton()) {
// Prevent tabs through the editing mode cancel button (bug 1001243).
menuButton.setEnabled(!isEditing);
ViewHelper.setTranslationX(menuButton, curveTranslation);
ViewHelper.setTranslationX(menuIcon, curveTranslation);
}
ViewHelper.setTranslationX(menuButton, curveTranslation);
ViewHelper.setTranslationX(menuIcon, curveTranslation);
}
}

View File

@ -69,7 +69,7 @@ abstract class BrowserToolbarTabletBase extends BrowserToolbar {
ColorUtils.getColor(context, R.color.tabs_tray_icon_grey), PorterDuff.Mode.SRC_IN);
menuButtonMarginView = findViewById(R.id.menu_margin);
if (menuButtonMarginView != null && !HardwareUtils.hasMenuButton()) {
if (menuButtonMarginView != null) {
menuButtonMarginView.setVisibility(View.VISIBLE);
}
}

View File

@ -36,7 +36,6 @@ public final class HardwareUtils {
private static volatile boolean sIsLargeTablet;
private static volatile boolean sIsSmallTablet;
private static volatile boolean sIsTelevision;
private static volatile boolean sHasMenuButton;
private HardwareUtils() {
}
@ -51,23 +50,16 @@ public final class HardwareUtils {
// Pre-populate common flags from the context.
final int screenLayoutSize = context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
if (Build.VERSION.SDK_INT >= 11) {
sHasMenuButton = false;
if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
sIsLargeTablet = true;
} else if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_LARGE) {
sIsSmallTablet = true;
}
if (Build.VERSION.SDK_INT >= 14) {
sHasMenuButton = ViewConfiguration.get(context).hasPermanentMenuKey();
if (Build.VERSION.SDK_INT >= 16) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION)) {
sIsTelevision = true;
}
if (Build.VERSION.SDK_INT >= 16) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION)) {
sIsTelevision = true;
}
}
} else {
sHasMenuButton = true;
}
sInited = true;
@ -89,10 +81,6 @@ public final class HardwareUtils {
return sIsTelevision;
}
public static boolean hasMenuButton() {
return sHasMenuButton;
}
public static int getMemSize() {
return SysInfo.getMemSize();
}

View File

@ -270,3 +270,8 @@
<!-- Localization note: the format string below will be replaced
with the Firefox Account's email address. -->
<!ENTITY fxaccount_sync_finish_migrating_notification_text 'Tap to sign in as &formatS;'>
<!-- Localization note: the following strings are used in a
notification and should be kept as short as possible. -->
<!ENTITY old_sync_deprecated_notification_title 'Sign in to continue syncing'>
<!ENTITY old_sync_deprecated_notification_content 'Your account is no longer supported'>

View File

Before

Width:  |  Height:  |  Size: 292 B

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!-- This asset is properly available in large-* dirs so this null
reference exists for build time on API 9 builds. -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent"/>
</shape>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!-- This asset is properly available in large-* dirs so this null
reference exists for build time on API 9 builds. -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent"/>
</shape>

View File

@ -124,8 +124,7 @@
android:layout_toLeftOf="@id/menu_margin"
android:layout_alignWithParentIfMissing="true"
android:contentDescription="@string/menu"
android:background="@drawable/browser_toolbar_action_bar_button"
android:visibility="gone">
android:background="@drawable/browser_toolbar_action_bar_button">
<org.mozilla.gecko.widget.themed.ThemedImageView
android:id="@+id/menu_icon"

View File

@ -41,8 +41,7 @@
style="@style/UrlBar.ImageButton"
android:layout_alignParentRight="true"
android:contentDescription="@string/menu"
android:background="@drawable/shaped_button"
android:visibility="gone">
android:background="@drawable/shaped_button">
<org.mozilla.gecko.widget.themed.ThemedImageView
android:id="@+id/menu_icon"

View File

@ -53,8 +53,7 @@
style="@style/UrlBar.ImageButton"
android:layout_width="@dimen/tabs_panel_button_width"
android:background="@drawable/action_bar_button_inverse"
android:contentDescription="@string/menu"
android:visibility="gone">
android:contentDescription="@string/menu">
<ImageButton
style="@style/UrlBar.ImageButton"

View File

@ -6,28 +6,24 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/reload"
android:icon="@drawable/ic_menu_reload"
android:title="@string/reload"/>
<!-- We keep the reference so calls to findView don't fail. Hide
to avoid taking up real estate on the users' screen. -->
<item android:id="@+id/back"
android:icon="@drawable/ic_menu_back"
android:title="@string/back"
android:visible="false"/>
<item android:id="@+id/forward"
android:icon="@drawable/ic_menu_forward"
android:title="@string/forward"/>
<item android:id="@+id/bookmark"
android:icon="@drawable/ic_menu_bookmark_add"
android:title="@string/bookmark"/>
<item android:id="@+id/new_tab"
android:icon="@drawable/ic_menu_new_tab"
android:title="@string/new_tab"/>
<item android:id="@+id/new_private_tab"
android:icon="@drawable/ic_menu_new_private_tab"
android:title="@string/new_private_tab"/>
<item android:id="@+id/share"
@ -36,13 +32,6 @@
<item android:id="@+id/reading_list"
android:title="@string/overlay_share_reading_list_btn_label" />
<item android:id="@+id/save_as_pdf"
android:title="@string/save_as_pdf" />
<item android:id="@+id/print"
android:visible="false"
android:title="@string/print" />
<item android:id="@+id/find_in_page"
android:title="@string/find_in_page" />
@ -50,14 +39,47 @@
android:title="@string/desktop_mode"
android:checkable="true" />
<item android:id="@+id/addons"
android:title="@string/addons"/>
<item android:id="@+id/page"
android:title="@string/page">
<item android:id="@+id/downloads"
android:title="@string/downloads"/>
<menu>
<item android:id="@+id/subscribe"
android:title="@string/contextmenu_subscribe"/>
<item android:id="@+id/logins"
android:title="@string/logins"/>
<item android:id="@+id/save_as_pdf"
android:title="@string/save_as_pdf"/>
<item android:id="@+id/print"
android:title="@string/print"/>
<item android:id="@+id/add_search_engine"
android:title="@string/contextmenu_add_search_engine"/>
<item android:id="@+id/add_to_launcher"
android:title="@string/contextmenu_add_to_launcher"/>
</menu>
</item>
<item android:id="@+id/tools"
android:title="@string/tools">
<menu>
<item android:id="@+id/downloads"
android:title="@string/downloads"/>
<item android:id="@+id/addons"
android:title="@string/addons"/>
<item android:id="@+id/logins"
android:title="@string/logins"/>
<item android:id="@+id/new_guest_session"
android:visible="false"
android:title="@string/new_guest_session"/>
<item android:id="@+id/exit_guest_session"
android:visible="false"
android:title="@string/exit_guest_session"/>
</menu>
</item>
<item android:id="@+id/char_encoding"
android:visible="false"
@ -69,14 +91,6 @@
<item android:id="@+id/help"
android:title="@string/help_menu" />
<item android:id="@+id/new_guest_session"
android:visible="false"
android:title="@string/new_guest_session"/>
<item android:id="@+id/exit_guest_session"
android:visible="false"
android:title="@string/exit_guest_session"/>
<!-- Android will eliminate v11+ resource files from pre-11 builds.
Those files are the only place in which certain IDs are defined.
This causes compilation errors.
@ -87,13 +101,4 @@
android:visible="false"
android:enabled="false" />
<item android:id="@+id/page"
android:visible="false"
android:enabled="false"
android:title="@string/page" />
<item android:id="@+id/tools"
android:visible="false"
android:enabled="false"
android:title="@string/tools" />
</menu>

View File

@ -1003,7 +1003,12 @@ SessionStore.prototype = {
// we stop the load above
let activeIndex = (aTabData.index || aTabData.entries.length) - 1;
aHistory.getEntryAtIndex(activeIndex, true);
aHistory.QueryInterface(Ci.nsISHistory).reloadCurrentEntry();
try {
aHistory.QueryInterface(Ci.nsISHistory).reloadCurrentEntry();
} catch (e) {
// This will throw if the current entry is an error page.
}
},
/**

View File

@ -68,7 +68,12 @@ public class HealthReportUploadService extends BackgroundService {
Logger.warn(LOG_TAG, "Got intent without uploadEnabled. Ignoring.");
return;
}
boolean uploadEnabled = intent.getBooleanExtra("uploadEnabled", false);
// We disabled Health Report uploads in Bug 1230206, because the service is being decommissioned.
// We chose this specific place to turn uploads off because we wish to preserve deletions in the
// interim, and this is the tested code path for when a user turns off upload, but still expects
// deletions to work.
boolean uploadEnabled = false;
// Don't do anything if the device can't talk to the server.
if (!backgroundDataIsEnabled()) {

View File

@ -103,9 +103,11 @@ public class SubmissionPolicy {
// with one request.
final String obsoleteId = tracker.getNextObsoleteId();
if (obsoleteId == null) {
Logger.debug(LOG_TAG, "Upload disabled and nothing to delete.");
return false;
}
Logger.info(LOG_TAG, "Upload disabled. Deleting obsolete document.");
Editor editor = editor();
editor.setLastDeleteRequested(localTime); // Write committed by delegate.
client.delete(localTime, obsoleteId, new DeleteDelegate(editor));

View File

@ -213,10 +213,6 @@ public class FxAccountStatusFragment
syncNowPreference = ensureFindPreference("sync_now");
syncNowPreference.setEnabled(true);
syncNowPreference.setOnPreferenceClickListener(this);
if (HardwareUtils.hasMenuButton()) {
syncCategory.removePreference(morePreference);
}
}
/**

View File

@ -54,4 +54,6 @@ public class SyncConstants {
// Used for BackoffHandler storage for Sync 1.1's SyncAdapter.
public static final String BACKOFF_PREF_SUFFIX_11 = "sync";
public static final String SYNC_ACCOUNT_DEPRECATED_ACTION = AppConstants.MOZ_ANDROID_SHARED_ACCOUNT_TYPE + ".accounts.SYNC_ACCOUNT_DEPRECATED_ACTION";
}

View File

@ -4,6 +4,9 @@
package org.mozilla.gecko.sync.receivers;
import org.mozilla.gecko.fxa.FirefoxAccounts;
import org.mozilla.gecko.fxa.FxAccountConstants;
import org.mozilla.gecko.fxa.activities.FxAccountWebFlowActivity;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.background.common.GlobalConstants;
import org.mozilla.gecko.background.common.log.Logger;
@ -16,8 +19,10 @@ import org.mozilla.gecko.sync.config.ClientRecordTerminator;
import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
import org.mozilla.gecko.sync.setup.Constants;
import org.mozilla.gecko.sync.setup.SyncAccounts;
import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.IntentService;
import android.content.Context;
@ -41,6 +46,27 @@ public class SyncAccountDeletedService extends IntentService {
final Context context = this;
if (SyncConstants.SYNC_ACCOUNT_DEPRECATED_ACTION.equals(intent.getAction())) {
// Delete Old Sync account.
final Account[] accounts = SyncAccounts.syncAccounts(this);
for (Account account : accounts) {
AccountManager.get(this).removeAccount(account, null, null);
}
// Offer signin for Firefox Account if we don't already have one.
if (!FirefoxAccounts.firefoxAccountsExist(this)) {
final Intent fxAccountWebIntent = new Intent(FxAccountConstants.ACTION_FXA_GET_STARTED);
fxAccountWebIntent.putExtra(FxAccountWebFlowActivity.EXTRA_ENDPOINT, FxAccountConstants.ENDPOINT_PREFERENCES);
fxAccountWebIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
fxAccountWebIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
context.startActivity(fxAccountWebIntent);
}
// Return early. The SYNC_ACCOUNT_DELETED_ACTION spawn by the account
// deletion above will remove the pickle file.
return;
}
long intentVersion = intent.getLongExtra(Constants.JSON_KEY_VERSION, 0);
long expectedVersion = SyncConstants.SYNC_ACCOUNT_DELETED_INTENT_VERSION;
if (intentVersion != expectedVersion) {

View File

@ -4,10 +4,12 @@
package org.mozilla.gecko.sync.receivers;
import org.mozilla.gecko.R;
import org.mozilla.gecko.background.common.GlobalConstants;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.CredentialException;
import org.mozilla.gecko.sync.SyncConfiguration;
import org.mozilla.gecko.sync.SyncConstants;
import org.mozilla.gecko.sync.ThreadPool;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.config.ConfigurationMigrator;
@ -17,9 +19,12 @@ import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat.Builder;
public class UpgradeReceiver extends BroadcastReceiver {
private static final String LOG_TAG = "UpgradeReceiver";
@ -34,6 +39,14 @@ public class UpgradeReceiver extends BroadcastReceiver {
return;
}
// Show account not supported notification.
ThreadPool.run(new Runnable() {
@Override
public void run() {
notifyAccountDeprecation(context);
}
});
// Should filter for specific MY_PACKAGE_REPLACED intent, but Android does
// not expose it.
ThreadPool.run(new Runnable() {
@ -94,4 +107,24 @@ public class UpgradeReceiver extends BroadcastReceiver {
}
});
}
/**
* Show a persistent notification telling the user that their Old Sync account is deprecated.
*/
private void notifyAccountDeprecation(final Context context) {
final Intent notificationIntent = new Intent(SyncConstants.SYNC_ACCOUNT_DEPRECATED_ACTION);
notificationIntent.setClass(context, SyncAccountDeletedService.class);
final PendingIntent pendingIntent = PendingIntent.getService(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
final Builder builder = new Builder(context)
.setSmallIcon(R.drawable.ic_status_logo)
.setContentTitle(context.getString(R.string.old_sync_deprecated_notification_title))
.setContentText(context.getString(R.string.old_sync_deprecated_notification_content))
.setAutoCancel(true)
.setOngoing(true)
.setContentIntent(pendingIntent);
final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final int notificationID = SyncConstants.SYNC_ACCOUNT_DEPRECATED_ACTION.hashCode();
notificationManager.notify(notificationID, builder.build());
}
}

View File

@ -242,3 +242,7 @@
<!-- Log Personal information -->
<string name="fxaccount_enable_debug_mode">&fxaccount_enable_debug_mode;</string>
<!-- Old Sync Account deprecated notification. -->
<string name="old_sync_deprecated_notification_title">&old_sync_deprecated_notification_title;</string>
<string name="old_sync_deprecated_notification_content">&old_sync_deprecated_notification_content;</string>

View File

@ -11,13 +11,13 @@ import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertTrue;
import java.util.List;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.R;
import org.mozilla.gecko.menu.MenuItemActionBar;
import org.mozilla.gecko.menu.MenuItemDefault;
import org.mozilla.gecko.tests.UITestContext;
import org.mozilla.gecko.tests.helpers.DeviceHelper;
import org.mozilla.gecko.tests.helpers.WaitHelper;
import org.mozilla.gecko.util.HardwareUtils;
import android.text.TextUtils;
import android.view.View;
@ -31,7 +31,7 @@ import com.jayway.android.robotium.solo.Solo;
* A class representing any interactions that take place on the app menu.
*/
public class AppMenuComponent extends BaseComponent {
private static final long MAX_WAITTIME_FOR_MENU_UPDATE_IN_MS = 1000L;
private static final long MAX_WAITTIME_FOR_MENU_UPDATE_IN_MS = 7500L;
private Boolean hasLegacyMenu = null;
@ -243,9 +243,9 @@ public class AppMenuComponent extends BaseComponent {
private void openAppMenu() {
assertMenuIsNotOpen();
// This is a hack needed for tablets where the OverflowMenuButton is always in the GONE state,
// This is a hack needed for tablets & GB where the OverflowMenuButton is always in the GONE state,
// so we press the menu key instead.
if (HardwareUtils.hasMenuButton() || DeviceHelper.isTablet()) {
if (DeviceHelper.isTablet() || AppConstants.Versions.preHC) {
mSolo.sendKey(Solo.MENU);
} else {
pressOverflowMenuButton();
@ -283,12 +283,14 @@ public class AppMenuComponent extends BaseComponent {
}
/**
* Determines whether the app menu is open by searching for the text "New tab".
* Determines whether the app menu is open by searching for items in the menu.
*
* @return true if app menu is open.
*/
private boolean isMenuOpen() {
return isMenuOpen(MenuItem.NEW_TAB.getString(mSolo));
// We choose these options because New Tab is near the top of the menu and Page is near the middle/bottom.
// Intermittently, the menu doesn't scroll to top so we can't just use the first item in the list.
return isMenuOpen(MenuItem.NEW_TAB.getString(mSolo)) || isMenuOpen(MenuItem.PAGE.getString(mSolo));
}
private boolean isLegacyMoreMenuOpen() {

View File

@ -221,7 +221,7 @@ public class SwitchBoard {
if(serverUrl != null) {
String params = "uuid="+uuid+"&device="+device+"&lang="+lang+"&country="+country
+"&manufacturer="+manufacturer+"&appId="+packageName+"&version="+versionName;
if(DEBUG) Log.d(TAG, "Read from server URL: " + serverUrl + params);
if(DEBUG) Log.d(TAG, "Read from server URL: " + serverUrl + "?" + params);
String serverConfig = readFromUrlGET(serverUrl, params);
if(DEBUG) Log.d(TAG, serverConfig);

View File

@ -37,6 +37,7 @@
#include "nsIObserverService.h"
#include "nsProxyRelease.h"
#include "nsPIDOMWindow.h"
#include "nsIDocShell.h"
#include "nsPerformance.h"
#include "nsINetworkInterceptController.h"
#include "mozIThirdPartyUtil.h"
@ -253,7 +254,7 @@ NS_IMETHODIMP
HttpBaseChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
{
MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread.");
if (!CanSetLoadGroup(aLoadGroup)) {
return NS_ERROR_FAILURE;
}
@ -295,6 +296,47 @@ HttpBaseChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetDocshellUserAgentOverride()
{
// This sets the docshell specific user agent override, it will be overwritten
// by UserAgentOverrides.jsm if site-specific user agent overrides are set.
nsresult rv;
nsCOMPtr<nsILoadContext> loadContext;
NS_QueryNotificationCallbacks(this, loadContext);
if (!loadContext) {
return NS_OK;
}
nsCOMPtr<nsIDOMWindow> domWindow;
loadContext->GetAssociatedWindow(getter_AddRefs(domWindow));
if (!domWindow) {
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> pDomWindow = do_QueryInterface(domWindow);
if (!pDomWindow) {
return NS_OK;
}
nsIDocShell* docshell = pDomWindow->GetDocShell();
if (!docshell) {
return NS_OK;
}
nsString customUserAgent;
docshell->GetCustomUserAgent(customUserAgent);
if (customUserAgent.IsEmpty()) {
return NS_OK;
}
NS_ConvertUTF16toUTF8 utf8CustomUserAgent(customUserAgent);
rv = SetRequestHeader(NS_LITERAL_CSTRING("User-Agent"), utf8CustomUserAgent, false);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpBaseChannel::nsIChannel
//-----------------------------------------------------------------------------
@ -369,7 +411,7 @@ NS_IMETHODIMP
HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
{
MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread.");
if (!CanSetCallbacks(aCallbacks)) {
return NS_ERROR_FAILURE;
}
@ -1379,7 +1421,7 @@ HttpBaseChannel::SetReferrerWithPolicy(nsIURI *referrer,
if (eTLDService) {
rv = eTLDService->GetBaseDomain(mURI, extraDomains, currentDomain);
if (NS_FAILED(rv)) return rv;
rv = eTLDService->GetBaseDomain(clone, extraDomains, referrerDomain);
rv = eTLDService->GetBaseDomain(clone, extraDomains, referrerDomain);
if (NS_FAILED(rv)) return rv;
}
@ -2446,7 +2488,7 @@ void
HttpBaseChannel::ReleaseListeners()
{
MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread.");
mListener = nullptr;
mListenerContext = nullptr;
mCallbacks = nullptr;
@ -3113,4 +3155,3 @@ HttpBaseChannel::SetCorsPreflightParameters(const nsTArray<nsCString>& aUnsafeHe
} // namespace net
} // namespace mozilla

View File

@ -100,6 +100,7 @@ public:
NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup) override;
NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags) override;
NS_IMETHOD SetLoadFlags(nsLoadFlags aLoadFlags) override;
NS_IMETHOD SetDocshellUserAgentOverride();
// nsIChannel
NS_IMETHOD GetOriginalURI(nsIURI **aOriginalURI) override;

View File

@ -1743,6 +1743,9 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
return NS_OK;
}
// Set user agent override
HttpBaseChannel::SetDocshellUserAgentOverride();
if (ShouldIntercept()) {
mResponseCouldBeSynthesized = true;

View File

@ -5038,6 +5038,9 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
gHttpHandler->OnOpeningRequest(this);
}
// Set user agent override
HttpBaseChannel::SetDocshellUserAgentOverride();
mIsPending = true;
mWasOpened = true;

View File

@ -2,6 +2,8 @@
# 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/.
import os
from mozboot.base import BaseBootstrapper
@ -13,8 +15,7 @@ class FedoraBootstrapper(BaseBootstrapper):
self.dist_id = dist_id
self.group_packages = [
'Development Tools',
'Development Libraries',
'C Development Tools and Libraries',
]
self.packages = [
@ -43,6 +44,13 @@ class FedoraBootstrapper(BaseBootstrapper):
'yasm',
]
self.mobile_android_packages = [
'ant',
'ncurses-devel.i686',
'libstdc++.i686',
'zlib-devel.i686',
]
def install_system_packages(self):
self.dnf_groupinstall(*self.group_packages)
self.dnf_install(*self.packages)
@ -51,5 +59,27 @@ class FedoraBootstrapper(BaseBootstrapper):
self.dnf_groupinstall(*self.browser_group_packages)
self.dnf_install(*self.browser_packages)
def install_mobile_android_packages(self):
import android
# Install Android specific packages.
self.dnf_install(*self.mobile_android_packages)
# Fetch Android SDK and NDK.
mozbuild_path = os.environ.get('MOZBUILD_STATE_PATH', os.path.expanduser(os.path.join('~', '.mozbuild')))
self.sdk_path = os.environ.get('ANDROID_SDK_HOME', os.path.join(mozbuild_path, 'android-sdk-linux'))
self.ndk_path = os.environ.get('ANDROID_NDK_HOME', os.path.join(mozbuild_path, 'android-ndk-r10e'))
self.sdk_url = 'https://dl.google.com/android/android-sdk_r24.0.1-linux.tgz'
self.ndk_url = android.android_ndk_url('linux')
android.ensure_android_sdk_and_ndk(path=mozbuild_path,
sdk_path=self.sdk_path, sdk_url=self.sdk_url,
ndk_path=self.ndk_path, ndk_url=self.ndk_url)
def suggest_mobile_android_mozconfig(self):
import android
android.suggest_mozconfig(sdk_path=self.sdk_path,
ndk_path=self.ndk_path)
def upgrade_mercurial(self, current):
self.dnf_update('mercurial')

View File

@ -2304,11 +2304,12 @@ var AddonManagerInternal = {
},
/**
* Starts installation of a temporary add-on from a local directory.
* @param aDirectory
* The directory of the add-on to be temporarily installed
* @return a Promise that rejects if the add-on is not restartless
* or an add-on with the same ID is already temporarily installed
* Installs a temporary add-on from a local file or directory.
* @param aFile
* An nsIFile for the file or directory of the add-on to be
* temporarily installed.
* @return a Promise that rejects if the add-on is not a valid restartless
* add-on or if the same ID is already temporarily installed.
*/
installTemporaryAddon: function(aFile) {
if (!gStarted)

View File

@ -3825,18 +3825,18 @@ this.XPIProvider = {
},
/**
* Temporarily installs add-on from local directory.
* Temporarily installs add-on from a local XPI file or directory.
* As this is intended for development, the signature is not checked and
* the add-on does not persist on application restart.
*
* @param aDirectory
* The directory containing the unpacked add-on directory or XPI file
* @param aFile
* An nsIFile for the unpacked add-on directory or XPI file.
*
* @return a Promise that rejects if the add-on is not restartless
* or an add-on with the same ID is already temporarily installed
* @return a Promise that rejects if the add-on is not a valid restartless
* add-on or if the same ID is already temporarily installed
*/
installTemporaryAddon: Task.async(function*(aDirectory) {
let addon = yield loadManifestFromFile(aDirectory, TemporaryInstallLocation);
installTemporaryAddon: Task.async(function*(aFile) {
let addon = yield loadManifestFromFile(aFile, TemporaryInstallLocation);
if (!addon.bootstrap) {
throw new Error("Only restartless (bootstrap) add-ons"
@ -3887,7 +3887,7 @@ this.XPIProvider = {
XPIProvider.callBootstrapMethod(addon, file, "install",
BOOTSTRAP_REASONS.ADDON_INSTALL);
addon.state = AddonManager.STATE_INSTALLED;
logger.debug("Install of temporary addon in " + aDirectory.path + " completed.");
logger.debug("Install of temporary addon in " + aFile.path + " completed.");
addon.visible = true;
addon.enabled = true;
addon.active = true;
@ -7977,8 +7977,7 @@ Object.assign(SystemAddonInstallLocation.prototype, {
});
/**
* An object which identifies a directory install location for temporary
* add-ons.
* An object which identifies an install location for temporary add-ons.
*/
const TemporaryInstallLocation = {
locked: false,

View File

@ -2363,7 +2363,6 @@ nsWindow::Natives::OnImeReplaceText(int32_t aStart, int32_t aEnd,
event.mOffset = uint32_t(aStart);
event.mLength = uint32_t(aEnd - aStart);
event.mExpandToClusterBoundary = false;
event.mReason = nsISelectionListener::IME_REASON;
window.DispatchEvent(&event);
}
@ -2492,7 +2491,6 @@ nsWindow::Natives::OnImeUpdateComposition(int32_t aStart, int32_t aEnd)
selEvent.mLength = std::max(aStart, aEnd) - selEvent.mOffset;
selEvent.mReversed = aStart > aEnd;
selEvent.mExpandToClusterBoundary = false;
selEvent.mReason = nsISelectionListener::IME_REASON;
window.DispatchEvent(&selEvent);
return;