merge fx-team to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-10-28 15:20:23 +01:00
Родитель 98dda84064 896fcc7cad
Коммит 51b468217d
60 изменённых файлов: 1217 добавлений и 242 удалений

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

@ -1386,6 +1386,8 @@ pref("devtools.timeline.enabled", false);
pref("devtools.performance_dev.enabled", false);
#endif
pref("devtools.performance.ui.show-timeline-memory", false);
// The default Profiler UI settings
pref("devtools.profiler.ui.show-platform-data", false);

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

@ -385,7 +385,7 @@ Tools.webAudioEditor = {
tooltip: l10n("ToolboxWebAudioEditor1.tooltip", webAudioEditorStrings),
isTargetSupported: function(target) {
return !target.isAddon && !target.chrome;
return !target.isAddon && !target.chrome && target.hasActor("webaudio");
},
build: function(iframeWindow, toolbox) {

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

@ -0,0 +1,322 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Cc, Ci, Cu, Cr } = require("chrome");
const { extend } = require("sdk/util/object");
const { Task } = require("resource://gre/modules/Task.jsm");
loader.lazyRequireGetter(this, "Services");
loader.lazyRequireGetter(this, "promise");
loader.lazyRequireGetter(this, "EventEmitter",
"devtools/toolkit/event-emitter");
loader.lazyRequireGetter(this, "TimelineFront",
"devtools/server/actors/timeline", true);
loader.lazyRequireGetter(this, "DevToolsUtils",
"devtools/toolkit/DevToolsUtils");
loader.lazyImporter(this, "gDevTools",
"resource:///modules/devtools/gDevTools.jsm");
let showTimelineMemory = () => Services.prefs.getBoolPref("devtools.performance.ui.show-timeline-memory");
/**
* A cache of all PerformanceActorsConnection instances. The keys are Target objects.
*/
let SharedPerformanceActors = new WeakMap();
/**
* Instantiates a shared PerformanceActorsConnection for the specified target.
* Consumers must yield on `open` to make sure the connection is established.
*
* @param Target target
* The target owning this connection.
*/
SharedPerformanceActors.forTarget = function(target) {
if (this.has(target)) {
return this.get(target);
}
let instance = new PerformanceActorsConnection(target);
this.set(target, instance);
return instance;
};
/**
* A connection to underlying actors (profiler, memory, framerate, etc)
* shared by all tools in a target.
*
* Use `SharedPerformanceActors.forTarget` to make sure you get the same
* instance every time, and the `PerformanceFront` to start/stop recordings.
*
* @param Target target
* The target owning this connection.
*/
function PerformanceActorsConnection(target) {
EventEmitter.decorate(this);
this._target = target;
this._client = this._target.client;
this._request = this._request.bind(this);
Services.obs.notifyObservers(null, "performance-actors-connection-created", null);
}
PerformanceActorsConnection.prototype = {
/**
* Initializes a connection to the profiler and other miscellaneous actors.
* If already open, nothing happens.
*
* @return object
* A promise that is resolved once the connection is established.
*/
open: Task.async(function*() {
if (this._connected) {
return;
}
// Local debugging needs to make the target remote.
yield this._target.makeRemote();
// Sets `this._profiler`
yield this._connectProfilerActor();
// Sets or shims `this._timeline`
yield this._connectTimelineActor();
this._connected = true;
Services.obs.notifyObservers(null, "performance-actors-connection-opened", null);
}),
/**
* Destroys this connection.
*/
destroy: function () {
this._disconnectActors();
this._connected = false;
},
/**
* Initializes a connection to the profiler actor.
*/
_connectProfilerActor: Task.async(function*() {
// Chrome debugging targets have already obtained a reference
// to the profiler actor.
if (this._target.chrome) {
this._profiler = this._target.form.profilerActor;
}
// Or when we are debugging content processes, we already have the tab
// specific one. Use it immediately.
else if (this._target.form && this._target.form.profilerActor) {
this._profiler = this._target.form.profilerActor;
}
// Check if we already have a grip to the `listTabs` response object
// and, if we do, use it to get to the profiler actor.
else if (this._target.root && this._target.root.profilerActor) {
this._profiler = this._target.root.profilerActor;
}
// Otherwise, call `listTabs`.
else {
this._profiler = (yield listTabs(this._client)).profilerActor;
}
}),
/**
* Initializes a connection to a timeline actor.
*/
_connectTimelineActor: function() {
// Only initialize the timeline front if the respective actor is available.
// Older Gecko versions don't have an existing implementation, in which case
// all the methods we need can be easily mocked.
//
// If the timeline actor exists, all underlying actors (memory, framerate) exist,
// with the expected methods and behaviour. If using the Performance tool,
// and timeline actor does not exist (FxOS devices < Gecko 35),
// then just use the mocked actor and do not display timeline data.
//
// TODO use framework level feature detection from bug 1069673
if (this._target.form && this._target.form.timelineActor) {
this._timeline = new TimelineFront(this._target.client, this._target.form);
} else {
this._timeline = {
start: () => {},
stop: () => {},
isRecording: () => false,
on: () => {},
off: () => {},
destroy: () => {}
};
}
},
/**
* Closes the connections to non-profiler actors.
*/
_disconnectActors: function () {
this._timeline.destroy();
},
/**
* Sends the request over the remote debugging protocol to the
* specified actor.
*
* @param string actor
* The designated actor. Currently supported: "profiler", "timeline".
* @param string method
* Method to call on the backend.
* @param any args [optional]
* Additional data or arguments to send with the request.
* @return object
* A promise resolved with the response once the request finishes.
*/
_request: function(actor, method, ...args) {
// Handle requests to the profiler actor.
if (actor == "profiler") {
let deferred = promise.defer();
let data = args[0] || {};
data.to = this._profiler;
data.type = method;
this._client.request(data, deferred.resolve);
return deferred.promise;
}
// Handle requests to the timeline actor.
if (actor == "timeline") {
return this._timeline[method].apply(this._timeline, args);
}
}
};
/**
* A thin wrapper around a shared PerformanceActorsConnection for the parent target.
* Handles manually starting and stopping a recording.
*
* @param PerformanceActorsConnection connection
* The shared instance for the parent target.
*/
function PerformanceFront(connection) {
EventEmitter.decorate(this);
this._request = connection._request;
// Pipe events from TimelineActor to the PerformanceFront
connection._timeline.on("markers", markers => this.emit("markers", markers));
connection._timeline.on("memory", (delta, measurement) => this.emit("memory", delta, measurement));
connection._timeline.on("ticks", (delta, timestamps) => this.emit("ticks", delta, timestamps));
}
PerformanceFront.prototype = {
/**
* Manually begins a recording session.
*
* @return object
* A promise that is resolved once recording has started.
*/
startRecording: Task.async(function*() {
let { isActive, currentTime } = yield this._request("profiler", "isActive");
// Start the profiler only if it wasn't already active. The built-in
// nsIPerformance module will be kept recording, because it's the same instance
// for all targets and interacts with the whole platform, so we don't want
// to affect other clients by stopping (or restarting) it.
if (!isActive) {
// Extend the options so that protocol.js doesn't modify
// the source object.
let options = extend({}, this._customPerformanceOptions);
yield this._request("profiler", "startProfiler", options);
this._profilingStartTime = 0;
this.emit("profiler-activated");
} else {
this._profilingStartTime = currentTime;
this.emit("profiler-already-active");
}
// The timeline actor is target-dependent, so just make sure
// it's recording.
let withMemory = showTimelineMemory();
yield this._request("timeline", "start", { withTicks: true, withMemory: withMemory });
}),
/**
* Manually ends the current recording session.
*
* @return object
* A promise that is resolved once recording has stopped,
* with the profiler and timeline data.
*/
stopRecording: Task.async(function*() {
// We'll need to filter out all samples that fall out of current profile's
// range. This is necessary because the profiler is continuously running.
let profilerData = yield this._request("profiler", "getProfile");
filterSamples(profilerData, this._profilingStartTime);
offsetSampleTimes(profilerData, this._profilingStartTime);
yield this._request("timeline", "stop");
// Join all the acquired data and return it for outside consumers.
return {
recordingDuration: profilerData.currentTime - this._profilingStartTime,
profilerData: profilerData
};
}),
/**
* Overrides the options sent to the built-in profiler module when activating,
* such as the maximum entries count, the sampling interval etc.
*
* Used in tests and for older backend implementations.
*/
_customPerformanceOptions: {
entries: 1000000,
interval: 1,
features: ["js"]
}
};
/**
* Filters all the samples in the provided profiler data to be more recent
* than the specified start time.
*
* @param object profilerData
* The profiler data received from the backend.
* @param number profilingStartTime
* The earliest acceptable sample time (in milliseconds).
*/
function filterSamples(profilerData, profilingStartTime) {
let firstThread = profilerData.profile.threads[0];
firstThread.samples = firstThread.samples.filter(e => {
return e.time >= profilingStartTime;
});
}
/**
* Offsets all the samples in the provided profiler data by the specified time.
*
* @param object profilerData
* The profiler data received from the backend.
* @param number timeOffset
* The amount of time to offset by (in milliseconds).
*/
function offsetSampleTimes(profilerData, timeOffset) {
let firstThreadSamples = profilerData.profile.threads[0].samples;
for (let sample of firstThreadSamples) {
sample.time -= timeOffset;
}
}
/**
* A collection of small wrappers promisifying functions invoking callbacks.
*/
function listTabs(client) {
let deferred = promise.defer();
client.listTabs(deferred.resolve);
return deferred.promise;
}
exports.getPerformanceActorsConnection = target => SharedPerformanceActors.forTarget(target);
exports.PerformanceFront = PerformanceFront;

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

@ -4,5 +4,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES.devtools.performance += [
'modules/front.js',
'panel.js'
]
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']

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

@ -6,6 +6,7 @@
"use strict";
const {Cc, Ci, Cu, Cr} = require("chrome");
const { PerformanceFront, getPerformanceActorsConnection } = require("devtools/performance/front");
Cu.import("resource://gre/modules/Task.jsm");
@ -27,16 +28,17 @@ PerformancePanel.prototype = {
* Open is effectively an asynchronous constructor.
*
* @return object
* A promise that is resolved when the Profiler completes opening.
* A promise that is resolved when the Performance tool
* completes opening.
*/
open: Task.async(function*() {
this.panelWin.gToolbox = this._toolbox;
this.panelWin.gTarget = this.target;
// Mock Front for now
let gFront = {};
EventEmitter.decorate(gFront);
this.panelWin.gFront = gFront;
this._connection = getPerformanceActorsConnection(this.target);
yield this._connection.open();
this.panelWin.gFront = new PerformanceFront(this._connection);
yield this.panelWin.startupPerformance();
@ -55,6 +57,9 @@ PerformancePanel.prototype = {
return;
}
// Destroy the connection to ensure packet handlers are removed from client.
this._connection.destroy();
yield this.panelWin.shutdownPerformance();
this.emit("destroyed");
this._destroyed = true;

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

@ -0,0 +1,30 @@
[DEFAULT]
skip-if = e10s # Handle in Bug 1077464 for profiler
subsuite = devtools
support-files =
doc_simple-test.html
head.js
# Commented out tests are profiler tests
# that need to be moved over to performance tool
[browser_perf-aaa-run-first-leaktest.js]
[browser_perf-front-basic-timeline-01.js]
[browser_perf-front-basic-profiler-01.js]
# bug 1077464
#[browser_perf-front-profiler-01.js]
[browser_perf-front-profiler-02.js]
[browser_perf-front-profiler-03.js]
[browser_perf-front-profiler-04.js]
# bug 1077464
#[browser_perf-front-profiler-05.js]
# bug 1077464
#[browser_perf-front-profiler-06.js]
# needs shared connection with profiler's shared connection
#[browser_perf-shared-connection-01.js]
[browser_perf-shared-connection-02.js]
[browser_perf-shared-connection-03.js]
# bug 1077464
#[browser_perf-shared-connection-04.js]
[browser_perf-data-samples.js]
[browser_perf-data-massaging-01.js]

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

@ -0,0 +1,22 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the performance tool leaks on initialization and sudden destruction.
* You can also use this initialization format as a template for other tests.
*/
function spawnTest () {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
ok(target, "Should have a target available.");
ok(toolbox, "Should have a toolbox available.");
ok(panel, "Should have a panel available.");
ok(panel.panelWin.gToolbox, "Should have a toolbox reference on the panel window.");
ok(panel.panelWin.gTarget, "Should have a target reference on the panel window.");
ok(panel.panelWin.gFront, "Should have a front reference on the panel window.");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,63 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the retrieved profiler data samples are correctly filtered and
* normalized before passed to consumers.
*/
const WAIT_TIME = 1000; // ms
function spawnTest () {
let { panel } = yield initPerformance(SIMPLE_URL);
let front = panel.panelWin.gFront;
// Perform the first recording...
yield front.startRecording();
let profilingStartTime = front._profilingStartTime;
info("Started profiling at: " + profilingStartTime);
busyWait(WAIT_TIME); // allow the profiler module to sample some cpu activity
let firstRecordingData = yield front.stopRecording();
let firstRecordingFinishTime = firstRecordingData.profilerData.currentTime;
is(profilingStartTime, 0,
"The profiling start time should be 0 for the first recording.");
ok(firstRecordingData.recordingDuration >= WAIT_TIME,
"The first recording duration is correct.");
ok(firstRecordingFinishTime >= WAIT_TIME,
"The first recording finish time is correct.");
// Perform the second recording...
yield front.startRecording();
profilingStartTime = front._profilingStartTime;
info("Started profiling at: " + profilingStartTime);
busyWait(WAIT_TIME); // allow the profiler module to sample more cpu activity
let secondRecordingData = yield front.stopRecording();
let secondRecordingFinishTime = secondRecordingData.profilerData.currentTime;
let secondRecordingProfile = secondRecordingData.profilerData.profile;
let secondRecordingSamples = secondRecordingProfile.threads[0].samples;
isnot(profilingStartTime, 0,
"The profiling start time should not be 0 on the second recording.");
ok(secondRecordingData.recordingDuration >= WAIT_TIME,
"The second recording duration is correct.");
ok(secondRecordingFinishTime - firstRecordingFinishTime >= WAIT_TIME,
"The second recording finish time is correct.");
ok(secondRecordingSamples[0].time < profilingStartTime,
"The second recorded sample times were normalized.");
ok(secondRecordingSamples[0].time > 0,
"The second recorded sample times were normalized correctly.");
ok(!secondRecordingSamples.find(e => e.time + profilingStartTime <= firstRecordingFinishTime),
"There should be no samples from the first recording in the second one, " +
"even though the total number of frames did not overflow.");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,34 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the retrieved profiler data samples always have a (root) node.
* If this ever changes, the |ThreadNode.prototype.insert| function in
* browser/devtools/profiler/utils/tree-model.js will have to be changed.
*/
const WAIT_TIME = 1000; // ms
function spawnTest () {
let { panel } = yield initPerformance(SIMPLE_URL);
let front = panel.panelWin.gFront;
yield front.startRecording();
busyWait(WAIT_TIME); // allow the profiler module to sample some cpu activity
let recordingData = yield front.stopRecording();
let profile = recordingData.profilerData.profile;
for (let thread of profile.threads) {
info("Checking thread: " + thread.name);
for (let sample of thread.samples) {
if (sample.frames[0].location != "(root)") {
ok(false, "The sample " + sample.toSource() + " doesn't have a root node.");
}
}
}
yield teardown(panel);
finish();
}

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

@ -0,0 +1,25 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test basic functionality of PerformanceFront
*/
let WAIT = 1000;
function spawnTest () {
let { target, front } = yield initBackend(SIMPLE_URL);
yield front.startRecording();
yield busyWait(WAIT);
let { recordingDuration, profilerData } = yield front.stopRecording();
ok(recordingDuration > 500, "recordingDuration exists");
ok(profilerData, "profilerData exists");
yield removeTab(target.tab);
finish();
}

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

@ -0,0 +1,84 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test basic functionality of PerformanceFront, retrieving timeline data.
*/
function spawnTest () {
Services.prefs.setBoolPref("devtools.performance.ui.show-timeline-memory", true);
let { target, front } = yield initBackend(SIMPLE_URL);
let lastMemoryDelta = 0;
let lastTickDelta = 0;
let counters = {
markers: [],
memory: [],
ticks: []
};
let deferreds = {
markers: Promise.defer(),
memory: Promise.defer(),
ticks: Promise.defer()
}
front.on("markers", handler);
front.on("memory", handler);
front.on("ticks", handler);
yield front.startRecording();
yield Promise.all(Object.keys(deferreds).map(type => deferreds[type].promise));
yield front.stopRecording();
is(counters.markers.length, 1, "one marker event fired.");
is(counters.memory.length, 3, "three memory events fired.");
is(counters.ticks.length, 3, "three ticks events fired.");
yield removeTab(target.tab);
finish();
function handler (name, ...args) {
if (name === "memory") {
let [delta, measurement] = args;
is(typeof delta, "number", "received `delta` in memory event");
ok(delta > lastMemoryDelta, "received `delta` in memory event");
ok(measurement.total, "received `total` in memory event");
ok(measurement.domSize, "received `domSize` in memory event");
ok(measurement.jsObjectsSize, "received `jsObjectsSize` in memory event");
counters.memory.push({ delta: delta, measurement: measurement });
lastMemoryDelta = delta;
} else if (name === "ticks") {
let [delta, timestamps] = args;
ok(delta > lastTickDelta, "received `delta` in ticks event");
// First tick doesn't contain any timestamps
if (counters.ticks.length) {
ok(timestamps.length, "received `timestamps` in ticks event");
}
counters.ticks.push({ delta: delta, timestamps: timestamps});
lastTickDelta = delta;
} else if (name === "markers") {
let [markers] = args;
ok(markers[0].start, "received atleast one marker with `start`");
ok(markers[0].end, "received atleast one marker with `end`");
ok(markers[0].name, "received atleast one marker with `name`");
counters.markers.push(markers);
front.off(name, handler);
deferreds[name].resolve();
} else {
throw new Error("unknown event");
}
if (name !== "markers" && counters[name].length === 3) {
front.off(name, handler);
deferreds[name].resolve();
}
};
}

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

@ -0,0 +1,37 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the profiler connection front does not activate the built-in
* profiler module if not necessary, and doesn't deactivate it when
* a recording is stopped.
*/
let test = Task.async(function*() {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
let front = panel.panelWin.gFront;
ok(!nsIProfilerModule.IsActive(),
"The built-in profiler module should not have been automatically started.");
let activated = front.once("profiler-activated");
yield front.startRecording();
yield activated;
yield front.stopRecording();
ok(nsIProfilerModule.IsActive(),
"The built-in profiler module should still be active (1).");
let alreadyActive = front.once("profiler-already-active");
yield front.startRecording();
yield alreadyActive;
yield front.stopRecording();
ok(nsIProfilerModule.IsActive(),
"The built-in profiler module should still be active (2).");
yield teardown(panel);
ok(!nsIProfilerModule.IsActive(),
"The built-in profiler module should have been automatically stoped.");
finish();
});

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

@ -0,0 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the built-in profiler module doesn't deactivate when the toolbox
* is destroyed if there are other consumers using it.
*/
let test = Task.async(function*() {
let { panel: firstPanel } = yield initPerformance(SIMPLE_URL);
let firstFront = firstPanel.panelWin.gFront;
let activated = firstFront.once("profiler-activated");
yield firstFront.startRecording();
yield activated;
let { panel: secondPanel } = yield initPerformance(SIMPLE_URL);
let secondFront = secondPanel.panelWin.gFront;
let alreadyActive = secondFront.once("profiler-already-active");
yield secondFront.startRecording();
yield alreadyActive;
yield teardown(firstPanel);
ok(nsIProfilerModule.IsActive(),
"The built-in profiler module should still be active.");
yield teardown(secondPanel);
ok(!nsIProfilerModule.IsActive(),
"The built-in profiler module should have been automatically stoped.");
finish();
});

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

@ -0,0 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the built-in profiler module is not reactivated if no other
* consumer was using it over the remote debugger protocol, and ensures
* that the actor will work properly even in such cases (e.g. the Gecko Profiler
* addon was installed and automatically activated the profiler module).
*/
let test = Task.async(function*() {
// Ensure the profiler is already running when the test starts.
let ENTRIES = 1000000;
let INTERVAL = 1;
let FEATURES = ["js"];
nsIProfilerModule.StartProfiler(ENTRIES, INTERVAL, FEATURES, FEATURES.length);
let { panel: firstPanel } = yield initPerformance(SIMPLE_URL);
let firstFront = firstPanel.panelWin.gFront;
let alredyActive = firstFront.once("profiler-already-active");
yield firstFront.startRecording();
yield alredyActive;
ok(firstFront._profilingStartTime > 0, "The profiler was not restarted.");
let { panel: secondPanel } = yield initPerformance(SIMPLE_URL);
let secondFront = secondPanel.panelWin.gFront;
let alreadyActive = secondFront.once("profiler-already-active");
yield secondFront.startRecording();
yield alreadyActive;
ok(secondFront._profilingStartTime > 0, "The profiler was not restarted.");
yield teardown(firstPanel);
ok(nsIProfilerModule.IsActive(),
"The built-in profiler module should still be active.");
yield teardown(secondPanel);
ok(!nsIProfilerModule.IsActive(),
"The built-in profiler module should have been automatically stoped.");
finish();
});

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

@ -0,0 +1,39 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the shared PerformanceActorsConnection is only opened once.
*/
let gProfilerConnectionsOpened = 0;
Services.obs.addObserver(profilerConnectionObserver, "performance-actors-connection-opened", false);
function spawnTest () {
let { target, panel } = yield initPerformance(SIMPLE_URL);
is(gProfilerConnectionsOpened, 1,
"Only one profiler connection was opened.");
let sharedConnection = getPerformanceActorsConnection(target);
ok(sharedConnection,
"A shared profiler connection for the current toolbox was retrieved.");
is(sharedConnection._request, panel.panelWin.gFront._request,
"The same shared profiler connection is used by the panel's front.");
yield sharedConnection.open();
is(gProfilerConnectionsOpened, 1,
"No additional profiler connections were opened.");
yield teardown(panel);
finish();
}
function profilerConnectionObserver(subject, topic, data) {
is(topic, "performance-actors-connection-opened", "The correct topic was observed.");
gProfilerConnectionsOpened++;
}
registerCleanupFunction(() => {
Services.obs.removeObserver(profilerConnectionObserver, "performance-actors-connection-opened");
});

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

@ -0,0 +1,29 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the shared PerformanceActorsConnection can properly send requests.
*/
function spawnTest () {
let { panel } = yield initPerformance(SIMPLE_URL);
let front = panel.panelWin.gFront;
ok(!nsIProfilerModule.IsActive(),
"The built-in profiler module should not have been automatically started.");
let result = yield front._request("profiler", "startProfiler");
is(result.started, true,
"The request finished successfully and the profiler should've been started.");
ok(nsIProfilerModule.IsActive(),
"The built-in profiler module should now be active.");
result = yield front._request("profiler", "stopProfiler");
is(result.started, false,
"The request finished successfully and the profiler should've been stopped.");
ok(!nsIProfilerModule.IsActive(),
"The built-in profiler module should now be inactive.");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,22 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Profiler test page</title>
</head>
<body>
<script type="text/javascript">
function test() {
var a = "Hello world!";
}
// Prevent this script from being garbage collected.
window.setInterval(test, 1);
</script>
</body>
</html>

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

@ -0,0 +1,209 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
// Enable logging for all the tests. Both the debugger server and frontend will
// be affected by this pref.
let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
Services.prefs.setBoolPref("devtools.debugger.log", false);
let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
let { Promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
let { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
let { getPerformanceActorsConnection, PerformanceFront } = devtools.require("devtools/performance/front");
let nsIProfilerModule = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
let TargetFactory = devtools.TargetFactory;
let mm = null;
const FRAME_SCRIPT_UTILS_URL = "chrome://browser/content/devtools/frame-script-utils.js"
const EXAMPLE_URL = "http://example.com/browser/browser/devtools/performance/test/";
const SIMPLE_URL = EXAMPLE_URL + "doc_simple-test.html";
// All tests are asynchronous.
waitForExplicitFinish();
let gToolEnabled = Services.prefs.getBoolPref("devtools.performance_dev.enabled");
let gShowTimelineMemory = Services.prefs.getBoolPref("devtools.performance.ui.show-timeline-memory");
gDevTools.testing = true;
/**
* Call manually in tests that use frame script utils after initializing
* the tool. Must be called after initializing so we can detect
* whether or not `content` is a CPOW or not. Call after init but before navigating
* to different pages.
*/
function loadFrameScripts () {
mm = gBrowser.selectedBrowser.messageManager;
mm.loadFrameScript(FRAME_SCRIPT_UTILS_URL, false);
}
registerCleanupFunction(() => {
gDevTools.testing = false;
info("finish() was called, cleaning up...");
Services.prefs.setBoolPref("devtools.performance.ui.show-timeline-memory", gShowTimelineMemory);
Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
Services.prefs.setBoolPref("devtools.performance_dev.enabled", gToolEnabled);
// Make sure the profiler module is stopped when the test finishes.
nsIProfilerModule.StopProfiler();
Cu.forceGC();
});
function addTab(aUrl, aWindow) {
info("Adding tab: " + aUrl);
let deferred = Promise.defer();
let targetWindow = aWindow || window;
let targetBrowser = targetWindow.gBrowser;
targetWindow.focus();
let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
let linkedBrowser = tab.linkedBrowser;
linkedBrowser.addEventListener("load", function onLoad() {
linkedBrowser.removeEventListener("load", onLoad, true);
info("Tab added and finished loading: " + aUrl);
deferred.resolve(tab);
}, true);
return deferred.promise;
}
function removeTab(aTab, aWindow) {
info("Removing tab.");
let deferred = Promise.defer();
let targetWindow = aWindow || window;
let targetBrowser = targetWindow.gBrowser;
let tabContainer = targetBrowser.tabContainer;
tabContainer.addEventListener("TabClose", function onClose(aEvent) {
tabContainer.removeEventListener("TabClose", onClose, false);
info("Tab removed and finished closing.");
deferred.resolve();
}, false);
targetBrowser.removeTab(aTab);
return deferred.promise;
}
function handleError(aError) {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
finish();
}
function once(aTarget, aEventName, aUseCapture = false) {
info("Waiting for event: '" + aEventName + "' on " + aTarget + ".");
let deferred = Promise.defer();
for (let [add, remove] of [
["on", "off"], // Use event emitter before DOM events for consistency
["addEventListener", "removeEventListener"],
["addListener", "removeListener"]
]) {
if ((add in aTarget) && (remove in aTarget)) {
aTarget[add](aEventName, function onEvent(...aArgs) {
aTarget[remove](aEventName, onEvent, aUseCapture);
deferred.resolve(...aArgs);
}, aUseCapture);
break;
}
}
return deferred.promise;
}
function test () {
Task.spawn(spawnTest).then(finish, handleError);
}
function initBackend(aUrl) {
info("Initializing a performance front.");
if (!DebuggerServer.initialized) {
DebuggerServer.init(() => true);
DebuggerServer.addBrowserActors();
}
return Task.spawn(function*() {
let tab = yield addTab(aUrl);
let target = TargetFactory.forTab(tab);
yield target.makeRemote();
yield gDevTools.showToolbox(target, "performance");
let connection = getPerformanceActorsConnection(target);
yield connection.open();
let front = new PerformanceFront(connection);
return { target, front };
});
}
function initPerformance(aUrl) {
info("Initializing a performance pane.");
return Task.spawn(function*() {
let tab = yield addTab(aUrl);
let target = TargetFactory.forTab(tab);
yield target.makeRemote();
Services.prefs.setBoolPref("devtools.performance_dev.enabled", true);
let toolbox = yield gDevTools.showToolbox(target, "performance");
let panel = toolbox.getCurrentPanel();
return { target, panel, toolbox };
});
}
function* teardown(panel) {
info("Destroying the performance tool.");
let tab = panel.target.tab;
yield panel._toolbox.destroy();
yield removeTab(tab);
}
function idleWait(time) {
return DevToolsUtils.waitForTime(time);
}
function consoleMethod (...args) {
if (!mm) {
throw new Error("`loadFrameScripts()` must be called before using frame scripts.");
}
mm.sendAsyncMessage("devtools:test:console", args);
}
function* consoleProfile(connection, label) {
let notified = connection.once("profile");
consoleMethod("profile", label);
yield notified;
}
function* consoleProfileEnd(connection) {
let notified = connection.once("profileEnd");
consoleMethod("profileEnd");
yield notified;
}
function busyWait(time) {
let start = Date.now();
let stack;
while (Date.now() - start < time) { stack = Components.stack; }
}
function idleWait(time) {
return DevToolsUtils.waitForTime(time);
}

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

@ -17,6 +17,11 @@ addMessageListener("devtools:test:reload", function ({ data }) {
content.location.reload(data.forceget);
});
addMessageListener("devtools:test:console", function ({ data }) {
let method = data.shift();
content.console[method].apply(content.console, data);
});
addEventListener("load", function() {
sendAsyncMessage("devtools:test:load");
}, true);

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

@ -73,7 +73,7 @@
}
#nav-bar {
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
background-image: linear-gradient(@toolbarHighlight@, transparent);
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
padding-top: 2px;
padding-bottom: 2px;
@ -1540,12 +1540,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
#urlbar-reload-button:not([disabled]):hover {
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.2), hsla(200,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.2), transparent);
-moz-image-region: rect(14px, 14px, 28px, 0);
}
#urlbar-reload-button:not([disabled]):hover:active {
background-image: radial-gradient(circle closest-side, hsla(200,100%,60%,.1), hsla(200,100%,60%,0));
background-image: radial-gradient(circle closest-side, hsla(200,100%,60%,.1), transparent);
-moz-image-region: rect(28px, 14px, 42px, 0);
}
@ -1558,12 +1558,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
#urlbar-go-button:hover {
background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.2), hsla(110,70%,50%,0));
background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.2), transparent);
-moz-image-region: rect(14px, 42px, 28px, 28px);
}
#urlbar-go-button:hover:active {
background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.1), hsla(110,70%,50%,0));
background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.1), transparent);
-moz-image-region: rect(28px, 42px, 42px, 28px);
}
@ -1576,12 +1576,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
#urlbar-stop-button:not([disabled]):hover {
background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.3), hsla(5,100%,75%,0));
background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.3), transparent);
-moz-image-region: rect(14px, 28px, 28px, 14px);
}
#urlbar-stop-button:hover:active {
background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.1), hsla(5,100%,75%,0));
background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.1), transparent);
-moz-image-region: rect(28px, 28px, 42px, 14px);
}
@ -1590,11 +1590,6 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
list-style-image: url("chrome://browser/skin/Info.png");
}
/* Loop */
#loop-call-button {
list-style-image: url("chrome://global/skin/loop/loop-call.png");
}
/* social share panel */
.social-share-frame {
@ -2123,7 +2118,7 @@ toolbarbutton.chevron > .toolbarbutton-icon {
.chat-titlebar {
background-color: #d9d9d9;
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
background-image: linear-gradient(@toolbarHighlight@, transparent);
}
.chat-titlebar[selected] {
@ -2133,7 +2128,7 @@ toolbarbutton.chevron > .toolbarbutton-icon {
.chatbar-button {
-moz-appearance: none;
background-color: #d9d9d9;
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
background-image: linear-gradient(@toolbarHighlight@, transparent);
}
.chatbar-button > .toolbarbutton-icon {
@ -2146,7 +2141,7 @@ toolbarbutton.chevron > .toolbarbutton-icon {
}
.chatbar-button[activity] {
background-image: radial-gradient(circle farthest-corner at center 3px, rgb(233,242,252) 3%, rgba(172,206,255,0.75) 40%, rgba(87,151,201,0.5) 80%, rgba(87,151,201,0));
background-image: radial-gradient(circle farthest-corner at center 3px, rgb(233,242,252) 3%, rgba(172,206,255,0.75) 40%, rgba(87,151,201,0.5) 80%, transparent);
}
chatbox {

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

@ -169,7 +169,7 @@ richlistitem[type="download"]:last-child {
border-top: 1px solid hsla(0,0%,100%,.3);
border-bottom: 1px solid hsla(0,0%,0%,.2);
background-color: Highlight;
background-image: linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,100%,0));
background-image: linear-gradient(hsla(0,0%,100%,.1), transparent);
color: HighlightText;
cursor: pointer;
}

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

@ -25,7 +25,7 @@
--toolbarbutton-hover-boxshadow: 0 1px 0 hsla(0,0%,100%,.5),
0 1px 0 hsla(0,0%,100%,.5) inset;
--toolbarbutton-active-background: hsla(0,0%,0%,.02) linear-gradient(hsla(0,0%,0%,.12), hsla(0,0%,0%,0)) border-box;
--toolbarbutton-active-background: hsla(0,0%,0%,.02) linear-gradient(hsla(0,0%,0%,.12), transparent) border-box;
--toolbarbutton-active-boxshadow: 0 1px 0 hsla(0,0%,100%,.5),
0 1px 0 hsla(0,0%,0%,.05) inset,
0 1px 1px hsla(0,0%,0%,.2) inset;
@ -2128,7 +2128,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
.urlbar-history-dropmarker[open="true"],
.urlbar-history-dropmarker:hover:active {
-moz-image-region: var(--urlbar-dropmarker-active-region);
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), hsla(205,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), transparent);
}
@media (min-resolution: 2dppx) {
@ -2157,7 +2157,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
.urlbar-icon[open="true"],
.urlbar-icon:hover:active {
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), hsla(205,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), transparent);
}
#urlbar-search-splitter {
@ -2373,7 +2373,7 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-
}
#urlbar > toolbarbutton:not([disabled]):hover:active {
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), hsla(205,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), transparent);
}
#urlbar-go-button {
@ -4523,7 +4523,7 @@ menulist.translate-infobar-element > .menulist-dropmarker {
.chat-titlebar {
background-color: #d9d9d9;
background-image: linear-gradient(rgba(255,255,255,.43), rgba(255,255,255,0));
background-image: linear-gradient(rgba(255,255,255,.43), transparent);
}
.chat-titlebar[selected] {
@ -4532,7 +4532,7 @@ menulist.translate-infobar-element > .menulist-dropmarker {
.chatbar-button {
background-color: #d9d9d9;
background-image: linear-gradient(rgba(255,255,255,.43), rgba(255,255,255,0));
background-image: linear-gradient(rgba(255,255,255,.43), transparent);
border-top-left-radius: @toolbarbuttonCornerRadius@;
border-top-right-radius: @toolbarbuttonCornerRadius@;
}

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

@ -12,14 +12,14 @@
#PanelUI-help[panel-multiview-anchor="true"]::after,
toolbarbutton[panel-multiview-anchor="true"] {
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));
linear-gradient(rgba(255,255,255,0.3), transparent);
background-size: 16px, auto;
}
#PanelUI-help[panel-multiview-anchor="true"]:-moz-locale-dir(rtl)::after,
toolbarbutton[panel-multiview-anchor="true"]:-moz-locale-dir(rtl) {
background-image: url(chrome://browser/skin/customizableui/subView-arrow-back-inverted-rtl@2x.png),
linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0));
linear-gradient(rgba(255,255,255,0.3), transparent);
}
#PanelUI-fxa-status {

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

