Merge fx-team to m-c.

This commit is contained in:
Ryan VanderMeulen 2014-02-04 14:31:48 -05:00
commit abc9790f7d
50 changed files with 661 additions and 261 deletions

View File

@ -6,7 +6,7 @@
const { Cc, Ci } = require('chrome');
const { isPrivate } = require('sdk/private-browsing');
const { isWindowPBSupported } = require('sdk/private-browsing/utils');
const { onFocus, getMostRecentWindow, getWindowTitle,
const { onFocus, getMostRecentWindow, getWindowTitle, getInnerId,
getFrames, windows, open: openWindow, isWindowPrivate } = require('sdk/window/utils');
const { open, close, focus, promise } = require('sdk/window/helpers');
const { browserWindows } = require("sdk/windows");
@ -25,31 +25,28 @@ function makeEmptyBrowserWindow(options) {
chrome: true,
private: !!options.private
}
});
}).then(focus);
}
exports.testWindowTrackerIgnoresPrivateWindows = function(assert, done) {
var myNonPrivateWindow, myPrivateWindow;
var finished = false;
var privateWindow;
var myNonPrivateWindowId, myPrivateWindowId;
var privateWindowClosed = false;
var privateWindowOpened = false;
var trackedWindowIds = [];
let wt = winUtils.WindowTracker({
onTrack: function(window) {
if (window === myPrivateWindow) {
assert.equal(isPrivate(window), isWindowPBSupported);
privateWindowOpened = true;
}
let id = getInnerId(window);
trackedWindowIds.push(id);
},
onUntrack: function(window) {
if (window === myPrivateWindow && isWindowPBSupported) {
let id = getInnerId(window);
if (id === myPrivateWindowId) {
privateWindowClosed = true;
}
if (window === myNonPrivateWindow) {
assert.equal(privateWindowClosed, isWindowPBSupported);
assert.ok(privateWindowOpened);
if (id === myNonPrivateWindowId) {
assert.equal(privateWindowClosed, true, 'private window was untracked');
wt.unload();
done();
}
@ -57,27 +54,23 @@ exports.testWindowTrackerIgnoresPrivateWindows = function(assert, done) {
});
// make a new private window
myPrivateWindow = openWindow(BROWSER, {
features: {
private: true
}
});
promise(myPrivateWindow, 'load').then(function(window) {
makeEmptyBrowserWindow({ private: true }).then(function(window) {
myPrivateWindowId = getInnerId(window);
assert.ok(trackedWindowIds.indexOf(myPrivateWindowId) >= 0, 'private window was tracked');
assert.equal(isPrivate(window), isWindowPBSupported, 'private window isPrivate');
assert.equal(isWindowPrivate(window), isWindowPBSupported);
assert.ok(getFrames(window).length > 1, 'there are frames for private window');
assert.equal(getWindowTitle(window), window.document.title,
'getWindowTitle works');
close(myPrivateWindow).then(function() {
close(window).then(function() {
assert.pass('private window was closed');
makeEmptyBrowserWindow().then(function(window) {
myNonPrivateWindow = window;
assert.notDeepEqual(myPrivateWindow, myNonPrivateWindow);
assert.pass('opened new window');
close(myNonPrivateWindow).then(function() {
assert.pass('non private window was closed');
})
myNonPrivateWindowId = getInnerId(window);
assert.notEqual(myPrivateWindowId, myNonPrivateWindowId, 'non private window was opened');
close(window);
});
});
});
@ -95,7 +88,7 @@ exports.testSettingActiveWindowDoesNotIgnorePrivateWindow = function(assert, don
// make a new private window
makeEmptyBrowserWindow({
private: true
}).then(focus).then(function(window) {
}).then(function(window) {
let continueAfterFocus = function(window) onFocus(window).then(nextTest);
// PWPB case
@ -172,7 +165,7 @@ exports.testActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
// make a new private window
makeEmptyBrowserWindow({
private: true
}).then(focus).then(function(window) {
}).then(function(window) {
// PWPB case
if (isWindowPBSupported) {
assert.equal(isPrivate(winUtils.activeWindow), true,
@ -212,7 +205,7 @@ exports.testWindowIteratorIgnoresPrivateWindows = function(assert, done) {
// make a new private window
makeEmptyBrowserWindow({
private: true
}).then(focus).then(function(window) {
}).then(function(window) {
assert.equal(isWindowPrivate(window), isWindowPBSupported);
assert.ok(toArray(winUtils.windowIterator()).indexOf(window) > -1,
"window is in windowIterator()");

View File

@ -128,12 +128,14 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
let url = aSource.url;
let label = SourceUtils.getSourceLabel(url.split(" -> ").pop());
let group = SourceUtils.getSourceGroup(url.split(" -> ").pop());
let unicodeUrl = NetworkHelper.convertToUnicode(unescape(url));
let contents = document.createElement("label");
contents.className = "plain dbg-source-item";
contents.setAttribute("value", label);
contents.setAttribute("crop", "start");
contents.setAttribute("flex", "1");
contents.setAttribute("tooltiptext", unicodeUrl);
// Append a source item to this container.
this.push([contents, url], {

View File

@ -45,6 +45,13 @@ function testSourcesDisplay() {
is(gSources.itemCount, 2,
"Found the expected number of sources.");
is(gSources.items[0].target.querySelector(".dbg-source-item").getAttribute("tooltiptext"),
EXAMPLE_URL + "code_script-switching-01.js",
"The correct tooltip text is displayed for the first source.");
is(gSources.items[1].target.querySelector(".dbg-source-item").getAttribute("tooltiptext"),
EXAMPLE_URL + "code_script-switching-02.js",
"The correct tooltip text is displayed for the second source.");
ok(gSources.containsValue(EXAMPLE_URL + gLabel1),
"First source url is incorrect.");
ok(gSources.containsValue(EXAMPLE_URL + gLabel2),

View File

@ -338,8 +338,9 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this._summary = $("#requests-menu-network-summary-label");
this._summary.setAttribute("value", L10N.getStr("networkMenu.empty"));
this.sortContents(this._byTiming);
this.allowFocusOnRightClick = true;
this.widget.maintainSelectionVisible = false;
this.maintainSelectionVisible = true;
this.widget.autoscrollWithAppendedItems = true;
this.widget.addEventListener("select", this._onSelect, false);
@ -471,27 +472,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
}
},
/**
* Create a new custom request form populated with the data from
* the currently selected request.
*/
cloneSelectedRequest: function() {
let selected = this.selectedItem.attachment;
// Create the element node for the network request item.
let menuView = this._createMenuView(selected.method, selected.url);
// Append a network request item to this container.
let newItem = this.push([menuView], {
attachment: Object.create(selected, {
isCustom: { value: true }
})
});
// Immediately switch to new request pane.
this.selectedItem = newItem;
},
/**
* Opens selected item in a new tab.
*/
@ -521,16 +501,37 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
});
},
/**
* Create a new custom request form populated with the data from
* the currently selected request.
*/
cloneSelectedRequest: function() {
let selected = this.selectedItem.attachment;
// Create the element node for the network request item.
let menuView = this._createMenuView(selected.method, selected.url);
// Append a network request item to this container.
let newItem = this.push([menuView], {
attachment: Object.create(selected, {
isCustom: { value: true }
})
});
// Immediately switch to new request pane.
this.selectedItem = newItem;
},
/**
* Send a new HTTP request using the data in the custom request form.
*/
sendCustomRequest: function() {
let selected = this.selectedItem.attachment;
let data = Object.create(selected);
let data = Object.create(selected, {
headers: { value: selected.requestHeaders.headers }
});
if (selected.requestHeaders) {
data.headers = selected.requestHeaders.headers;
}
if (selected.requestPostData) {
data.body = selected.requestPostData.postData.text;
}
@ -548,9 +549,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
*/
closeCustomRequest: function() {
this.remove(this.selectedItem);
NetMonitorView.Sidebar.toggle(false);
},
},
/**
* Filters all network requests in this container by a specified type.
@ -2126,26 +2126,41 @@ NetworkDetailsView.prototype = {
// Handle json, which we tentatively identify by checking the MIME type
// for "json" after any word boundary. This works for the standard
// "application/json", and also for custom types like "x-bigcorp-json".
// This should be marginally more reliable than just looking for "json".
if (/\bjson/.test(mimeType)) {
let jsonpRegex = /^[a-zA-Z0-9_$]+\(|\)$/g; // JSONP with callback.
let sanitizedJSON = aString.replace(jsonpRegex, "");
let callbackPadding = aString.match(jsonpRegex);
// Additionally, we also directly parse the response text content to
// verify whether it's json or not, to handle responses incorrectly
// labeled as text/plain instead.
let jsonMimeType, jsonObject, jsonObjectParseError;
try {
// Test the mime type *and* parse the string, because "JSONP" responses
// (json with callback) aren't actually valid json.
jsonMimeType = /\bjson/.test(mimeType);
jsonObject = JSON.parse(aString);
} catch (e) {
jsonObjectParseError = e;
}
if (jsonMimeType || jsonObject) {
// Extract the actual json substring in case this might be a "JSONP".
// This regex basically parses a function call and captures the
// function name and arguments in two separate groups.
let jsonpRegex = /^\s*([\w$]+)\s*\(\s*([^]*)\s*\)\s*;?\s*$/;
let [_, callbackPadding, jsonpString] = aString.match(jsonpRegex) || [];
// Make sure this is a valid JSON object first. If so, nicely display
// the parsing results in a variables view. Otherwise, simply show
// the contents as plain text.
try {
var jsonObject = JSON.parse(sanitizedJSON);
} catch (e) {
var parsingError = e;
if (callbackPadding && jsonpString) {
try {
jsonObject = JSON.parse(jsonpString);
} catch (e) {
jsonObjectParseError = e;
}
}
// Valid JSON.
// Valid JSON or JSONP.
if (jsonObject) {
$("#response-content-json-box").hidden = false;
let jsonScopeName = callbackPadding
? L10N.getFormatStr("jsonpScopeName", callbackPadding[0].slice(0, -1))
? L10N.getFormatStr("jsonpScopeName", callbackPadding)
: L10N.getStr("jsonScopeName");
return this._json.controller.setSingleVariable({
@ -2157,8 +2172,8 @@ NetworkDetailsView.prototype = {
else {
$("#response-content-textarea-box").hidden = false;
let infoHeader = $("#response-content-info-header");
infoHeader.setAttribute("value", parsingError);
infoHeader.setAttribute("tooltiptext", parsingError);
infoHeader.setAttribute("value", jsonObjectParseError);
infoHeader.setAttribute("tooltiptext", jsonObjectParseError);
infoHeader.hidden = false;
return NetMonitorView.editor("#response-content-textarea").then(aEditor => {
aEditor.setMode(Editor.modes.js);
@ -2328,13 +2343,9 @@ PerformanceStatisticsView.prototype = {
id: "#primed-cache-chart",
title: "charts.cacheEnabled",
data: this._sanitizeChartDataSource(aItems),
sorted: true,
totals: {
size: L10N.getStr("charts.totalSize"),
time: L10N.getStr("charts.totalTime2"),
cached: L10N.getStr("charts.totalCached"),
count: L10N.getStr("charts.totalCount")
}
strings: this._commonChartStrings,
totals: this._commonChartTotals,
sorted: true
});
window.emit(EVENTS.PRIMED_CACHE_CHART_DISPLAYED);
},
@ -2350,26 +2361,54 @@ PerformanceStatisticsView.prototype = {
id: "#empty-cache-chart",
title: "charts.cacheDisabled",
data: this._sanitizeChartDataSource(aItems, true),
sorted: true,
totals: {
size: L10N.getStr("charts.totalSize"),
time: L10N.getStr("charts.totalTime2"),
cached: L10N.getStr("charts.totalCached"),
count: L10N.getStr("charts.totalCount")
}
strings: this._commonChartStrings,
totals: this._commonChartTotals,
sorted: true
});
window.emit(EVENTS.EMPTY_CACHE_CHART_DISPLAYED);
},
/**
* Common stringifier predicates used for items and totals in both the
* "primed" and "empty" cache charts.
*/
_commonChartStrings: {
size: value => {
let string = L10N.numberWithDecimals(value / 1024, CONTENT_SIZE_DECIMALS);
return L10N.getFormatStr("charts.sizeKB", string);
},
time: value => {
let string = L10N.numberWithDecimals(value / 1000, REQUEST_TIME_DECIMALS);
return L10N.getFormatStr("charts.totalS", string);
}
},
_commonChartTotals: {
size: total => {
let string = L10N.numberWithDecimals(total / 1024, CONTENT_SIZE_DECIMALS);
return L10N.getFormatStr("charts.totalSize", string);
},
time: total => {
let seconds = total / 1000;
let string = L10N.numberWithDecimals(seconds, REQUEST_TIME_DECIMALS);
return PluralForm.get(seconds, L10N.getStr("charts.totalSeconds")).replace("#1", string);
},
cached: total => {
return L10N.getFormatStr("charts.totalCached", total);
},
count: total => {
return L10N.getFormatStr("charts.totalCount", total);
}
},
/**
* Adds a specific chart to this container.
*
* @param object
* An object containing all or some the following properties:
* - id: either "#primed-cache-chart" or "#empty-cache-chart"
* - title/data/sorted/totals: @see Chart.jsm for details
* - title/data/strings/totals/sorted: @see Chart.jsm for details
*/
_createChart: function({ id, title, data, sorted, totals }) {
_createChart: function({ id, title, data, strings, totals, sorted }) {
let container = $(id);
// Nuke all existing charts of the specified type.
@ -2382,8 +2421,9 @@ PerformanceStatisticsView.prototype = {
diameter: NETWORK_ANALYSIS_PIE_CHART_DIAMETER,
title: L10N.getStr(title),
data: data,
sorted: sorted,
totals: totals
strings: strings,
totals: totals,
sorted: sorted
});
chart.on("click", (_, item) => {
@ -2448,13 +2488,6 @@ PerformanceStatisticsView.prototype = {
data[type].count++;
}
for (let chartItem of data) {
let size = L10N.numberWithDecimals(chartItem.size / 1024, CONTENT_SIZE_DECIMALS);
let time = L10N.numberWithDecimals(chartItem.time / 1000, REQUEST_TIME_DECIMALS);
chartItem.size = L10N.getFormatStr("charts.sizeKB", size);
chartItem.time = L10N.getFormatStr("charts.totalS", time);
}
return data.filter(e => e.count > 0);
},
};

View File

@ -215,6 +215,11 @@
data-key="flash"
label="&netmonitorUI.footer.filterFlash;">
</button>
<button id="requests-menu-filter-other-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="other"
label="&netmonitorUI.footer.filterOther;">
</button>
<spacer id="requests-menu-spacer"
class="requests-menu-footer-spacer"
flex="100"/>

View File

@ -10,6 +10,7 @@ support-files =
html_json-custom-mime-test-page.html
html_json-long-test-page.html
html_json-malformed-test-page.html
html_json-text-mime-test-page.html
html_jsonp-test-page.html
html_navigate-test-page.html
html_post-data-test-page.html
@ -46,6 +47,7 @@ support-files =
[browser_net_json-long.js]
[browser_net_json-malformed.js]
[browser_net_json_custom_mime.js]
[browser_net_json_text_mime.js]
[browser_net_jsonp.js]
[browser_net_large-response.js]
[browser_net_open_request_in_tab.js]

View File

@ -9,24 +9,27 @@ function test() {
initNetMonitor(SIMPLE_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
let { document, Chart } = aMonitor.panelWin;
let { document, L10N, Chart } = aMonitor.panelWin;
let container = document.createElement("box");
let table = Chart.Table(document, {
title: "Table title",
data: [{
label1: 1,
label2: "11.1foo"
label2: 11.1
}, {
label1: 2,
label2: "12.2bar"
label2: 12.2
}, {
label1: 3,
label2: "13.3baz"
label2: 13.3
}],
strings: {
label2: (value, index) => value + ["foo", "bar", "baz"][index]
},
totals: {
label1: "Hello %S",
label2: "World %S"
label1: value => "Hello " + L10N.numberWithDecimals(value, 2),
label2: value => "World " + L10N.numberWithDecimals(value, 2)
}
});

View File

@ -17,8 +17,8 @@ function test() {
title: "Table title",
data: null,
totals: {
label1: "Hello %S",
label2: "World %S"
label1: value => "Hello " + L10N.numberWithDecimals(value, 2),
label2: value => "World " + L10N.numberWithDecimals(value, 2)
}
});

View File

@ -9,24 +9,27 @@ function test() {
initNetMonitor(SIMPLE_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
let { document, Chart } = aMonitor.panelWin;
let { document, L10N, Chart } = aMonitor.panelWin;
let container = document.createElement("box");
let chart = Chart.PieTable(document, {
title: "Table title",
data: [{
size: 1,
label: "11.1foo"
label: 11.1
}, {
size: 2,
label: "12.2bar"
label: 12.2
}, {
size: 3,
label: "13.3baz"
label: 13.3
}],
strings: {
label2: (value, index) => value + ["foo", "bar", "baz"][index]
},
totals: {
size: "Hello %S",
label: "World %S"
size: value => "Hello " + L10N.numberWithDecimals(value, 2),
label: value => "World " + L10N.numberWithDecimals(value, 2)
}
});

View File

@ -0,0 +1,81 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if JSON responses with unusal/custom MIME types are handled correctly.
*/
function test() {
initNetMonitor(JSON_TEXT_MIME_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
let { document, L10N, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
waitForNetworkEvents(aMonitor, 1).then(() => {
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
"GET", CONTENT_TYPE_SJS + "?fmt=json-text-mime", {
status: 200,
statusText: "OK",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
time: true
});
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[3]);
let RESPONSE_BODY_DISPLAYED = aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED;
waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED)
.then(testResponseTab)
.then(() => teardown(aMonitor))
.then(finish);
function testResponseTab() {
let tab = document.querySelectorAll("#details-pane tab")[3];
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
is(tab.getAttribute("selected"), "true",
"The response tab in the network details pane should be selected.");
is(tabpanel.querySelector("#response-content-info-header")
.hasAttribute("hidden"), true,
"The response info header doesn't have the intended visibility.");
is(tabpanel.querySelector("#response-content-json-box")
.hasAttribute("hidden"), false,
"The response content json box doesn't have the intended visibility.");
is(tabpanel.querySelector("#response-content-textarea-box")
.hasAttribute("hidden"), true,
"The response content textarea box doesn't have the intended visibility.");
is(tabpanel.querySelector("#response-content-image-box")
.hasAttribute("hidden"), true,
"The response content image box doesn't have the intended visibility.");
is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
"There should be 1 json scope displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".variables-view-property").length, 2,
"There should be 2 json properties displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
"The empty notice should not be displayed in this tabpanel.");
let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
is(jsonScope.querySelectorAll(".variables-view-property .name")[0].getAttribute("value"),
"greeting", "The first json property name was incorrect.");
is(jsonScope.querySelectorAll(".variables-view-property .value")[0].getAttribute("value"),
"\"Hello third-party JSON!\"", "The first json property value was incorrect.");
is(jsonScope.querySelectorAll(".variables-view-property .name")[1].getAttribute("value"),
"__proto__", "The second json property name was incorrect.");
is(jsonScope.querySelectorAll(".variables-view-property .value")[1].getAttribute("value"),
"Object", "The second json property value was incorrect.");
}
});
aDebuggee.performRequests();
});
}

View File

@ -10,11 +10,12 @@ function test() {
info("Starting test... ");
let { document, L10N, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
NetworkDetails._json.lazyEmpty = false;
waitForNetworkEvents(aMonitor, 1).then(() => {
waitForNetworkEvents(aMonitor, 2).then(() => {
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
"GET", CONTENT_TYPE_SJS + "?fmt=jsonp&jsonp=$_0123Fun", {
status: 200,
@ -24,19 +25,37 @@ function test() {
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
time: true
});
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(1),
"GET", CONTENT_TYPE_SJS + "?fmt=jsonp2&jsonp=$_4567Sad", {
status: 200,
statusText: "OK",
type: "json",
fullMimeType: "text/json; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.05),
time: true
});
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[3]);
Task.spawn(function() {
let RESPONSE_BODY_DISPLAYED = aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED;
let RESPONSE_BODY_DISPLAYED = aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED;
waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED)
.then(testResponseTab)
.then(() => teardown(aMonitor))
.then(finish);
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[3]);
function testResponseTab() {
yield waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED);
testResponseTab("$_0123Fun", "\"Hello JSONP!\"");
RequestsMenu.selectedIndex = 1;
yield waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED);
testResponseTab("$_4567Sad", "\"Hello weird JSONP!\"");
yield teardown(aMonitor);
finish();
});
function testResponseTab(aFunction, aGreeting) {
let tab = document.querySelectorAll("#details-pane tab")[3];
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
@ -66,13 +85,13 @@ function test() {
let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
is(jsonScope.querySelector(".name").getAttribute("value"),
L10N.getFormatStr("jsonpScopeName", "$_0123Fun"),
L10N.getFormatStr("jsonpScopeName", aFunction),
"The json scope doesn't have the correct title.");
is(jsonScope.querySelectorAll(".variables-view-property .name")[0].getAttribute("value"),
"greeting", "The first json property name was incorrect.");
is(jsonScope.querySelectorAll(".variables-view-property .value")[0].getAttribute("value"),
"\"Hello JSONP!\"", "The first json property value was incorrect.");
aGreeting, "The first json property value was incorrect.");
is(jsonScope.querySelectorAll(".variables-view-property .name")[1].getAttribute("value"),
"__proto__", "The second json property name was incorrect.");

View File

@ -26,6 +26,7 @@ const JSONP_URL = EXAMPLE_URL + "html_jsonp-test-page.html";
const JSON_LONG_URL = EXAMPLE_URL + "html_json-long-test-page.html";
const JSON_MALFORMED_URL = EXAMPLE_URL + "html_json-malformed-test-page.html";
const JSON_CUSTOM_MIME_URL = EXAMPLE_URL + "html_json-custom-mime-test-page.html";
const JSON_TEXT_MIME_URL = EXAMPLE_URL + "html_json-text-mime-test-page.html";
const SORTING_URL = EXAMPLE_URL + "html_sorting-test-page.html";
const FILTERING_URL = EXAMPLE_URL + "html_filter-test-page.html";
const INFINITE_GET_URL = EXAMPLE_URL + "html_infinite-get-page.html";

View File

@ -0,0 +1,35 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Network Monitor test page</title>
</head>
<body>
<p>JSON text test</p>
<script type="text/javascript">
function get(aAddress, aCallback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", aAddress, true);
xhr.onreadystatechange = function() {
if (this.readyState == this.DONE) {
aCallback();
}
};
xhr.send(null);
}
function performRequests() {
get("sjs_content-type-test-server.sjs?fmt=json-text-mime", function() {
// Done.
});
}
</script>
</body>
</html>

View File

@ -26,7 +26,9 @@
function performRequests() {
get("sjs_content-type-test-server.sjs?fmt=jsonp&jsonp=$_0123Fun", function() {
// Done.
get("sjs_content-type-test-server.sjs?fmt=jsonp2&jsonp=$_4567Sad", function() {
// Done.
});
});
}
</script>

View File

@ -95,6 +95,15 @@ function handleRequest(request, response) {
response.finish();
break;
}
case "jsonp2": {
let fun = params.filter((s) => s.contains("jsonp="))[0].split("=")[1];
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "text/json; charset=utf-8", false);
maybeMakeCached();
response.write(" " + fun + " ( { \"greeting\": \"Hello weird JSONP!\" } ) ; ");
response.finish();
break;
}
case "json-long": {
let str = "{ \"greeting\": \"Hello long string JSON!\" },";
response.setStatusLine(request.httpVersion, status, "OK");
@ -112,6 +121,14 @@ function handleRequest(request, response) {
response.finish();
break;
}
case "json-text-mime": {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "text/plain; charset=utf-8", false);
maybeMakeCached();
response.write("{ \"greeting\": \"Hello third-party JSON!\" }");
response.finish();
break;
}
case "json-custom-mime": {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "text/x-bigcorp-json; charset=utf-8", false);

View File

@ -96,18 +96,19 @@ function PieTableChart(node, pie, table) {
* - data: an array of items used to display each slice in the pie
* and each row in the table;
* @see `createPieChart` and `createTableChart` for details.
* - strings: @see `createTableChart` for details.
* - totals: @see `createTableChart` for details.
* - sorted: a flag specifying if the `data` should be sorted
* ascending by `size`.
* - totals: @see `createTableChart` for details.
* @return PieTableChart
* A pie+table chart proxy instance, which emits the following events:
* - "mouseenter", when the mouse enters a slice or a row
* - "mouseleave", when the mouse leaves a slice or a row
* - "click", when the mouse enters a slice or a row
*/
function createPieTableChart(document, { sorted, title, diameter, data, totals }) {
function createPieTableChart(document, { title, diameter, data, strings, totals, sorted }) {
if (sorted) {
data = data.slice().sort((a, b) => +(parseFloat(a.size) < parseFloat(b.size)));
data = data.slice().sort((a, b) => +(a.size < b.size));
}
let pie = Chart.Pie(document, {
@ -118,6 +119,7 @@ function createPieTableChart(document, { sorted, title, diameter, data, totals }
let table = Chart.Table(document, {
title: title,
data: data,
strings: strings,
totals: totals
});
@ -202,7 +204,7 @@ function createPieChart(document, { data, width, height, centerX, centerY, radiu
let isPlaceholder = false;
// Filter out very small sizes, as they'll just render invisible slices.
data = data ? data.filter(e => parseFloat(e.size) > EPSILON) : null;
data = data ? data.filter(e => e.size > EPSILON) : null;
// If there's no data available, display an empty placeholder.
if (!data || !data.length) {
@ -222,10 +224,10 @@ function createPieChart(document, { data, width, height, centerX, centerY, radiu
let proxy = new PieChart(container);
let total = data.reduce((acc, e) => acc + parseFloat(e.size), 0);
let angles = data.map(e => parseFloat(e.size) / total * (TAU - EPSILON));
let largest = data.reduce((a, b) => parseFloat(a.size) > parseFloat(b.size) ? a : b);
let smallest = data.reduce((a, b) => parseFloat(a.size) < parseFloat(b.size) ? a : b);
let total = data.reduce((acc, e) => acc + e.size, 0);
let angles = data.map(e => e.size / total * (TAU - EPSILON));
let largest = data.reduce((a, b) => a.size > b.size ? a : b);
let smallest = data.reduce((a, b) => a.size < b.size ? a : b);
let textDistance = radius / NAMED_SLICE_TEXT_DISTANCE_RATIO;
let translateDistance = radius / HOVERED_SLICE_TRANSLATE_DISTANCE_RATIO;
@ -307,19 +309,25 @@ function createPieChart(document, { data, width, height, centerX, centerY, radiu
* should be objects representing columns, for which the
* properties' values will be displayed in each cell of a row.
* e.g: [{
* size: 1,
* label2: "1foo",
* label3: "2yolo"
* label1: 1,
* label2: 3,
* label3: "foo"
* }, {
* size: 2,
* label2: "3bar",
* label3: "4swag"
* label1: 4,
* label2: 6,
* label3: "bar
* }];
* - strings: an object specifying for which rows in the `data` array
* their cell values should be stringified and localized
* based on a predicate function;
* e.g: {
* label1: value => l10n.getFormatStr("...", value)
* }
* - totals: an object specifying for which rows in the `data` array
* the sum of their cells is to be displayed in the chart;
* e.g: {
* label1: "Total size: %S",
* label3: "Total lolz: %S"
* label1: total => l10n.getFormatStr("...", total), // 5
* label2: total => l10n.getFormatStr("...", total), // 9
* }
* @return TableChart
* A table chart proxy instance, which emits the following events:
@ -327,7 +335,9 @@ function createPieChart(document, { data, width, height, centerX, centerY, radiu
* - "mouseleave", when the mouse leaves a row
* - "click", when the mouse clicks a row
*/
function createTableChart(document, { data, totals, title }) {
function createTableChart(document, { title, data, strings, totals }) {
strings = strings || {};
totals = totals || {};
let isPlaceholder = false;
// If there's no data available, display an empty placeholder.
@ -365,10 +375,12 @@ function createTableChart(document, { data, totals, title }) {
rowNode.appendChild(boxNode);
for (let [key, value] in Iterator(rowInfo)) {
let index = data.indexOf(rowInfo);
let stringified = strings[key] ? strings[key](value, index) : value;
let labelNode = document.createElement("label");
labelNode.className = "plain table-chart-row-label";
labelNode.setAttribute("name", key);
labelNode.setAttribute("value", value);
labelNode.setAttribute("value", stringified);
rowNode.appendChild(labelNode);
}
@ -380,13 +392,13 @@ function createTableChart(document, { data, totals, title }) {
let totalsNode = document.createElement("vbox");
totalsNode.className = "table-chart-totals";
for (let [key, value] in Iterator(totals || {})) {
let total = data.reduce((acc, e) => acc + parseFloat(e[key]), 0);
let formatted = !isNaN(total) ? L10N.numberWithDecimals(total, 2) : 0;
for (let [key, value] in Iterator(totals)) {
let total = data.reduce((acc, e) => acc + e[key], 0);
let stringified = totals[key] ? totals[key](total || 0) : total;
let labelNode = document.createElement("label");
labelNode.className = "plain table-chart-summary-label";
labelNode.setAttribute("name", key);
labelNode.setAttribute("value", value.replace("%S", formatted));
labelNode.setAttribute("value", stringified);
totalsNode.appendChild(labelNode);
}

View File

@ -423,7 +423,6 @@ function SideMenuGroup(aWidget, aName, aOptions={}) {
let target = this._target = this.document.createElement("vbox");
target.className = "side-menu-widget-group";
target.setAttribute("name", aName);
target.setAttribute("tooltiptext", aName);
let list = this._list = this.document.createElement("vbox");
list.className = "side-menu-widget-group-list";

View File

@ -166,9 +166,11 @@ charts.cacheDisabled=Empty cache
# in the performance analysis view for total requests size, in kilobytes.
charts.totalSize=Size: %S KB
# LOCALIZATION NOTE (charts.totalTime2): This is the label displayed
# in the performance analysis view for total requests time, in seconds.
charts.totalTime2=Time: %S seconds
# LOCALIZATION NOTE (charts.totalSeconds): Semi-colon list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# This is the label displayed in the performance analysis view for the
# total requests time, in seconds.
charts.totalSeconds=Time: #1 second;Time: #1 seconds
# LOCALIZATION NOTE (charts.totalCached): This is the label displayed
# in the performance analysis view for total cached responses.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -3,15 +3,6 @@
* 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/. */
#inspector-inspect-toolbutton {
list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
#inspector-inspect-toolbutton[checked=true] {
-moz-image-region: rect(0px 32px 16px 16px);
}
#inspector-searchbox {
transition-property: max-width, -moz-padding-end, -moz-padding-start;
transition-duration: 250ms;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

View File

@ -23,11 +23,6 @@ browser.jar:
* skin/classic/browser/browser.css
* skin/classic/browser/browser-lightweightTheme.css
skin/classic/browser/click-to-play-warning-stripes.png
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
skin/classic/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
* skin/classic/browser/engineManager.css
skin/classic/browser/fullscreen-darknoise.png
skin/classic/browser/Geolocation-16.png
@ -73,7 +68,13 @@ browser.jar:
skin/classic/browser/webRTC-shareDevice-16.png
skin/classic/browser/webRTC-shareDevice-64.png
skin/classic/browser/webRTC-sharingDevice-16.png
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
skin/classic/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
* skin/classic/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
skin/classic/browser/customizableui/subView-arrow-back-inverted.png (../shared/customizableui/subView-arrow-back-inverted.png)
skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
skin/classic/browser/downloads/contentAreaDownloadsView.css (downloads/contentAreaDownloadsView.css)
@ -190,7 +191,10 @@ browser.jar:
* skin/classic/browser/devtools/profiler.css (devtools/profiler.css)
* skin/classic/browser/devtools/netmonitor.css (devtools/netmonitor.css)
* skin/classic/browser/devtools/scratchpad.css (devtools/scratchpad.css)
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
skin/classic/browser/devtools/magnifying-glass.png (../shared/devtools/images/magnifying-glass.png)
skin/classic/browser/devtools/magnifying-glass@2x.png (../shared/devtools/images/magnifying-glass@2x.png)
skin/classic/browser/devtools/magnifying-glass-light.png (../shared/devtools/images/magnifying-glass-light.png)
skin/classic/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
skin/classic/browser/devtools/option-icon.png (../shared/devtools/images/option-icon.png)
skin/classic/browser/devtools/itemToggle.png (../shared/devtools/images/itemToggle.png)
skin/classic/browser/devtools/itemToggle-light.png (../shared/devtools/images/itemToggle-light.png)
@ -200,7 +204,6 @@ browser.jar:
skin/classic/browser/devtools/itemArrow-ltr.svg (../shared/devtools/images/itemArrow-ltr.svg)
skin/classic/browser/devtools/background-noise-toolbar.png (devtools/background-noise-toolbar.png)
skin/classic/browser/devtools/noise.png (devtools/noise.png)
skin/classic/browser/devtools/inspect-button.png (devtools/inspect-button.png)
skin/classic/browser/devtools/dropmarker.png (devtools/dropmarker.png)
skin/classic/browser/devtools/layout-background-grid.png (devtools/layout-background-grid.png)
skin/classic/browser/devtools/layoutview.css (devtools/layoutview.css)

View File

@ -1024,11 +1024,19 @@ toolbar .toolbarbutton-1:not([type="menu-button"]),
-moz-image-region: rect(0px, 320px, 64px, 256px);
}
#bookmarks-menu-button[cui-areatype="menu-panel"].panel-multiview-anchor {
-moz-image-region: rect(64px, 320px, 128px, 256px);
}
#history-panelmenu[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #history-panelmenu {
-moz-image-region: rect(0px, 448px, 64px, 384px);
}
#history-panelmenu[cui-areatype="menu-panel"].panel-multiview-anchor {
-moz-image-region: rect(64px, 448px, 128px, 384px);
}
#downloads-button[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #downloads-button {
-moz-image-region: rect(0px, 512px, 64px, 448px);
@ -1069,6 +1077,10 @@ toolbar .toolbarbutton-1:not([type="menu-button"]),
-moz-image-region: rect(0, 960px, 64px, 896px);
}
#characterencoding-button[cui-areatype="menu-panel"].panel-multiview-anchor {
-moz-image-region: rect(64px, 960px, 128px, 896px);
}
#new-window-button[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #new-window-button {
-moz-image-region: rect(0px, 1024px, 64px, 960px);
@ -1109,6 +1121,10 @@ toolbar .toolbarbutton-1:not([type="menu-button"]),
-moz-image-region: rect(0px, 1472px, 64px, 1408px);
}
#developer-button[cui-areatype="menu-panel"].panel-multiview-anchor {
-moz-image-region: rect(64px, 1472px, 128px, 1408px);
}
#preferences-button[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #preferences-button {
-moz-image-region: rect(0px, 1536px, 64px, 1472px);

View File

@ -5,6 +5,12 @@
%include ../../shared/customizableui/panelUIOverlay.inc.css
@media (min-resolution: 2dppx) {
toolbarbutton.panel-multiview-anchor {
background-image: url(chrome://browser/skin/customizableui/subView-arrow-back-inverted@2x.png),
linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0));
background-size: 16px;
}
#PanelUI-customize {
list-style-image: url(chrome://browser/skin/menuPanel-customize@2x.png);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -6,15 +6,6 @@
%include ../shared.inc
%filter substitution
#inspector-inspect-toolbutton {
list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
#inspector-inspect-toolbutton[checked=true] {
-moz-image-region: rect(0px 32px 16px 16px);
}
#inspector-toolbar {
padding-top: 4px;
padding-bottom: 4px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

View File

@ -23,13 +23,6 @@ browser.jar:
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/browser-lightweightTheme.css
skin/classic/browser/click-to-play-warning-stripes.png
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/browser/customizableui/customize-titleBar-toggle.png (customizableui/customize-titleBar-toggle.png)
skin/classic/browser/customizableui/customize-titleBar-toggle@2x.png (customizableui/customize-titleBar-toggle@2x.png)
skin/classic/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
skin/classic/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-darknoise.png
skin/classic/browser/Geolocation-16.png
@ -120,6 +113,15 @@ browser.jar:
skin/classic/browser/webRTC-shareDevice-64@2x.png
skin/classic/browser/webRTC-sharingDevice-16.png
skin/classic/browser/webRTC-sharingDevice-16@2x.png
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/browser/customizableui/customize-titleBar-toggle.png (customizableui/customize-titleBar-toggle.png)
skin/classic/browser/customizableui/customize-titleBar-toggle@2x.png (customizableui/customize-titleBar-toggle@2x.png)
skin/classic/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
skin/classic/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
skin/classic/browser/customizableui/subView-arrow-back-inverted.png (../shared/customizableui/subView-arrow-back-inverted.png)
skin/classic/browser/customizableui/subView-arrow-back-inverted@2x.png (../shared/customizableui/subView-arrow-back-inverted@2x.png)
* skin/classic/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
@ -298,7 +300,10 @@ browser.jar:
* skin/classic/browser/devtools/profiler.css (devtools/profiler.css)
* skin/classic/browser/devtools/netmonitor.css (devtools/netmonitor.css)
* skin/classic/browser/devtools/scratchpad.css (devtools/scratchpad.css)
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
skin/classic/browser/devtools/magnifying-glass.png (../shared/devtools/images/magnifying-glass.png)
skin/classic/browser/devtools/magnifying-glass@2x.png (../shared/devtools/images/magnifying-glass@2x.png)
skin/classic/browser/devtools/magnifying-glass-light.png (../shared/devtools/images/magnifying-glass-light.png)
skin/classic/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
skin/classic/browser/devtools/option-icon.png (../shared/devtools/images/option-icon.png)
skin/classic/browser/devtools/itemToggle.png (../shared/devtools/images/itemToggle.png)
skin/classic/browser/devtools/itemToggle-light.png (../shared/devtools/images/itemToggle-light.png)
@ -308,7 +313,6 @@ browser.jar:
skin/classic/browser/devtools/itemArrow-ltr.svg (../shared/devtools/images/itemArrow-ltr.svg)
skin/classic/browser/devtools/background-noise-toolbar.png (devtools/background-noise-toolbar.png)
skin/classic/browser/devtools/noise.png (devtools/noise.png)
skin/classic/browser/devtools/inspect-button.png (devtools/inspect-button.png)
skin/classic/browser/devtools/dropmarker.png (devtools/dropmarker.png)
skin/classic/browser/devtools/layout-background-grid.png (devtools/layout-background-grid.png)
skin/classic/browser/devtools/layoutview.css (devtools/layoutview.css)

View File

@ -523,12 +523,22 @@ panelview toolbarseparator,
height: 16px;
}
#PanelUI-footer.panel-multiview-anchor,
#PanelUI-footer.panel-multiview-anchor > #PanelUI-help,
#PanelUI-footer > #PanelUI-footer-inner.panel-multiview-anchor,
toolbarbutton.panel-multiview-anchor {
background-color: Highlight;
background-image: linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0));
background-repeat: repeat-x;
}
toolbarbutton.panel-multiview-anchor {
background-image: url(chrome://browser/skin/customizableui/subView-arrow-back-inverted.png),
linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0));
background-position: right 5px center;
background-repeat: no-repeat;
}
#PanelUI-footer > #PanelUI-footer-inner.panel-multiview-anchor,
toolbarbutton.panel-multiview-anchor,
toolbarbutton.panel-multiview-anchor > .toolbarbutton-menubutton-button {
color: HighlightText;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

View File

@ -217,12 +217,30 @@
padding-bottom: 3px;
-moz-padding-start: 22px;
-moz-padding-end: 12px;
background-image: url(magnifying-glass.png);
background-position: 8px center;
background-size: 11px 11px;
background-repeat: no-repeat;
font-size: inherit;
}
.theme-dark .devtools-searchinput {
background-image: url(magnifying-glass.png);
}
.theme-light .devtools-searchinput {
background-image: url(magnifying-glass-light.png);
}
@media (min-resolution: 2dppx) {
.theme-dark .devtools-searchinput {
background-image: url(magnifying-glass@2x.png);
}
.theme-light .devtools-searchinput {
background-image: url(magnifying-glass-light@2x.png);
}
}
.devtools-searchinput:-moz-locale-dir(rtl) {
background-position: calc(100% - 8px) center;
}

View File

@ -15,11 +15,19 @@ toolbarpaletteitem[place="palette"] > #bookmarks-menu-button {
-moz-image-region: rect(0px, 160px, 32px, 128px);
}
#bookmarks-menu-button[cui-areatype="menu-panel"].panel-multiview-anchor {
-moz-image-region: rect(32px, 160px, 64px, 128px);
}
#history-panelmenu[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #history-panelmenu {
-moz-image-region: rect(0px, 224px, 32px, 192px);
}
#history-panelmenu[cui-areatype="menu-panel"].panel-multiview-anchor {
-moz-image-region: rect(32px, 224px, 64px, 192px);
}
#downloads-button[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #downloads-button {
-moz-image-region: rect(0px, 256px, 32px, 224px);
@ -60,6 +68,10 @@ toolbarpaletteitem[place="palette"] > #characterencoding-button {
-moz-image-region: rect(0px, 480px, 32px, 448px);
}
#characterencoding-button[cui-areatype="menu-panel"].panel-multiview-anchor {
-moz-image-region: rect(32px, 480px, 64px, 448px);
}
#new-window-button[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #new-window-button {
-moz-image-region: rect(0px, 512px, 32px, 480px);
@ -100,6 +112,10 @@ toolbarpaletteitem[place="palette"] > #developer-button {
-moz-image-region: rect(0px, 736px, 32px, 704px);
}
#developer-button[cui-areatype="menu-panel"].panel-multiview-anchor {
-moz-image-region: rect(32px, 736px, 64px, 704px);
}
#preferences-button[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #preferences-button {
-moz-image-region: rect(0px, 768px, 32px, 736px);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -3,15 +3,6 @@
* 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/. */
#inspector-inspect-toolbutton {
list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
#inspector-inspect-toolbutton[checked=true] {
-moz-image-region: rect(0px 32px 16px 16px);
}
#inspector-searchbox {
transition-property: max-width, -moz-padding-end, -moz-padding-start;
transition-duration: 250ms;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -25,12 +25,6 @@ browser.jar:
* skin/classic/browser/browser.css
* skin/classic/browser/browser-lightweightTheme.css
skin/classic/browser/click-to-play-warning-stripes.png
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
skin/classic/browser/customizableui/customize-titleBar-toggle.png (customizableui/customize-titleBar-toggle.png)
skin/classic/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
* skin/classic/browser/engineManager.css
skin/classic/browser/fullscreen-darknoise.png
skin/classic/browser/Geolocation-16.png
@ -92,7 +86,14 @@ browser.jar:
skin/classic/browser/webRTC-shareDevice-16.png
skin/classic/browser/webRTC-shareDevice-64.png
skin/classic/browser/webRTC-sharingDevice-16.png
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
skin/classic/browser/customizableui/customize-titleBar-toggle.png (customizableui/customize-titleBar-toggle.png)
skin/classic/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
* skin/classic/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
skin/classic/browser/customizableui/subView-arrow-back-inverted.png (../shared/customizableui/subView-arrow-back-inverted.png)
* skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
skin/classic/browser/downloads/contentAreaDownloadsView.css (downloads/contentAreaDownloadsView.css)
@ -219,17 +220,19 @@ browser.jar:
* skin/classic/browser/devtools/profiler.css (devtools/profiler.css)
* skin/classic/browser/devtools/netmonitor.css (devtools/netmonitor.css)
* skin/classic/browser/devtools/scratchpad.css (devtools/scratchpad.css)
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
skin/classic/browser/devtools/magnifying-glass.png (../shared/devtools/images/magnifying-glass.png)
skin/classic/browser/devtools/magnifying-glass@2x.png (../shared/devtools/images/magnifying-glass@2x.png)
skin/classic/browser/devtools/magnifying-glass-light.png (../shared/devtools/images/magnifying-glass-light.png)
skin/classic/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
skin/classic/browser/devtools/option-icon.png (../shared/devtools/images/option-icon.png)
skin/classic/browser/devtools/itemToggle.png (../shared/devtools/images/itemToggle.png)
skin/classic/browser/devtools/itemToggle-light.png (../shared/devtools/images/itemToggle-light.png)
skin/classic/browser/devtools/itemArrow-dark-rtl.png (../shared/devtools/images/itemArrow-dark-rtl.png)
skin/classic/browser/devtools/itemArrow-dark-ltr.png (../shared/devtools/images/itemArrow-dark-ltr.png)
skin/classic/browser/devtools/itemArrow-rtl.png (../shared/devtools/images/itemArrow-rtl.svg)
skin/classic/browser/devtools/itemArrow-ltr.png (../shared/devtools/images/itemArrow-ltr.svg)
skin/classic/browser/devtools/itemArrow-rtl.svg (../shared/devtools/images/itemArrow-rtl.svg)
skin/classic/browser/devtools/itemArrow-ltr.svg (../shared/devtools/images/itemArrow-ltr.svg)
skin/classic/browser/devtools/background-noise-toolbar.png (devtools/background-noise-toolbar.png)
skin/classic/browser/devtools/noise.png (devtools/noise.png)
skin/classic/browser/devtools/inspect-button.png (devtools/inspect-button.png)
skin/classic/browser/devtools/dropmarker.png (devtools/dropmarker.png)
skin/classic/browser/devtools/layout-background-grid.png (devtools/layout-background-grid.png)
skin/classic/browser/devtools/layoutview.css (devtools/layoutview.css)
@ -335,12 +338,6 @@ browser.jar:
* skin/classic/aero/browser/browser.css (browser-aero.css)
* skin/classic/aero/browser/browser-lightweightTheme.css
skin/classic/aero/browser/click-to-play-warning-stripes.png
skin/classic/aero/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/aero/browser/customizableui/customize-titleBar-toggle.png (customizableui/customize-titleBar-toggle.png)
skin/classic/aero/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
skin/classic/aero/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/aero/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/aero/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
* skin/classic/aero/browser/engineManager.css
skin/classic/aero/browser/fullscreen-darknoise.png
skin/classic/aero/browser/Geolocation-16.png
@ -401,7 +398,14 @@ browser.jar:
skin/classic/aero/browser/webRTC-shareDevice-16.png
skin/classic/aero/browser/webRTC-shareDevice-64.png
skin/classic/aero/browser/webRTC-sharingDevice-16.png
skin/classic/aero/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/aero/browser/customizableui/customize-titleBar-toggle.png (customizableui/customize-titleBar-toggle.png)
skin/classic/aero/browser/customizableui/customizeFavicon.ico (../shared/customizableui/customizeFavicon.ico)
skin/classic/aero/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/aero/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/aero/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
* skin/classic/aero/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
skin/classic/aero/browser/customizableui/subView-arrow-back-inverted.png (../shared/customizableui/subView-arrow-back-inverted.png)
* skin/classic/aero/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay-aero.css)
skin/classic/aero/browser/downloads/buttons.png (downloads/buttons-aero.png)
skin/classic/aero/browser/downloads/contentAreaDownloadsView.css (downloads/contentAreaDownloadsView.css)
@ -429,6 +433,7 @@ browser.jar:
skin/classic/aero/browser/places/bookmarksMenu.png (places/bookmarksMenu-aero.png)
skin/classic/aero/browser/places/bookmarksToolbar.png (places/bookmarksToolbar-aero.png)
skin/classic/aero/browser/places/bookmarksToolbar-menuPanel.png (places/bookmarksToolbar-menuPanel-aero.png)
skin/classic/aero/browser/places/bookmarks-notification-finish.png (places/bookmarks-notification-finish.png)
skin/classic/aero/browser/places/calendar.png (places/calendar-aero.png)
skin/classic/aero/browser/places/toolbarDropMarker.png (places/toolbarDropMarker-aero.png)
skin/classic/aero/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
@ -527,7 +532,10 @@ browser.jar:
* skin/classic/aero/browser/devtools/profiler.css (devtools/profiler.css)
* skin/classic/aero/browser/devtools/netmonitor.css (devtools/netmonitor.css)
* skin/classic/aero/browser/devtools/scratchpad.css (devtools/scratchpad.css)
skin/classic/aero/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
skin/classic/aero/browser/devtools/magnifying-glass.png (../shared/devtools/images/magnifying-glass.png)
skin/classic/aero/browser/devtools/magnifying-glass@2x.png (../shared/devtools/images/magnifying-glass@2x.png)
skin/classic/aero/browser/devtools/magnifying-glass-light.png (../shared/devtools/images/magnifying-glass-light.png)
skin/classic/aero/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
skin/classic/aero/browser/devtools/option-icon.png (../shared/devtools/images/option-icon.png)
skin/classic/aero/browser/devtools/itemToggle.png (../shared/devtools/images/itemToggle.png)
skin/classic/aero/browser/devtools/itemToggle-light.png (../shared/devtools/images/itemToggle-light.png)
@ -537,7 +545,6 @@ browser.jar:
skin/classic/aero/browser/devtools/itemArrow-ltr.png (../shared/devtools/images/itemArrow-ltr.svg)
skin/classic/aero/browser/devtools/background-noise-toolbar.png (devtools/background-noise-toolbar.png)
skin/classic/aero/browser/devtools/noise.png (devtools/noise.png)
skin/classic/aero/browser/devtools/inspect-button.png (devtools/inspect-button.png)
skin/classic/aero/browser/devtools/dropmarker.png (devtools/dropmarker.png)
skin/classic/aero/browser/devtools/layout-background-grid.png (devtools/layout-background-grid.png)
skin/classic/aero/browser/devtools/layoutview.css (devtools/layoutview.css)

View File

@ -572,6 +572,8 @@ public abstract class GeckoApp
} else if (event.equals("Reader:FaviconRequest")) {
final String url = message.getString("url");
handleFaviconRequest(url);
} else if (event.equals("Gecko:DelayedStartup")) {
ThreadUtils.postToBackgroundThread(new UninstallListener.DelayedStartupTask(this));
} else if (event.equals("Gecko:Ready")) {
mGeckoReadyStartupTimer.stop();
geckoConnected();
@ -1325,11 +1327,6 @@ public abstract class GeckoApp
GeckoApp.this.onLocaleReady(uiLocale);
}
});
// Perform webapp uninstalls as appropiate.
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
UninstallListener.initUninstallPackageScan(getApplicationContext());
}
}
});
@ -1534,6 +1531,7 @@ public abstract class GeckoApp
registerEventListener("Menu:Remove");
registerEventListener("Menu:Update");
registerEventListener("Gecko:Ready");
registerEventListener("Gecko:DelayedStartup");
registerEventListener("Toast:Show");
registerEventListener("DOMFullScreen:Start");
registerEventListener("DOMFullScreen:Stop");
@ -2063,6 +2061,7 @@ public abstract class GeckoApp
unregisterEventListener("Menu:Remove");
unregisterEventListener("Menu:Update");
unregisterEventListener("Gecko:Ready");
unregisterEventListener("Gecko:DelayedStartup");
unregisterEventListener("Toast:Show");
unregisterEventListener("DOMFullScreen:Start");
unregisterEventListener("DOMFullScreen:Stop");

View File

@ -362,6 +362,7 @@ gbjar.sources += [
'widget/FlowLayout.java',
'widget/GeckoActionProvider.java',
'widget/GeckoPopupMenu.java',
'widget/GeckoViewFlipper.java',
'widget/IconTabWidget.java',
'widget/SquaredImageView.java',
'widget/TabRow.java',

View File

@ -75,7 +75,7 @@
the root view, BrowserToolbar should be specified as low in the
view hierarchy as possible. -->
<ViewFlipper android:id="@id/browser_actionbar"
<org.mozilla.gecko.widget.GeckoViewFlipper android:id="@id/browser_actionbar"
android:layout_width="fill_parent"
android:layout_height="@dimen/browser_toolbar_height"
android:clickable="true"
@ -95,7 +95,7 @@
android:layout_width="fill_parent"
style="@style/GeckoActionBar"/>
</ViewFlipper>
</org.mozilla.gecko.widget.GeckoViewFlipper>
</view>

View File

@ -29,6 +29,9 @@ import java.util.HashMap;
* provide a framework to improve upon the issues discovered with the previous BaseTest
* implementation by providing simple test authorship and framework extension, consistency,
* and reliability.
*
* For documentation on writing tests and extending the framework, see
* https://wiki.mozilla.org/Mobile/Fennec/Android/UITest
*/
abstract class UITest extends ActivityInstrumentationTestCase2<Activity>
implements UITestContext {

View File

@ -12,8 +12,8 @@ import android.os.Build;
import android.util.Log;
import android.view.ViewConfiguration;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -28,6 +28,10 @@ public final class HardwareUtils {
// where we can't depend on Gecko to be up and running e.g. show/hide
// reading list capabilities in HomePager.
private static final int LOW_MEMORY_THRESHOLD_MB = 384;
// Number of bytes of /proc/meminfo to read in one go.
private static final int MEMINFO_BUFFER_SIZE_BYTES = 256;
private static volatile int sTotalRAM = -1;
private static Context sContext;
@ -89,9 +93,58 @@ public final class HardwareUtils {
return sHasMenuButton;
}
/**
* Helper functions used to extract key/value data from /proc/meminfo
* Pulled from:
* http://androidxref.com/4.2_r1/xref/frameworks/base/core/java/com/android/internal/util/MemInfoReader.java
*/
private static boolean matchMemText(byte[] buffer, int index, int bufferLength, byte[] text) {
final int N = text.length;
if ((index + N) >= bufferLength) {
return false;
}
for (int i = 0; i < N; i++) {
if (buffer[index + i] != text[i]) {
return false;
}
}
return true;
}
/**
* Parses a line like:
*
* MemTotal: 1605324 kB
*
* into 1605324.
*
* @return the first uninterrupted sequence of digits following the
* specified index, parsed as an integer value in KB.
*/
private static int extractMemValue(byte[] buffer, int offset, int length) {
if (offset >= length) {
return 0;
}
while (offset < length && buffer[offset] != '\n') {
if (buffer[offset] >= '0' && buffer[offset] <= '9') {
int start = offset++;
while (offset < length &&
buffer[offset] >= '0' &&
buffer[offset] <= '9') {
++offset;
}
return Integer.parseInt(new String(buffer, start, offset - start), 10);
}
++offset;
}
return 0;
}
/**
* Fetch the total memory of the device in MB by parsing /proc/meminfo.
*
*
* Of course, Android doesn't have a neat and tidy way to find total
* RAM, so we do it by parsing /proc/meminfo.
*
@ -102,48 +155,33 @@ public final class HardwareUtils {
return sTotalRAM;
}
// This is the string "MemTotal" that we're searching for in the buffer.
final byte[] MEMTOTAL = {'M', 'e', 'm', 'T', 'o', 't', 'a', 'l'};
try {
RandomAccessFile reader = new RandomAccessFile("/proc/meminfo", "r");
final byte[] buffer = new byte[MEMINFO_BUFFER_SIZE_BYTES];
final FileInputStream is = new FileInputStream("/proc/meminfo");
try {
// MemTotal will be one of the first three lines.
int i = 0;
String memTotal = null;
while (i++ < 3) {
memTotal = reader.readLine();
if (memTotal == null ||
memTotal.startsWith("MemTotal: ")) {
break;
}
memTotal = null;
}
final int length = is.read(buffer);
if (memTotal == null) {
return sTotalRAM = 0;
}
// Parse a line like this:
// MemTotal: 1605324 kB
Matcher m = Pattern.compile("^MemTotal:\\s+([0-9]+) kB\\s*$")
.matcher(memTotal);
if (m.matches()) {
String kb = m.group(1);
if (kb != null) {
sTotalRAM = (Integer.parseInt(kb) / 1024);
for (int i = 0; i < length; i++) {
if (matchMemText(buffer, i, length, MEMTOTAL)) {
i += 8;
sTotalRAM = extractMemValue(buffer, i, length) / 1024;
Log.d(LOGTAG, "System memory: " + sTotalRAM + "MB.");
return sTotalRAM;
}
}
} finally {
is.close();
}
Log.w(LOGTAG, "Got unexpected MemTotal line: " + memTotal);
return sTotalRAM = 0;
} finally {
reader.close();
}
} catch (FileNotFoundException f) {
return sTotalRAM = 0;
} catch (IOException e) {
return sTotalRAM = 0;
}
Log.w(LOGTAG, "Did not find MemTotal line in /proc/meminfo.");
return sTotalRAM = 0;
} catch (FileNotFoundException f) {
return sTotalRAM = 0;
} catch (IOException e) {
return sTotalRAM = 0;
}
}
public static boolean isLowMemoryPlatform() {

View File

@ -5,8 +5,11 @@
package org.mozilla.gecko.webapp;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.util.ThreadUtils;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -23,6 +26,7 @@ import android.content.pm.PackageManager;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.ArrayList;
@ -91,4 +95,20 @@ public class UninstallListener extends BroadcastReceiver {
}
}
}
public static class DelayedStartupTask implements Runnable {
private GeckoApp mApp;
public DelayedStartupTask(GeckoApp app) {
mApp = app;
}
@Override
public void run() {
// Perform webapp uninstalls as appropiate.
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
UninstallListener.initUninstallPackageScan(mApp.getApplicationContext());
}
}
}
}

View File

@ -0,0 +1,47 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko.widget;
import org.mozilla.gecko.animation.ViewHelper;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.view.MotionEvent;
import android.widget.ViewFlipper;
import android.util.Log;
import android.util.AttributeSet;
/* This extends the normal ViewFlipper only to fix bug 956075 on < 3.0 devices.
* i.e. It ignores touch events on the ViewFlipper when its hidden. */
public class GeckoViewFlipper extends ViewFlipper {
private static final String LOGTAG = "GeckoViewFlipper";
private Rect mRect = new Rect();
public GeckoViewFlipper(Context context) {
super(context);
}
public GeckoViewFlipper(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (Build.VERSION.SDK_INT < 11) {
// Fix bug 956075. Don't allow touching this View if its hidden.
getHitRect(mRect);
mRect.offset((int) ViewHelper.getTranslationX(this), (int) ViewHelper.getTranslationY(this));
if (!mRect.contains((int) ev.getX(), (int) ev.getY())) {
return false;
}
}
return super.dispatchTouchEvent(ev);
}
}

View File

@ -57,9 +57,21 @@ function truncate(text, newLength = kTruncateLength) {
}
function getMessage(error) {
return truncate(JSON.stringify(error.actual, replacer)) + " " +
(error.operator ? error.operator + " " : "") +
truncate(JSON.stringify(error.expected, replacer));
let actual, expected;
// Wrap calls to JSON.stringify in try...catch blocks, as they may throw. If
// so, fall back to toString().
try {
actual = JSON.stringify(error.actual, replacer);
} catch (ex) {
actual = Object.prototype.toString.call(error.actual);
}
try {
expected = JSON.stringify(error.expected, replacer);
} catch (ex) {
expected = Object.prototype.toString.call(error.expected);
}
return truncate(actual) + " " + (error.operator ? error.operator + " " : "") +
truncate(expected);
}
/**

View File

@ -288,4 +288,15 @@ function run_test() {
deepEqual(/a/igm, /a/igm, "deep equal should work on RegExp");
deepEqual({a: 4, b: "1"}, {b: "1", a: 4}, "deep equal should work on regular Object");
deepEqual(a1, a2, "deep equal should work on Array with Object properties");
// Test robustness of reporting:
equal(new ns.Assert.AssertionError({
actual: {
toJSON: function() {
throw "bam!";
}
},
expected: "foo",
operator: "="
}).message, "[object Object] = \"foo\"");
}