@ -352,7 +352,7 @@ toolbarpaletteitem[place="toolbar"] {
}
#customization-lwtheme-menu-footer {
background: linear-gradient(hsla(210,4%,10%,.05) 60%, hsla(210,4%,10%,0)) border-box;
background: linear-gradient(hsla(210,4%,10%,.05) 60%, transparent) border-box;
border-top: 1px solid hsla(210,4%,10%,.05);
margin-bottom: -10px;
}
@ -368,7 +368,7 @@ toolbarpaletteitem[place="toolbar"] {
}
.customization-lwtheme-menu-footeritem:hover {
background: linear-gradient(hsla(210,4%,10%,.08) 40%, hsla(210,4%,10%,0)) padding-box;
background: linear-gradient(hsla(210,4%,10%,.08) 40%, transparent) padding-box;
}
.customization-lwtheme-menu-footeritem:first-child {

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

@ -87,9 +87,9 @@
}
#PanelUI-button {
background-image: linear-gradient(to bottom, hsla(0,0%,100%,0), hsla(0,0%,100%,.3) 30%, hsla(0,0%,100%,.3) 70%, hsla(0,0%,100%,0)),
linear-gradient(to bottom, hsla(210,54%,20%,0), hsla(210,54%,20%,.3) 30%, hsla(210,54%,20%,.3) 70%, hsla(210,54%,20%,0)),
linear-gradient(to bottom, hsla(0,0%,100%,0), hsla(0,0%,100%,.3) 30%, hsla(0,0%,100%,.3) 70%, hsla(0,0%,100%,0));
background-image: linear-gradient(to bottom, transparent, hsla(0,0%,100%,.3) 30%, hsla(0,0%,100%,.3) 70%, transparent),
linear-gradient(to bottom, transparent, hsla(210,54%,20%,.3) 30%, hsla(210,54%,20%,.3) 70%, transparent),
linear-gradient(to bottom, transparent, hsla(0,0%,100%,.3) 30%, hsla(0,0%,100%,.3) 70%, transparent);
background-size: 1px calc(100% - 1px), 1px calc(100% - 1px), 1px calc(100% - 1px) !important;
background-position: 0px 0px, 1px 0px, 2px 0px;
background-repeat: no-repeat;
@ -874,7 +874,7 @@ toolbarbutton[panel-multiview-anchor="true"] > .toolbarbutton-menubutton-button
}
#PanelUI-help[panel-multiview-anchor="true"] {
background-image: linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0));
background-image: linear-gradient(rgba(255,255,255,0.3), transparent);
background-position: 0;
}
@ -885,7 +885,7 @@ toolbarbutton[panel-multiview-anchor="true"] > .toolbarbutton-menubutton-button
height: 100%;
width: @exitSubviewGutterWidth@;
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));
linear-gradient(rgba(255,255,255,0.3), transparent);
background-repeat: no-repeat;
background-color: Highlight;
background-position: left 10px center, 0;
@ -893,20 +893,20 @@ toolbarbutton[panel-multiview-anchor="true"] > .toolbarbutton-menubutton-button
#PanelUI-help[panel-multiview-anchor="true"]:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/customizableui/subView-arrow-back-inverted-rtl.png),
linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0));
linear-gradient(rgba(255,255,255,0.3), transparent);
background-position: right 10px center, 0;
}
toolbarbutton[panel-multiview-anchor="true"] {
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));
linear-gradient(rgba(255,255,255,0.3), transparent);
background-position: right calc(@menuPanelButtonWidth@ / 2 - @exitSubviewGutterWidth@ + 2px) center;
background-repeat: no-repeat, repeat;
}
toolbarbutton[panel-multiview-anchor="true"]:-moz-locale-dir(rtl) {
background-image: url(chrome://browser/skin/customizableui/subView-arrow-back-inverted-rtl.png),
linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0));
linear-gradient(rgba(255,255,255,0.3), transparent);
background-position: left calc(@menuPanelButtonWidth@ / 2 - @exitSubviewGutterWidth@ + 2px) center;
}
@ -1005,9 +1005,9 @@ toolbarpaletteitem[haswideitem][place="panel"] + toolbarpaletteitem[haswideitem]
-moz-appearance: none;
width: 3px;
-moz-box-align: stretch;
background-image: linear-gradient(to bottom, hsla(0,0%,100%,0), hsla(0,0%,100%,.3) 40%, hsla(0,0%,100%,.3) 60%, hsla(0,0%,100%,0)),
linear-gradient(to bottom, hsla(210,54%,20%,0), hsla(210,54%,20%,.15) 40%, hsla(210,54%,20%,.15) 60%, hsla(210,54%,20%,0)),
linear-gradient(to bottom, hsla(0,0%,100%,0), hsla(0,0%,100%,.3) 40%, hsla(0,0%,100%,.3) 60%, hsla(0,0%,100%,0));
background-image: linear-gradient(to bottom, transparent, hsla(0,0%,100%,.3) 40%, hsla(0,0%,100%,.3) 60%, transparent),
linear-gradient(to bottom, transparent, hsla(210,54%,20%,.15) 40%, hsla(210,54%,20%,.15) 60%, transparent),
linear-gradient(to bottom, transparent, hsla(0,0%,100%,.3) 40%, hsla(0,0%,100%,.3) 60%, transparent);
background-size: 1px, 1px, 1px;
background-position: 0 0, 1px 0, 2px 0;
background-repeat: no-repeat;

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

@ -303,7 +303,7 @@ button {
header {
padding-top: 140px;
background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.7));
background-image: linear-gradient(to bottom, transparent, rgba(0,0,0,0.7));
color: #FFF;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
padding: 10px;

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

@ -524,9 +524,9 @@
.devtools-separator {
margin: 0 2px;
width: 2px;
background-image: linear-gradient(hsla(204,45%,98%,0), hsla(204,45%,98%,.1), hsla(204,45%,98%,0)),
linear-gradient(hsla(206,37%,4%,0), hsla(206,37%,4%,.6), hsla(206,37%,4%,0)),
linear-gradient(hsla(204,45%,98%,0), hsla(204,45%,98%,.1), hsla(204,45%,98%,0));
background-image: linear-gradient(transparent, hsla(204,45%,98%,.1), transparent),
linear-gradient(transparent, hsla(206,37%,4%,.6), transparent),
linear-gradient(transparent, hsla(204,45%,98%,.1), transparent);
background-size: 1px 100%;
background-repeat: no-repeat;
background-position: 0, 1px, 2px;

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

@ -126,7 +126,7 @@ chatbar > chatbox > .chat-titlebar > .chat-swap-button {
}
.chat-titlebar[activity] {
background-image: radial-gradient(ellipse closest-side at center, rgb(255,255,255), rgba(255,255,255,0));
background-image: radial-gradient(ellipse closest-side at center, rgb(255,255,255), transparent);
background-repeat: no-repeat;
background-size: 100% 20px;
background-position: 0 -10px;

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

@ -294,7 +294,7 @@
}
.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]) > .tab-stack > .tab-content {
background-image: radial-gradient(farthest-corner at center bottom, rgb(255,255,255) 3%, rgba(186,221,251,0.75) 20%, rgba(127,179,255,0.25) 40%, rgba(127,179,255,0) 70%);
background-image: radial-gradient(farthest-corner at center bottom, rgb(255,255,255) 3%, rgba(186,221,251,0.75) 20%, rgba(127,179,255,0.25) 40%, transparent 70%);
background-position: center bottom @tabToolbarNavbarOverlap@;
background-repeat: no-repeat;
background-size: 85% 100%;

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

@ -287,7 +287,7 @@
#nav-bar {
border-top: 1px solid @toolbarShadowColor@ !important;
background-clip: padding-box;
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
background-image: linear-gradient(@toolbarHighlight@, transparent);
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
}
@ -877,7 +877,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled=true]):hover,
.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled=true]):hover,
.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled=true]):hover {
background-image: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,.5)),
background-image: linear-gradient(transparent, rgba(255,255,255,.5)),
linear-gradient(transparent, rgba(0,0,0,.25) 30%),
linear-gradient(transparent, rgba(0,0,0,.25) 30%);
background-position: 1px -1px, 0 -1px, 100% -1px;
@ -1223,12 +1223,12 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
}
.urlbar-icon:hover {
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.3), hsla(200,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.3), transparent);
}
.urlbar-icon[open="true"],
.urlbar-icon:hover:active {
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.1), hsla(200,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.1), transparent);
}
#urlbar-search-splitter {
@ -1343,13 +1343,13 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
}
.urlbar-history-dropmarker:hover {
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), hsla(205,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), transparent);
-moz-image-region: rect(0px, 22px, 14px, 11px);
}
.urlbar-history-dropmarker:hover:active,
.urlbar-history-dropmarker[open="true"] {
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.1), hsla(205,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.1), transparent);
-moz-image-region: rect(0px, 33px, 14px, 22px);
}
@ -1495,12 +1495,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
#urlbar-reload-button:not([disabled]):hover {
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.2), hsla(200,100%,70%,0));
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.2), transparent);
-moz-image-region: rect(14px, 14px, 28px, 0);
}
#urlbar-reload-button:not([disabled]):hover:active {
background-image: radial-gradient(circle closest-side, hsla(200,100%,60%,.1), hsla(200,100%,60%,0));
background-image: radial-gradient(circle closest-side, hsla(200,100%,60%,.1), transparent);
-moz-image-region: rect(28px, 14px, 42px, 0);
}
@ -1513,12 +1513,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
#urlbar-go-button:hover {
background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.2), hsla(110,70%,50%,0));
background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.2), transparent);
-moz-image-region: rect(14px, 42px, 28px, 28px);
}
#urlbar-go-button:hover:active {
background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.1), hsla(110,70%,50%,0));
background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.1), transparent);
-moz-image-region: rect(28px, 42px, 42px, 28px);
}
@ -1531,12 +1531,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
#urlbar-stop-button:not([disabled]):hover {
background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.3), hsla(5,100%,75%,0));
background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.3), transparent);
-moz-image-region: rect(14px, 28px, 28px, 14px);
}
#urlbar-stop-button:hover:active {
background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.1), hsla(5,100%,75%,0));
background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.1), transparent);
-moz-image-region: rect(28px, 28px, 42px, 14px);
}
@ -2772,7 +2772,7 @@ toolbarpaletteitem[place="palette"] > #switch-to-metro-button {
.chat-titlebar {
background-color: #c4cfde;
background-image: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0));
background-image: linear-gradient(rgba(255,255,255,.5), transparent);
}
.chat-titlebar[selected] {
@ -2782,7 +2782,7 @@ toolbarpaletteitem[place="palette"] > #switch-to-metro-button {
.chatbar-button {
-moz-appearance: none;
background-color: #c4cfde;
background-image: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0));
background-image: linear-gradient(rgba(255,255,255,.5), transparent);
}
.chatbar-button > .toolbarbutton-icon {

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

@ -21,10 +21,10 @@
background-color: transparent;
/* four gradients for the bevel highlights on each edge, one for blue background */
background-image:
linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, rgba(255,255,255,0) 3px),
linear-gradient(to right, rgba(255,255,255,0.5) 3px, rgba(255,255,255,0) 3px),
linear-gradient(to left, rgba(255,255,255,0.5) 3px, rgba(255,255,255,0) 3px),
linear-gradient(to top, rgba(255,255,255,0.4) 3px, rgba(255,255,255,0) 3px),
linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
background-clip: content-box;
border-radius: 6px;

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

@ -84,7 +84,7 @@ browser.jar:
skin/classic/browser/Toolbar.png (Toolbar-XP.png)
skin/classic/browser/Toolbar-inverted.png
skin/classic/browser/Toolbar-lunaSilver.png
skin/classic/browser/toolbarbutton-dropdown-arrow.png
skin/classic/browser/toolbarbutton-dropdown-arrow.png (toolbarbutton-dropdown-arrow-XPVista7.png)
skin/classic/browser/toolbarbutton-dropdown-arrow-inverted.png
skin/classic/browser/undoCloseTab.png (../shared/undoCloseTab.png)
skin/classic/browser/undoCloseTab@2x.png (../shared/undoCloseTab@2x.png)
@ -192,13 +192,13 @@ browser.jar:
skin/classic/browser/social/chat-icons.svg (../shared/social/chat-icons.svg)
skin/classic/browser/social/gear_default.png (../shared/social/gear_default.png)
skin/classic/browser/social/gear_clicked.png (../shared/social/gear_clicked.png)
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab-XPVista7.png)
skin/classic/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
skin/classic/browser/tabbrowser/tab-active-middle.png (tabbrowser/tab-active-middle.png)
skin/classic/browser/tabbrowser/tab-active-middle@2x.png (tabbrowser/tab-active-middle@2x.png)
skin/classic/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
skin/classic/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left-XPVista7.png)
skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)
skin/classic/browser/tabbrowser/tab-background-start.png (tabbrowser/tab-background-start.png)
skin/classic/browser/tabbrowser/tab-background-start@2x.png (tabbrowser/tab-background-start@2x.png)
@ -516,6 +516,7 @@ browser.jar:
skin/classic/aero/browser/Toolbar-inverted.png
skin/classic/aero/browser/Toolbar-aero.png
skin/classic/aero/browser/toolbarbutton-dropdown-arrow.png
skin/classic/aero/browser/toolbarbutton-dropdown-arrow-XPVista7.png
skin/classic/aero/browser/toolbarbutton-dropdown-arrow-inverted.png
skin/classic/aero/browser/undoCloseTab.png (../shared/undoCloseTab.png)
skin/classic/aero/browser/undoCloseTab@2x.png (../shared/undoCloseTab@2x.png)
@ -626,12 +627,14 @@ browser.jar:
skin/classic/aero/browser/social/gear_default.png (../shared/social/gear_default.png)
skin/classic/aero/browser/social/gear_clicked.png (../shared/social/gear_clicked.png)
skin/classic/aero/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
skin/classic/aero/browser/tabbrowser/newtab-XPVista7.png (tabbrowser/newtab-XPVista7.png)
skin/classic/aero/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
skin/classic/aero/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
skin/classic/aero/browser/tabbrowser/loading.png (tabbrowser/loading.png)
skin/classic/aero/browser/tabbrowser/tab-active-middle.png (tabbrowser/tab-active-middle.png)
skin/classic/aero/browser/tabbrowser/tab-active-middle@2x.png (tabbrowser/tab-active-middle@2x.png)
skin/classic/aero/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
skin/classic/aero/browser/tabbrowser/tab-arrow-left-XPVista7.png (tabbrowser/tab-arrow-left-XPVista7.png)
skin/classic/aero/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)
skin/classic/aero/browser/tabbrowser/tab-background-start.png (tabbrowser/tab-background-start.png)
skin/classic/aero/browser/tabbrowser/tab-background-start@2x.png (tabbrowser/tab-background-start@2x.png)
@ -875,5 +878,14 @@ browser.jar:
% override chrome://browser/skin/sync-horizontalbar.png chrome://browser/skin/sync-horizontalbar-XPVista7.png os=WINNT osversion<6.2
% override chrome://browser/skin/syncProgress-horizontalbar.png chrome://browser/skin/syncProgress-horizontalbar-XPVista7.png os=WINNT osversion<6.2
% override chrome://browser/skin/toolbarbutton-dropdown-arrow.png chrome://browser/skin/toolbarbutton-dropdown-arrow-XPVista7.png os=WINNT osversion=6
% override chrome://browser/skin/toolbarbutton-dropdown-arrow.png chrome://browser/skin/toolbarbutton-dropdown-arrow-XPVista7.png os=WINNT osversion=6.1
% override chrome://browser/skin/tabbrowser/newtab.png chrome://browser/skin/tabbrowser/newtab-XPVista7.png os=WINNT osversion=6
% override chrome://browser/skin/tabbrowser/newtab.png chrome://browser/skin/tabbrowser/newtab-XPVista7.png os=WINNT osversion=6.1
% override chrome://browser/skin/tabbrowser/tab-arrow-left.png chrome://browser/skin/tabbrowser/tab-arrow-left-XPVista7.png os=WINNT osversion=6
% override chrome://browser/skin/tabbrowser/tab-arrow-left.png chrome://browser/skin/tabbrowser/tab-arrow-left-XPVista7.png os=WINNT osversion=6.1
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-XPVista7.png os=WINNT osversion=6
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-XPVista7.png os=WINNT osversion=6.1

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

@ -32,7 +32,7 @@
}
#placesToolbar {
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
background-image: linear-gradient(@toolbarHighlight@, transparent);
}
}

Двоичные данные
browser/themes/windows/tabbrowser/newtab-XPVista7.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 237 B

Двоичные данные
browser/themes/windows/tabbrowser/newtab.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 237 B

После

Ширина:  |  Высота:  |  Размер: 105 B

Двоичные данные
browser/themes/windows/tabbrowser/tab-arrow-left-XPVista7.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 302 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 302 B

После

Ширина:  |  Высота:  |  Размер: 122 B

Двоичные данные
browser/themes/windows/toolbarbutton-dropdown-arrow-XPVista7.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 208 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 208 B

После

Ширина:  |  Высота:  |  Размер: 91 B

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

@ -2873,7 +2873,7 @@ nsDocShell::PopProfileTimelineMarkers(JSContext* aCx,
// If we see an unpaired START, we keep it around for the next call
// to PopProfileTimelineMarkers. We store the kept START objects in
// this array.
decltype(mProfileTimelineMarkers) keptMarkers;
nsTArray<InternalProfileTimelineMarker*> keptMarkers;
for (uint32_t i = 0; i < mProfileTimelineMarkers.Length(); ++i) {
ProfilerMarkerTracing* startPayload = static_cast<ProfilerMarkerTracing*>(

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

@ -103,6 +103,7 @@ import android.nfc.NfcEvent;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
@ -152,6 +153,7 @@ public class BrowserApp extends GeckoApp
private static final String STATE_ABOUT_HOME_TOP_PADDING = "abouthome_top_padding";
private static final String BROWSER_SEARCH_TAG = "browser_search";
private static final String ONBOARD_STARTPANE_TAG = "startpane_dialog";
// Request ID for startActivityForResult.
private static final int ACTIVITY_REQUEST_PREFERENCES = 1001;
@ -628,8 +630,8 @@ public class BrowserApp extends GeckoApp
if (prefs.getBoolean(PREF_STARTPANE_ENABLED, false)) {
if (!Intent.ACTION_VIEW.equals(intentAction)) {
final Intent startIntent = new Intent(this, StartPane.class);
context.startActivity(startIntent);
final DialogFragment dialog = new StartPane();
dialog.show(getSupportFragmentManager(), ONBOARD_STARTPANE_TAG);
}
// Don't bother trying again to show the v1 minimal first run.
prefs.edit().putBoolean(PREF_STARTPANE_ENABLED, false).apply();
@ -637,7 +639,7 @@ public class BrowserApp extends GeckoApp
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
}
private Class<?> getMediaPlayerManager() {
if (AppConstants.MOZ_MEDIA_PLAYER) {

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

@ -27,13 +27,8 @@ import android.widget.Toast;
public final class ReadingListHelper implements GeckoEventListener, NativeEventListener {
private static final String LOGTAG = "ReadingListHelper";
private static final int READER_ADD_SUCCESS = 0;
private static final int READER_ADD_FAILED = 1;
private static final int READER_ADD_DUPLICATE = 2;
protected final Context context;
public ReadingListHelper(Context context) {
this.context = context;
@ -86,16 +81,6 @@ public final class ReadingListHelper implements GeckoEventListener, NativeEventL
* icon, or by tapping the readinglist-add icon in the ReaderMode banner.
*/
private void handleAddToList(JSONObject message) {
final int result = message.optInt("result", READER_ADD_FAILED);
if (result != READER_ADD_SUCCESS) {
if (result == READER_ADD_FAILED) {
showToast(R.string.reading_list_failed, Toast.LENGTH_SHORT);
} else if (result == READER_ADD_DUPLICATE) {
showToast(R.string.reading_list_duplicate, Toast.LENGTH_SHORT);
}
return;
}
final ContentValues values = new ContentValues();
final String url = message.optString("url");

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

@ -1,73 +1,71 @@
package org.mozilla.gecko;
import org.mozilla.gecko.fxa.activities.FxAccountGetStartedActivity;
import org.mozilla.gecko.util.HardwareUtils;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.Button;
public class StartPane extends Activity {
public class StartPane extends DialogFragment {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.onboard_start_pane);
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}
final Button accountButton = (Button) findViewById(R.id.button_account);
accountButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.BUTTON, "firstrun-sync");
showAccountSetup();
}
});
final Button browserButton = (Button) findViewById(R.id.button_browser);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
final View view = inflater.inflate(R.layout.onboard_start_pane, container, false);
final Button browserButton = (Button) view.findViewById(R.id.button_browser);
browserButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.BUTTON, "firstrun-browser");
showBrowser();
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.BUTTON, "firstrun-sync");
// StartPane is on the stack above the browser, so just dismiss this Fragment.
StartPane.this.dismiss();
}
});
if (!HardwareUtils.isTablet() && !HardwareUtils.isTelevision()) {
addDismissHandler();
}
}
final Button accountButton = (Button) view.findViewById(R.id.button_account);
accountButton.setOnClickListener(new OnClickListener() {
private void showBrowser() {
// StartPane is on the stack above the browser, so just kill this activity.
finish();
}
@Override
public void onClick(View v) {
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.BUTTON, "firstrun-browser");
private void showAccountSetup() {
final Intent intent = new Intent(this, FxAccountGetStartedActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
final Intent intent = new Intent(getActivity(), FxAccountGetStartedActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
StartPane.this.dismiss();
}
});
addDismissHandler(view);
return view;
}
// Add handler for dismissing the StartPane on a single click.
private void addDismissHandler() {
final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
private void addDismissHandler(View view) {
final GestureDetector gestureDetector = new GestureDetector(getActivity(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
StartPane.this.finish();
StartPane.this.dismiss();
return true;
}
});
findViewById(R.id.onboard_content).setOnTouchListener(new OnTouchListener() {
view.findViewById(R.id.onboard_content).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);

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

@ -359,8 +359,6 @@ size. -->
<!ENTITY site_settings_no_settings "There are no settings to clear.">
<!ENTITY reading_list_added "Page added to your Reading List">
<!ENTITY reading_list_failed "Failed to add page to your Reading List">
<!ENTITY reading_list_duplicate "Page already in your Reading List">
<!-- Localization note (reading_list_time_minutes) : This string is used in the "Reading List"
panel on the home page to give the user an estimate of how many minutes it will take to

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

@ -10,10 +10,12 @@
android:right="-2dp"
android:left="-2dp">
<shape>
<!-- Padding creates vertical space between the text and the underline -->
<!-- Padding creates vertical space between the text and the underline,
as well as right padding for search icon/clear button -->
<padding
android:top="@dimen/search_bar_padding_y"
android:bottom="@dimen/search_bar_padding_y"/>
android:bottom="@dimen/search_bar_padding_y"
android:right="@dimen/search_bar_padding_right"/>
<solid android:color="@android:color/transparent"/>
<stroke android:width="1dp" android:color="@color/edit_text_default"/>
</shape>

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

@ -10,10 +10,12 @@
android:right="-3dp"
android:left="-3dp">
<shape>
<!-- Padding creates vertical space between the text and the underline -->
<!-- Padding creates vertical space between the text and the underline,
as well as right padding for search icon/clear button -->
<padding
android:top="@dimen/search_bar_padding_y"
android:bottom="@dimen/search_bar_padding_y"/>
android:bottom="@dimen/search_bar_padding_y"
android:right="@dimen/search_bar_padding_right"/>
<solid android:color="@android:color/transparent"/>
<!-- We apply a color filter to set the color for the selected search engine -->
<stroke android:width="2dp" android:color="@android:color/white"/>

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

@ -5,10 +5,10 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/OnboardStartLayout"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:orientation="vertical"
android:background="@color/onboard_start"
android:windowIsFloating="true">
android:background="@color/onboard_start">
<ScrollView android:id="@+id/onboard_content"
android:layout_width="match_parent"
@ -25,8 +25,8 @@
android:layout_height="0dp"
android:layout_weight="1"/>
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
<RelativeLayout android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingTop="15dp">
<ImageView android:id="@+id/image_shield"
@ -59,34 +59,35 @@
<ImageView android:id="@+id/image_sync"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/image_shield"
android:layout_toLeftOf="@id/image_logo"
android:layout_marginRight="30dp"
android:paddingRight="200dp"
android:src="@drawable/onboard_start_sync"
android:contentDescription="@string/onboard_empty_contentDescription"/>
<ImageView android:id="@+id/image_addon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/image_private"
android:layout_toRightOf="@id/image_logo"
android:layout_marginLeft="30dp"
android:layout_centerHorizontal="true"
android:layout_below="@id/image_shield"
android:paddingLeft="200dp"
android:src="@drawable/onboard_start_addon"
android:contentDescription="@string/onboard_empty_contentDescription"/>
<TextView android:id="@+id/text_message"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/image_logo"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:gravity="center"
android:padding="10sp"
android:text="@string/onboard_start_message"
android:textAppearance="@style/OnboardStartTextAppearance"
android:textSize="23sp" />
<TextView android:layout_width="295dp"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:layout_below="@id/text_message"
@ -124,4 +125,4 @@
android:text="@string/onboard_start_button_browser"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

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

@ -168,11 +168,6 @@
<item name="android:layout_gravity">center</item>
</style>
<style name="OnboardStartLayout">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">400dp</item>
</style>
<style name="TextAppearance.UrlBar.Title" parent="TextAppearance.Medium">
<item name="android:textSize">16sp</item>
</style>

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

@ -14,6 +14,9 @@
<dimen name="search_row_padding">15dp</dimen>
<dimen name="search_bar_padding_y">10dp</dimen>
<!-- Padding to account for search engine icon/clear button -->
<dimen name="search_bar_padding_right">25dp</dimen>
<dimen name="search_history_drawable_padding">10dp</dimen>
<!-- Widget Buttons -->

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

@ -835,10 +835,6 @@
<item name="android:windowIsTranslucent">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
<style name="OnboardStartLayout">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
</style>
<style name="OnboardStartTextAppearance">
<item name="android:textColor">#5F636B</item>

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

@ -294,8 +294,6 @@
<string name="site_settings_no_settings">&site_settings_no_settings;</string>
<string name="reading_list_added">&reading_list_added;</string>
<string name="reading_list_failed">&reading_list_failed;</string>
<string name="reading_list_duplicate">&reading_list_duplicate;</string>
<string name="reading_list_time_minutes">&reading_list_time_minutes;</string>
<string name="reading_list_time_over_an_hour">&reading_list_time_over_an_hour;</string>

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

@ -10,10 +10,6 @@ let Reader = {
DEBUG: 0,
READER_ADD_SUCCESS: 0,
READER_ADD_FAILED: 1,
READER_ADD_DUPLICATE: 2,
// Don't try to parse the page if it has too many elements (for memory and
// performance reasons)
MAX_ELEMS_TO_PARSE: 3000,
@ -38,7 +34,7 @@ let Reader = {
},
readerModeActiveCallback: function(tabID) {
Reader.addTabToReadingList(tabID);
Reader._addTabToReadingList(tabID);
UITelemetry.addEvent("save.1", "pageaction", null, "reader");
},
},
@ -93,50 +89,49 @@ let Reader = {
}
},
addTabToReadingList: function(tabID) {
_addTabToReadingList: function(tabID) {
let tab = BrowserApp.getTabForId(tabID);
let currentURI = tab.browser.currentURI;
let url = currentURI.spec;
let urlWithoutRef = currentURI.specIgnoringRef;
let sendResult = function(result, article) {
article = article || {};
Messaging.sendRequest({
type: "Reader:AddToList",
result: result,
title: truncate(article.title, MAX_TITLE_LENGTH),
url: truncate(url, MAX_URI_LENGTH),
length: article.length,
excerpt: article.excerpt
});
}.bind(this);
let handleArticle = function(article) {
if (!article) {
sendResult(this.READER_ADD_FAILED, null);
return;
}
this.storeArticleInCache(article, function(success) {
let result = (success ? this.READER_ADD_SUCCESS : this.READER_ADD_FAILED);
sendResult(result, article);
}.bind(this));
}.bind(this);
this.getArticleFromCache(urlWithoutRef, function (article) {
// If the article is already in reading list, bail
this.getArticleFromCache(urlWithoutRef, (article) => {
// If the article is already in the cache, just use that.
if (article) {
sendResult(this.READER_ADD_DUPLICATE, null);
this.addArticleToReadingList(article);
return;
}
if (tabID != null) {
this.getArticleForTab(tabID, urlWithoutRef, handleArticle);
} else {
this.parseDocumentFromURL(urlWithoutRef, handleArticle);
}
}.bind(this));
// Otherwise, get the article data from the tab.
this.getArticleForTab(tabID, urlWithoutRef, (article) => {
if (article) {
this.addArticleToReadingList(article);
} else {
// If there was a problem getting the article, just store the
// URL and title from the tab.
this.addArticleToReadingList({
url: urlWithoutRef,
title: tab.browser.contentDocument.title,
});
}
});
});
},
addArticleToReadingList: function(article) {
if (!article || !article.url) {
Cu.reportError("addArticleToReadingList requires article with valid URL");
return;
}
Messaging.sendRequest({
type: "Reader:AddToList",
url: truncate(article.url, MAX_URI_LENGTH),
title: truncate(article.title || "", MAX_TITLE_LENGTH),
length: article.length || 0,
excerpt: article.excerpt || "",
});
this.storeArticleInCache(article);
},
getStateForParseOnLoad: function Reader_getStateForParseOnLoad() {
@ -261,10 +256,9 @@ let Reader = {
}.bind(this));
},
storeArticleInCache: function Reader_storeArticleInCache(article, callback) {
storeArticleInCache: function Reader_storeArticleInCache(article) {
this._getCacheDB(function(cacheDB) {
if (!cacheDB) {
callback(false);
return;
}
@ -275,12 +269,10 @@ let Reader = {
request.onerror = function(event) {
this.log("Error storing article in the cache DB: " + article.url);
callback(false);
}.bind(this);
request.onsuccess = function(event) {
this.log("Stored article in the cache DB: " + article.url);
callback(true);
}.bind(this);
}.bind(this));
},

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

@ -4,6 +4,7 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -78,7 +79,11 @@ var WebcompatReporter = {
let webcompatURL = new URL("http://webcompat.com/");
webcompatURL.searchParams.append("open", "1");
webcompatURL.searchParams.append("url", url);
BrowserApp.addTab(webcompatURL.href);
if (PrivateBrowsingUtils.isBrowserPrivate(BrowserApp.selectedTab.browser)) {
BrowserApp.addTab(webcompatURL.href, {parentId: BrowserApp.selectedTab.id, isPrivate: true});
} else {
BrowserApp.addTab(webcompatURL.href);
}
}
};

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

@ -320,25 +320,9 @@ AboutReader.prototype = {
return;
if (this._isReadingListItem == 0) {
let uptime = UITelemetry.uptimeMillis();
gChromeWin.Reader.storeArticleInCache(this._article, function(success) {
let result = gChromeWin.Reader.READER_ADD_FAILED;
if (success) {
result = gChromeWin.Reader.READER_ADD_SUCCESS;
UITelemetry.addEvent("save.1", "button", uptime, "reader");
}
gChromeWin.Reader.addArticleToReadingList(this._article);
let json = JSON.stringify({ fromAboutReader: true, url: this._article.url });
Messaging.sendRequest({
type: "Reader:AddToList",
result: result,
title: this._article.title,
url: this._article.url,
length: this._article.length,
excerpt: this._article.excerpt
});
}.bind(this));
UITelemetry.addEvent("save.1", "button", null, "reader");
} else {
Messaging.sendRequest({
type: "Reader:RemoveFromList",

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

@ -212,7 +212,7 @@ let TimelineActor = exports.TimelineActor = protocol.ActorClass({
if (withMemory) {
this._memoryActor = new MemoryActor(this.conn, this.tabActor);
events.emit(this, "memory", Date.now(), this._memoryActor.measure());
events.emit(this, "memory", this._startTime, this._memoryActor.measure());
}
if (withTicks) {
this._framerateActor = new FramerateActor(this.conn, this.tabActor);

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

@ -36,7 +36,7 @@ button {
border-radius: 2px;
color: black !important;
background-color: hsl(0,0%,90%);
background-image: linear-gradient(hsla(0,0%,100%,.7), hsla(0,0%,100%,0));
background-image: linear-gradient(hsla(0,0%,100%,.7), transparent);
background-clip: padding-box;
border: 1px solid;
border-color: hsl(0,0%,65%) hsl(0,0%,60%) hsl(0,0%,50%);
@ -54,7 +54,7 @@ button:hover {
}
button:hover:active {
background-image: linear-gradient(hsla(0,0%,100%,.2), hsla(0,0%,100%,0));
background-image: linear-gradient(hsla(0,0%,100%,.2), transparent);
background-color: hsl(0,0%,70%);
box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset,
0 1px 3px hsla(0,0%,0%,.2);

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

@ -797,7 +797,7 @@
#detail-screenshot[loading] {
background-image: url("chrome://global/skin/icons/loading_16.png"),
linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
linear-gradient(rgba(255, 255, 255, 0.5), transparent);
background-position: 50% 50%;
background-repeat: no-repeat;
border-radius: 3px;
@ -805,7 +805,7 @@
#detail-screenshot[loading="error"] {
background-image: url("chrome://global/skin/media/error.png"),
linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
linear-gradient(rgba(255, 255, 255, 0.5), transparent);
}
#detail-desc-container {
@ -1152,7 +1152,7 @@ button.button-link:not([disabled="true"]):active:hover {
border: 1px solid rgba(60,73,97,0.5);
border-radius: @toolbarbuttonCornerRadius@;
box-shadow: inset 0 1px rgba(255,255,255,0.25), 0 1px rgba(255,255,255,0.25);
background: linear-gradient(rgba(255,255,255,0.45), rgba(255,255,255,0));
background: linear-gradient(rgba(255,255,255,0.45), transparent);
background-clip: padding-box;
}
@ -1168,7 +1168,7 @@ button.button-link:not([disabled="true"]):active:hover {
.header-button[open="true"] {
border-color: rgba(45,54,71,0.7);
box-shadow: inset 0 0 4px rgb(45,54,71), 0 1px rgba(255,255,255,0.25);
background-image: linear-gradient(rgba(45,54,71,0.6), rgba(45,54,71,0));
background-image: linear-gradient(rgba(45,54,71,0.6), transparent);
}
/*** telemetry experiments ***/

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

@ -116,10 +116,10 @@ treechildren.autocomplete-treebody::-moz-tree-cell-text(selected) {
background-color: transparent;
/* four gradients for the bevel highlights on each edge, one for blue background */
background-image:
linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, rgba(255,255,255,0) 3px),
linear-gradient(to right, rgba(255,255,255,0.5) 3px, rgba(255,255,255,0) 3px),
linear-gradient(to left, rgba(255,255,255,0.5) 3px, rgba(255,255,255,0) 3px),
linear-gradient(to top, rgba(255,255,255,0.4) 3px, rgba(255,255,255,0) 3px),
linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
background-clip: content-box;
border-radius: 6px;

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

@ -38,22 +38,22 @@ html|html {
/* Blame shorlander for this monstrosity. */
background-image: /* Side gradients */
linear-gradient(to right,
rgba(255,255,255,0.2), rgba(255,255,255,0) 40%,
rgba(255,255,255,0) 60%, rgba(255,255,255,0.2)),
rgba(255,255,255,0.2), transparent 40%,
transparent 60%, rgba(255,255,255,0.2)),
/* Aero-style light beams */
-moz-linear-gradient(left 32deg,
/* First light beam */
rgba(255,255,255,0) 19.5%, rgba(255,255,255,0.1) 20%,
transparent 19.5%, rgba(255,255,255,0.1) 20%,
rgba(255,255,255,0.1) 21.5%, rgba(255,255,255,0.2) 22%,
rgba(255,255,255,0.2) 25.5%, rgba(255,255,255,0.1) 26%,
rgba(255,255,255,0.1) 27.5%, rgba(255,255,255,0) 28%,
rgba(255,255,255,0.1) 27.5%, transparent 28%,
/* Second light beam */
rgba(255,255,255,0) 49.5%, rgba(255,255,255,0.1) 50%,
transparent 49.5%, rgba(255,255,255,0.1) 50%,
rgba(255,255,255,0.1) 52.5%, rgba(255,255,255,0.2) 53%,
rgba(255,255,255,0.2) 54.5%, rgba(255,255,255,0.1) 55%,
rgba(255,255,255,0.1) 57.5%, rgba(255,255,255,0) 58%,
rgba(255,255,255,0.1) 57.5%, transparent 58%,
/* Third light beam */
rgba(255,255,255,0) 87%, rgba(255,255,255,0.2) 90%),
transparent 87%, rgba(255,255,255,0.2) 90%),
/* Texture */
url("chrome://global/skin/inContentUI/background-texture.png");
}
@ -88,7 +88,7 @@ html|html {
-moz-appearance: none;
color: black;
padding: 0 5px;
background: linear-gradient(rgba(251, 252, 253, 0.95), rgba(246, 247, 248, 0) 49%,
background: linear-gradient(rgba(251, 252, 253, 0.95), transparent 49%,
rgba(211, 212, 213, 0.45) 51%, rgba(225, 226, 229, 0.3));
background-clip: padding-box;
border-radius: 3px;

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

@ -790,7 +790,7 @@
#detail-screenshot[loading] {
background-image: url("chrome://global/skin/icons/loading_16.png"),
linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
linear-gradient(rgba(255, 255, 255, 0.5), transparent);
background-position: 50% 50%;
background-repeat: no-repeat;
border-radius: 3px;
@ -798,7 +798,7 @@
#detail-screenshot[loading="error"] {
background-image: url("chrome://global/skin/media/error.png"),
linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
linear-gradient(rgba(255, 255, 255, 0.5), transparent);
}
#detail-desc-container {
@ -1161,7 +1161,7 @@ button.button-link:not([disabled="true"]):active:hover {
padding: 1px 3px;
color: #444;
text-shadow: 0 0 3px white;
background: linear-gradient(rgba(251, 252, 253, 0.95), rgba(246, 247, 248, 0) 49%,
background: linear-gradient(rgba(251, 252, 253, 0.95), transparent 49%,
rgba(211, 212, 213, 0.45) 51%, rgba(225, 226, 229, 0.3));
background-clip: padding-box;
border: 1px solid rgba(31, 64, 100, 0.4);