Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2016-06-30 12:46:28 +02:00
commit 6152d5afcc
168 changed files with 3292 additions and 3502 deletions

View File

@ -109,6 +109,7 @@ devtools/client/webconsole/**
devtools/client/webide/**
!devtools/client/webide/components/webideCli.js
devtools/server/**
!devtools/server/css-logic.js
!devtools/server/actors/webbrowser.js
!devtools/server/actors/styles.js
!devtools/server/actors/string.js
@ -125,7 +126,6 @@ devtools/shared/discovery/**
devtools/shared/gcli/**
!devtools/shared/gcli/templater.js
devtools/shared/heapsnapshot/**
devtools/shared/inspector/**
devtools/shared/layout/**
devtools/shared/locales/**
devtools/shared/performance/**

View File

@ -1,3 +1,3 @@
[flake8]
max-line-length = 99
filename = *.py, *.lint
filename = *.py, +.lint

View File

@ -45,7 +45,7 @@
"gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
"gaia": {
"l10n": {
"vcs": "hgtool",
"vcs": "hg",
"root": "https://hg.mozilla.org/gaia-l10n"
}
}

View File

@ -1,5 +1,22 @@
[
{
"version": "Android NDK r11b for B2G",
"algorithm": "sha512",
"visibility": "internal",
"filename": "android-ndk-b2g.tar.xz",
"unpack": true,
"digest": "bc37c6b2e38f4ff19e3326786312d8f893600e155d35dfba45163bd909e022db852b9c6920863cb498bbe7da8b86a6a387fa024bc9444ce3a8d1715cf2c24b21",
"size": 292442020
},
{
"algorithm": "sha512",
"visibility": "internal",
"filename": "backup-aries_23.0.1.A.5.77.tar.xz",
"unpack": true,
"digest": "79c8e390e88cc4765ff7f5f29f3d5337c9037b7eb9414006947d38d34acefdbcf7090c18a366948c682b1c2c9d9ef51012e7be44daa28fdde7b837ade647c257",
"size": 227555180
},
{
"version": "gcc 4.8.5 + PR64905",
"size": 80160264,
"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",

View File

@ -6,23 +6,21 @@
<remote fetch="https://git.mozilla.org/external/aosp" name="aosp"/>
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<!--original fetch url was git://github.com/mozilla-b2g/-->
<remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
<remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
<!--original fetch url was https://git.mozilla.org/b2g-->
<remote fetch="https://git.mozilla.org/b2g" name="b2gmozilla"/>
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was http://android.git.linaro.org/git-ro/-->
<remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
<!--original fetch url was git://github.com/mozilla/-->
<remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
<remote fetch="git://github.com/mozilla/" name="mozilla"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="a954bd2954c422b7d24d92cfd73000cb455dce44"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="19150d320e6802ec211ccc5e74c254ae9992312d"/>
<project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="31f2fbb02035c18b84f3387317aab75adf65da87"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>

View File

@ -48,7 +48,7 @@
"gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
"gaia": {
"l10n": {
"vcs": "hgtool",
"vcs": "hg",
"root": "https://hg.mozilla.org/gaia-l10n"
}
}

View File

@ -1,8 +1,19 @@
[{
[
{
"version": "Android NDK r11b for B2G",
"algorithm": "sha512",
"visibility": "internal",
"filename": "android-ndk-b2g.tar.xz",
"unpack": true,
"digest": "bc37c6b2e38f4ff19e3326786312d8f893600e155d35dfba45163bd909e022db852b9c6920863cb498bbe7da8b86a6a387fa024bc9444ce3a8d1715cf2c24b21",
"size": 292442020
},
{
"version": "gcc 4.8.5 + PR64905",
"size": 80160264,
"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
}]
}
]

View File

@ -6,23 +6,21 @@
<remote fetch="https://git.mozilla.org/external/aosp" name="aosp"/>
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<!--original fetch url was git://github.com/mozilla-b2g/-->
<remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
<remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
<!--original fetch url was https://git.mozilla.org/b2g-->
<remote fetch="https://git.mozilla.org/b2g" name="b2gmozilla"/>
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was http://android.git.linaro.org/git-ro/-->
<remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
<!--original fetch url was git://github.com/mozilla/-->
<remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
<remote fetch="git://github.com/mozilla/" name="mozilla"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="a954bd2954c422b7d24d92cfd73000cb455dce44"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="19150d320e6802ec211ccc5e74c254ae9992312d"/>
<project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="31f2fbb02035c18b84f3387317aab75adf65da87"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>

View File

@ -292,6 +292,10 @@ pref("browser.urlbar.suggest.bookmark", true);
pref("browser.urlbar.suggest.openpage", true);
pref("browser.urlbar.suggest.searches", false);
pref("browser.urlbar.userMadeSearchSuggestionsChoice", false);
// 4 here means the suggestion notification will be automatically
// hidden the 4th day, so it will actually be shown on 3 different days.
pref("browser.urlbar.daysBeforeHidingSuggestionsPrompt", 4);
pref("browser.urlbar.lastSuggestionsPromptDate", 20160601);
// Limit the number of characters sent to the current search engine to fetch
// suggestions.

View File

@ -961,7 +961,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// When _urlbarFocused is true, tabbrowser would close the
// popup if it's opened here, so don't show the notification.
!gBrowser.selectedBrowser._urlbarFocused &&
Services.prefs.getBoolPref("browser.search.suggest.enabled");
Services.prefs.getBoolPref("browser.search.suggest.enabled") &&
this._prefs.getIntPref("daysBeforeHidingSuggestionsPrompt");
]]></getter>
</property>
@ -1300,8 +1301,26 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// to avoid impacting startup / new window performance
aInput.popup.hidden = false;
if (aInput.shouldShowSearchSuggestionsNotification) {
let showNotification = aInput.shouldShowSearchSuggestionsNotification;
if (showNotification) {
let prefs = aInput._prefs;
let date = parseInt((new Date()).toLocaleFormat("%Y%m%d"));
let previousDate = prefs.getIntPref("lastSuggestionsPromptDate");
if (previousDate < date) {
let remainingDays =
prefs.getIntPref("daysBeforeHidingSuggestionsPrompt") - 1;
prefs.setIntPref("daysBeforeHidingSuggestionsPrompt",
remainingDays);
prefs.setIntPref("lastSuggestionsPromptDate", date);
if (!remainingDays)
showNotification = false;
}
}
if (showNotification) {
this._showSearchSuggestionsNotification();
} else if (this.classList.contains("showSearchSuggestionsNotification")) {
this._hideSearchSuggestionsNotification();
}
this._openAutocompletePopup(aInput, aElement);
@ -1384,8 +1403,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
</method>
<method name="_showSearchSuggestionsNotification">
<parameter name="aInput"/>
<parameter name="aElement"/>
<body>
<![CDATA[
// With the notification shown, the listbox's height can sometimes be

View File

@ -5,9 +5,9 @@
"AllWindowEvents": true,
"currentWindow": true,
"EventEmitter": true,
"IconDetails": true,
"makeWidgetId": true,
"pageActionFor": true,
"IconDetails": true,
"PanelPopup": true,
"TabContext": true,
"ViewPopup": true,

View File

@ -10,6 +10,7 @@ Cu.import("resource://devtools/shared/event-emitter.js");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
EventManager,
IconDetails,
} = ExtensionUtils;
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";

View File

@ -6,6 +6,7 @@ Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
EventManager,
IconDetails,
} = ExtensionUtils;
// WeakMap[Extension -> PageAction]
@ -223,11 +224,13 @@ extensions.registerSchemaAPI("pageAction", (extension, context) => {
show(tabId) {
let tab = TabManager.getTab(tabId);
PageAction.for(extension).setProperty(tab, "show", true);
return Promise.resolve();
},
hide(tabId) {
let tab = TabManager.getTab(tabId);
PageAction.for(extension).setProperty(tab, "show", false);
return Promise.resolve();
},
setTitle(details) {

View File

@ -8,138 +8,21 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const INTEGER = /^[1-9]\d*$/;
// Minimum time between two resizes.
const RESIZE_TIMEOUT = 100;
var {
EventManager,
instanceOf,
} = ExtensionUtils;
// This file provides some useful code for the |tabs| and |windows|
// modules. All of the code is installed on |global|, which is a scope
// shared among the different ext-*.js scripts.
// Manages icon details for toolbar buttons in the |pageAction| and
// |browserAction| APIs.
global.IconDetails = {
// Normalizes the various acceptable input formats into an object
// with icon size as key and icon URL as value.
//
// If a context is specified (function is called from an extension):
// Throws an error if an invalid icon size was provided or the
// extension is not allowed to load the specified resources.
//
// If no context is specified, instead of throwing an error, this
// function simply logs a warning message.
normalize(details, extension, context = null) {
let result = {};
try {
if (details.imageData) {
let imageData = details.imageData;
// The global might actually be from Schema.jsm, which
// normalizes most of our arguments. In that case it won't have
// an ImageData property. But Schema.jsm doesn't normalize
// actual ImageData objects, so they will come from a global
// with the right property.
if (instanceOf(imageData, "ImageData")) {
imageData = {"19": imageData};
}
for (let size of Object.keys(imageData)) {
if (!INTEGER.test(size)) {
throw new Error(`Invalid icon size ${size}, must be an integer`);
}
result[size] = this.convertImageDataToPNG(imageData[size], context);
}
}
if (details.path) {
let path = details.path;
if (typeof path != "object") {
path = {"19": path};
}
let baseURI = context ? context.uri : extension.baseURI;
for (let size of Object.keys(path)) {
if (!INTEGER.test(size)) {
throw new Error(`Invalid icon size ${size}, must be an integer`);
}
let url = baseURI.resolve(path[size]);
// The Chrome documentation specifies these parameters as
// relative paths. We currently accept absolute URLs as well,
// which means we need to check that the extension is allowed
// to load them. This will throw an error if it's not allowed.
Services.scriptSecurityManager.checkLoadURIStrWithPrincipal(
extension.principal, url,
Services.scriptSecurityManager.DISALLOW_SCRIPT);
result[size] = url;
}
}
} catch (e) {
// Function is called from extension code, delegate error.
if (context) {
throw e;
}
// If there's no context, it's because we're handling this
// as a manifest directive. Log a warning rather than
// raising an error.
extension.manifestError(`Invalid icon data: ${e}`);
}
return result;
},
// Returns the appropriate icon URL for the given icons object and the
// screen resolution of the given window.
getURL(icons, window, extension, size = 16) {
const DEFAULT = "chrome://browser/content/extension.svg";
size *= window.devicePixelRatio;
let bestSize = null;
if (icons[size]) {
bestSize = size;
} else if (icons[2 * size]) {
bestSize = 2 * size;
} else {
let sizes = Object.keys(icons)
.map(key => parseInt(key, 10))
.sort((a, b) => a - b);
bestSize = sizes.find(candidate => candidate > size) || sizes.pop();
}
if (bestSize) {
return {size: bestSize, icon: icons[bestSize]};
}
return {size, icon: DEFAULT};
},
convertImageDataToPNG(imageData, context) {
let document = context.contentWindow.document;
let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.width = imageData.width;
canvas.height = imageData.height;
canvas.getContext("2d").putImageData(imageData, 0, 0);
return canvas.toDataURL("image/png");
},
};
global.makeWidgetId = id => {
id = id.toLowerCase();
// FIXME: This allows for collisions.

View File

@ -55,6 +55,7 @@
{
"name": "show",
"type": "function",
"async": true,
"description": "Shows the page action. The page action is shown whenever the tab is selected.",
"parameters": [
{"type": "integer", "name": "tabId", "minimum": 0, "description": "The id of the tab for which you want to modify the page action."}
@ -63,6 +64,7 @@
{
"name": "hide",
"type": "function",
"async": true,
"description": "Hides the page action.",
"parameters": [
{"type": "integer", "name": "tabId", "minimum": 0, "description": "The id of the tab for which you want to modify the page action."}

View File

@ -201,9 +201,9 @@ add_task(function* testDetailsObjects() {
browser.tabs.query({active: true, currentWindow: true}, tabs => {
tabId = tabs[0].id;
browser.pageAction.show(tabId);
browser.test.sendMessage("ready", tests);
browser.pageAction.show(tabId).then(() => {
browser.test.sendMessage("ready", tests);
});
});
}
@ -337,8 +337,9 @@ add_task(function* testDefaultDetails() {
browser.tabs.query({active: true, currentWindow: true}, tabs => {
let tabId = tabs[0].id;
browser.pageAction.show(tabId);
browser.test.sendMessage("ready");
browser.pageAction.show(tabId).then(() => {
browser.test.sendMessage("ready");
});
});
}
});

View File

@ -212,8 +212,9 @@ add_task(function* testTabSwitchContext() {
},
expect => {
browser.test.log("Show the icon on the first tab, expect default properties.");
browser.pageAction.show(tabs[0]);
expect(details[0]);
browser.pageAction.show(tabs[0]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Change the icon. Expect default properties excluding the icon.");
@ -234,12 +235,13 @@ add_task(function* testTabSwitchContext() {
expect => {
browser.test.log("Change properties. Expect new properties.");
let tabId = tabs[1];
browser.pageAction.show(tabId);
browser.pageAction.setIcon({tabId, path: "2.png"});
browser.pageAction.setPopup({tabId, popup: "2.html"});
browser.pageAction.setTitle({tabId, title: "Title 2"});
browser.pageAction.show(tabId).then(() => {
browser.pageAction.setIcon({tabId, path: "2.png"});
browser.pageAction.setPopup({tabId, popup: "2.html"});
browser.pageAction.setTitle({tabId, title: "Title 2"});
expect(details[2]);
expect(details[2]);
});
},
expect => {
browser.test.log("Clear the title. Expect default title.");
@ -260,8 +262,9 @@ add_task(function* testTabSwitchContext() {
},
expect => {
browser.test.log("Show the icon. Expect default properties again.");
browser.pageAction.show(tabs[1]);
expect(details[0]);
browser.pageAction.show(tabs[1]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Switch back to the first tab. Expect previously set properties.");
@ -271,9 +274,10 @@ add_task(function* testTabSwitchContext() {
},
expect => {
browser.test.log("Hide the icon on tab 2. Switch back, expect hidden.");
browser.pageAction.hide(tabs[1]);
browser.tabs.update(tabs[1], {active: true}, () => {
expect(null);
browser.pageAction.hide(tabs[1]).then(() => {
browser.tabs.update(tabs[1], {active: true}, () => {
expect(null);
});
});
},
expect => {
@ -284,8 +288,9 @@ add_task(function* testTabSwitchContext() {
},
expect => {
browser.test.log("Hide the icon. Expect hidden.");
browser.pageAction.hide(tabs[0]);
expect(null);
browser.pageAction.hide(tabs[0]).then(() => {
expect(null);
});
},
];
},
@ -321,8 +326,9 @@ add_task(function* testDefaultTitle() {
},
expect => {
browser.test.log("Show the icon on the first tab, expect extension title as default title.");
browser.pageAction.show(tabs[0]);
expect(details[0]);
browser.pageAction.show(tabs[0]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Change the title. Expect new title.");

View File

@ -128,8 +128,9 @@ add_task(function* testPageActionPopup() {
browser.tabs.query({active: true, currentWindow: true}, tabs => {
tabId = tabs[0].id;
browser.pageAction.show(tabId);
browser.test.sendMessage("next-test");
browser.pageAction.show(tabId).then(() => {
browser.test.sendMessage("next-test");
});
});
},
},

View File

@ -14,8 +14,9 @@ add_task(function* testPageActionPopupResize() {
browser.tabs.query({active: true, currentWindow: true}, tabs => {
const tabId = tabs[0].id;
browser.pageAction.show(tabId);
browser.test.sendMessage("action-shown");
browser.pageAction.show(tabId).then(() => {
browser.test.sendMessage("action-shown");
});
});
},

View File

@ -32,8 +32,9 @@ add_task(function* () {
browser.tabs.query({active: true, currentWindow: true}, tabs => {
let tabId = tabs[0].id;
browser.pageAction.show(tabId);
browser.test.sendMessage("page-action-shown");
browser.pageAction.show(tabId).then(() => {
browser.test.sendMessage("page-action-shown");
});
});
},
});

View File

@ -29,8 +29,9 @@ add_task(function* testPageActionPopup() {
let tabId;
browser.tabs.query({active: true, currentWindow: true}, tabs => {
tabId = tabs[0].id;
browser.pageAction.show(tabId);
browser.test.sendMessage("ready");
browser.pageAction.show(tabId).then(() => {
browser.test.sendMessage("ready");
});
});
browser.test.onMessage.addListener(() => {

View File

@ -95,8 +95,9 @@ add_task(function* testBadPermissions() {
contentSetup() {
return new Promise(resolve => {
browser.tabs.query({active: true, currentWindow: true}, tabs => {
browser.pageAction.show(tabs[0].id);
resolve();
browser.pageAction.show(tabs[0].id).then(() => {
resolve();
});
});
});
},

View File

@ -99,8 +99,9 @@ add_task(function* testGoodPermissions() {
contentSetup() {
return new Promise(resolve => {
browser.tabs.query({active: true, currentWindow: true}, tabs => {
browser.pageAction.show(tabs[0].id);
resolve();
browser.pageAction.show(tabs[0].id).then(() => {
resolve();
});
});
});
},
@ -127,8 +128,9 @@ add_task(function* testGoodPermissions() {
contentSetup() {
return new Promise(resolve => {
browser.tabs.query({active: true, currentWindow: true}, tabs => {
browser.pageAction.show(tabs[0].id);
resolve();
browser.pageAction.show(tabs[0].id).then(() => {
resolve();
});
});
});
},

View File

@ -56,13 +56,16 @@ const AutoMigrate = {
}
Services.obs.removeObserver(migrationObserver, "Migration:Ended");
Services.obs.removeObserver(migrationObserver, "Migration:ItemError");
Services.prefs.setCharPref(kAutoMigrateStartedPref, startTime.toString());
Services.prefs.setCharPref(kAutoMigrateFinishedPref, Date.now().toString());
}
};
Services.obs.addObserver(migrationObserver, "Migration:Ended", false);
Services.obs.addObserver(migrationObserver, "Migration:ItemError", false);
Services.prefs.setCharPref(kAutoMigrateStartedPref, Date.now().toString());
// We'll save this when the migration has finished, at which point the pref
// service will be available.
let startTime = Date.now();
migrator.migrate(this.resourceTypesToUse, profileStartup, profileToMigrate);
histogram.add(20);
},

View File

@ -529,6 +529,7 @@ this.MigrationUtils = Object.freeze({
// Canary uses the same description as Chrome so we can't distinguish them.
const APP_DESC_TO_KEY = {
"Internet Explorer": "ie",
"Microsoft Edge": "edge",
"Safari": "safari",
"Firefox": "firefox",
"Google Chrome": "chrome", // Windows, Linux

View File

@ -111,7 +111,7 @@ span#hostname {
#automaticallyReportInFuture {
cursor: pointer;
display: inline-block;
-moz-padding-start: 2.3em;
padding-inline-start: 2.3em;
text-indent: -2.3em;
line-height: 16px
}

View File

@ -557,7 +557,6 @@ SECMOD_DeleteInternalModule
SECMOD_DeleteModule
SECMOD_DestroyModule
SECMOD_FindModule
SECMOD_FindSlot
SECMOD_GetDeadModuleList
SECMOD_GetDefaultModuleList
SECMOD_GetDefaultModuleListLock

View File

@ -7,6 +7,7 @@ import unittest
import inspect
from StringIO import StringIO
import os
import sys
'''Helper to make python unit tests report the way that the Mozilla
unit test infrastructure expects tests to report.
@ -107,6 +108,17 @@ class MockedFile(StringIO):
def __exit__(self, type, value, traceback):
self.close()
def normcase(path):
'''
Normalize the case of `path`.
Don't use `os.path.normcase` because that also normalizes forward slashes
to backslashes on Windows.
'''
if sys.platform.startswith('win'):
return path.lower()
return path
class MockedOpen(object):
'''
Context manager diverting the open builtin such that opening files
@ -129,10 +141,10 @@ class MockedOpen(object):
def __init__(self, files = {}):
self.files = {}
for name, content in files.iteritems():
self.files[os.path.abspath(name)] = content
self.files[normcase(os.path.abspath(name))] = content
def __call__(self, name, mode = 'r'):
absname = os.path.abspath(name)
absname = normcase(os.path.abspath(name))
if 'w' in mode:
file = MockedFile(self, absname)
elif absname in self.files:
@ -169,6 +181,7 @@ class MockedOpen(object):
self._orig_path_exists(p))
def _wrapped_isfile(self, p):
p = normcase(p)
if p in self.files:
return True
@ -179,6 +192,7 @@ class MockedOpen(object):
return self._orig_path_isfile(p)
def _wrapped_isdir(self, p):
p = normcase(p)
p = p if p.endswith(('/', '\\')) else p + os.sep
if any(f.startswith(p) for f in self.files):
return True

View File

@ -903,7 +903,8 @@ StackFrames.prototype = {
// to contain all the values.
if (this._syncedWatchExpressions && aDepth == 0) {
let label = L10N.getStr("watchExpressionsScopeLabel");
let scope = DebuggerView.Variables.addScope(label);
let scope = DebuggerView.Variables.addScope(label,
"variables-view-watch-expressions");
// Customize the scope for holding watch expressions evaluations.
scope.descriptorTooltip = false;

View File

@ -11,7 +11,7 @@
const {Cc, Ci} = require("chrome");
const ToolDefinitions = require("devtools/client/definitions").Tools;
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const CssLogic = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const promise = require("promise");
const defer = require("devtools/shared/defer");

View File

@ -8,7 +8,7 @@
const {Cc, Ci} = require("chrome");
const promise = require("promise");
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const CssLogic = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const {TextProperty} =
require("devtools/client/inspector/rules/models/text-property");

View File

@ -14,7 +14,7 @@ const Services = require("Services");
const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
const {Task} = require("devtools/shared/task");
const {Tools} = require("devtools/client/definitions");
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const {l10n} = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const {OutputParser} = require("devtools/client/shared/output-parser");
const {PrefObserver, PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
@ -968,7 +968,7 @@ CssRuleView.prototype = {
createChild(this.element, "div", {
id: "noResults",
textContent: CssLogic.l10n("rule.empty")
textContent: l10n("rule.empty")
});
},
@ -1011,7 +1011,7 @@ CssRuleView.prototype = {
if (this._selectedElementLabel) {
return this._selectedElementLabel;
}
this._selectedElementLabel = CssLogic.l10n("rule.selectedElement");
this._selectedElementLabel = l10n("rule.selectedElement");
return this._selectedElementLabel;
},
@ -1022,7 +1022,7 @@ CssRuleView.prototype = {
if (this._pseudoElementLabel) {
return this._pseudoElementLabel;
}
this._pseudoElementLabel = CssLogic.l10n("rule.pseudoElement");
this._pseudoElementLabel = l10n("rule.pseudoElement");
return this._pseudoElementLabel;
},

View File

@ -19,7 +19,7 @@
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
var {CssLogic} = require("devtools/shared/inspector/css-logic");
var {isContentStylesheet} = require("devtools/shared/inspector/css-logic");
var defer = require("devtools/shared/defer");
/**
@ -68,7 +68,7 @@ addMessageListener("Test:GetStyleSheetsInfoForNode", function (msg) {
let sheet = domRules.GetElementAt(i).parentStyleSheet;
sheets.push({
href: sheet.href,
isContentSheet: CssLogic.isContentStylesheet(sheet)
isContentSheet: isContentStylesheet(sheet)
});
}

View File

@ -6,7 +6,7 @@
const {Ci} = require("chrome");
const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const {l10n} = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const {PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
const {Rule} = require("devtools/client/inspector/rules/models/rule");
@ -159,7 +159,7 @@ RuleEditor.prototype = {
class: "ruleview-selectorhighlighter" +
(this.ruleView.highlightedSelector === selector ?
" highlighted" : ""),
title: CssLogic.l10n("rule.selectorHighlighter.tooltip")
title: l10n("rule.selectorHighlighter.tooltip")
});
selectorHighlighter.addEventListener("click", () => {
this.ruleView.toggleSelectorHighlighter(selectorHighlighter, selector);

View File

@ -5,7 +5,7 @@
"use strict";
const {Ci} = require("chrome");
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const {l10n} = require("devtools/shared/inspector/css-logic");
const {getCssProperties} = require("devtools/shared/fronts/css-properties");
const {InplaceEditor, editableField} =
require("devtools/client/shared/inplace-editor");
@ -176,7 +176,7 @@ TextPropertyEditor.prototype = {
this.warning = createChild(this.container, "div", {
class: "ruleview-warning",
hidden: "",
title: CssLogic.l10n("rule.warning.title"),
title: l10n("rule.warning.title"),
});
// Filter button that filters for the current property name and is
@ -184,7 +184,7 @@ TextPropertyEditor.prototype = {
this.filterProperty = createChild(this.container, "div", {
class: "ruleview-overridden-rule-filter",
hidden: "",
title: CssLogic.l10n("rule.filterProperty.title"),
title: l10n("rule.filterProperty.title"),
});
this.filterProperty.addEventListener("click", event => {
@ -371,7 +371,7 @@ TextPropertyEditor.prototype = {
onRevert: this._onSwatchRevert
});
span.on("unit-change", this._onSwatchCommit);
let title = CssLogic.l10n("rule.colorSwatch.tooltip");
let title = l10n("rule.colorSwatch.tooltip");
span.setAttribute("title", title);
}
}
@ -389,7 +389,7 @@ TextPropertyEditor.prototype = {
onCommit: this._onSwatchCommit,
onRevert: this._onSwatchRevert
});
let title = CssLogic.l10n("rule.bezierSwatch.tooltip");
let title = l10n("rule.bezierSwatch.tooltip");
span.setAttribute("title", title);
}
}
@ -406,7 +406,7 @@ TextPropertyEditor.prototype = {
onCommit: this._onSwatchCommit,
onRevert: this._onSwatchRevert
}, outputParser, parserOptions);
let title = CssLogic.l10n("rule.filterSwatch.tooltip");
let title = l10n("rule.filterSwatch.tooltip");
span.setAttribute("title", title);
}
}
@ -416,7 +416,7 @@ TextPropertyEditor.prototype = {
if (this.ruleEditor.isEditable) {
for (let angleSpan of this.angleSwatchSpans) {
angleSpan.on("unit-change", this._onSwatchCommit);
let title = CssLogic.l10n("rule.angleSwatch.tooltip");
let title = l10n("rule.angleSwatch.tooltip");
angleSpan.setAttribute("title", title);
}
}

View File

@ -19,7 +19,7 @@
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
var {CssLogic} = require("devtools/shared/inspector/css-logic");
var {isContentStylesheet} = require("devtools/shared/inspector/css-logic");
var defer = require("devtools/shared/defer");
/**
@ -68,7 +68,7 @@ addMessageListener("Test:GetStyleSheetsInfoForNode", function (msg) {
let sheet = domRules.GetElementAt(i).parentStyleSheet;
sheets.push({
href: sheet.href,
isContentSheet: CssLogic.isContentStylesheet(sheet)
isContentSheet: isContentStylesheet(sheet)
});
}

View File

@ -12,7 +12,6 @@ Services.scriptloader.loadSubScript(
this);
var {CssRuleView} = require("devtools/client/inspector/rules/rules");
var {CssLogic, CssSelector} = require("devtools/shared/inspector/css-logic");
var {getInplaceEditorForSpan: inplaceEditor} =
require("devtools/client/shared/inplace-editor");

View File

@ -138,6 +138,11 @@ const LOAD_CAUSE_STRINGS = {
[Ci.nsIContentPolicy.TYPE_IMAGESET]: "imageset",
[Ci.nsIContentPolicy.TYPE_WEB_MANIFEST]: "webManifest"
};
function loadCauseString(causeType) {
return LOAD_CAUSE_STRINGS[causeType] || "unknown";
}
const DEFAULT_EDITOR_CONFIG = {
mode: Editor.modes.text,
readOnly: true,
@ -1228,6 +1233,13 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this.sortContents((a, b) => !this._byDomain(a, b));
}
break;
case "cause":
if (direction == "ascending") {
this.sortContents(this._byCause);
} else {
this.sortContents((a, b) => !this._byCause(a, b));
}
break;
case "type":
if (direction == "ascending") {
this.sortContents(this._byType);
@ -1439,10 +1451,18 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
: firstDomain > secondDomain;
},
_byCause: function ({ attachment: first }, { attachment: second }) {
let firstCause = loadCauseString(first.cause.type);
let secondCause = loadCauseString(second.cause.type);
return firstCause == secondCause
? first.startedMillis > second.startedMillis
: firstCause > secondCause;
},
_byType: function ({ attachment: first }, { attachment: second }) {
let firstType = this._getAbbreviatedMimeType(first.mimeType).toLowerCase();
let secondType = this._getAbbreviatedMimeType(second.mimeType)
.toLowerCase();
let secondType = this._getAbbreviatedMimeType(second.mimeType).toLowerCase();
return firstType == secondType
? first.startedMillis > second.startedMillis
@ -1940,8 +1960,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
}
case "cause": {
let labelNode = $(".requests-menu-cause-label", target);
let text = LOAD_CAUSE_STRINGS[value.type] || "unknown";
labelNode.setAttribute("value", text);
labelNode.setAttribute("value", loadCauseString(value.type));
if (value.loadingDocumentUri) {
labelNode.setAttribute("tooltiptext", value.loadingDocumentUri);
}

View File

@ -85,7 +85,8 @@ var test = Task.async(function* () {
// We can't use about:blank here, because initNetMonitor checks that the
// page has actually made at least one request.
let [, debuggee, monitor] = yield initNetMonitor(SIMPLE_URL);
let { RequestsMenu } = monitor.panelWin.NetMonitorView;
let { $, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
debuggee.location = CAUSE_URL;
@ -129,6 +130,16 @@ var test = Task.async(function* () {
}
});
// Sort the requests by cause and check the order
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-cause-button"));
let expectedOrder = EXPECTED_REQUESTS.map(r => r.causeType).sort();
expectedOrder.forEach((expectedCause, i) => {
let { target } = RequestsMenu.getItemAtIndex(i);
let causeLabel = target.querySelector(".requests-menu-cause-label");
let cause = causeLabel.getAttribute("value");
is(cause, expectedCause, `The request #${i} has the expected cause after sorting`);
});
yield teardown(monitor);
finish();
});

View File

@ -16,8 +16,7 @@ const { getToplevelWindow } = require("sdk/window/utils");
const { Task: { spawn } } = require("devtools/shared/task");
const e10s = require("../utils/e10s");
const BASE_URL = "resource://devtools/client/responsive.html";
const audioCamera = new window.Audio(`${BASE_URL}/audio/camera-click.mp3`);
const audioCamera = new window.Audio("resource://devtools/client/themes/audio/shutter.wav");
const animationFrame = () => new Promise(resolve => {
window.requestAnimationFrame(resolve);

View File

@ -79,6 +79,7 @@ module.exports = createClass({
if (state == Types.deviceListState.LOADED) {
listContent = [dom.option({
value: "",
title: "",
disabled: true,
hidden: true,
}, getStr("responsive.noDeviceSelected")),
@ -86,20 +87,24 @@ module.exports = createClass({
return dom.option({
key: device.name,
value: device.name,
title: "",
}, device.name);
}),
dom.option({
value: OPEN_DEVICE_MODAL_VALUE,
title: "",
}, getStr("responsive.editDeviceList"))];
} else if (state == Types.deviceListState.LOADING
|| state == Types.deviceListState.INITIALIZED) {
listContent = [dom.option({
value: "",
title: "",
disabled: true,
}, getStr("responsive.deviceListLoading"))];
} else if (state == Types.deviceListState.ERROR) {
listContent = [dom.option({
value: "",
title: "",
disabled: true,
}, getStr("responsive.deviceListError"))];
}
@ -108,6 +113,7 @@ module.exports = createClass({
{
className: selectClass,
value: selectedDevice,
title: selectedDevice,
onChange: this.onSelectChange,
disabled: (state !== Types.deviceListState.LOADED),
},

View File

@ -177,17 +177,18 @@ html, body {
-moz-appearance: none;
background-color: var(--theme-toolbar-background);
background-image: var(--viewport-selection-arrow);
background-position: 136px;
background-position: 100% 52%;
background-repeat: no-repeat;
background-size: 7px;
border: none;
color: var(--viewport-color);
height: 100%;
padding: 0 16px 0 0;
padding: 0 8px 0 8px;
text-align: center;
text-overflow: ellipsis;
width: 150px;
font-size: 11px;
width: -moz-fit-content;
}
.viewport-device-selector.selected {

View File

@ -6,7 +6,6 @@
DIRS += [
'actions',
'audio',
'browser',
'components',
'images',

View File

@ -8,6 +8,7 @@ support-files =
[test_notification_box_03.html]
[test_reps_attribute.html]
[test_reps_date-time.html]
[test_reps_function.html]
[test_reps_grip.html]
[test_reps_object-with-url.html]
[test_reps_stylesheet.html]

View File

@ -188,3 +188,18 @@ function shallowRenderComponent(component, props) {
renderer.render(el, {});
return renderer.getRenderOutput();
}
/**
* Test that a rep renders correctly across different modes.
*/
function testRepRenderModes(modeTests, testName, componentUnderTest, gripStub) {
modeTests.forEach(({mode, expectedOutput, message}) => {
const modeString = typeof mode === "undefined" ? "no mode" : mode;
if (!message) {
message = `${testName}: ${modeString} renders correctly.`;
}
const rendered = renderComponent(componentUnderTest.rep, { object: gripStub, mode });
is(rendered.textContent, expectedOutput, message);
});
}

View File

@ -0,0 +1,171 @@
<!DOCTYPE HTML>
<html>
<!--
Test Func rep
-->
<head>
<meta charset="utf-8">
<title>Rep test - Func</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
window.onload = Task.async(function* () {
let { Rep } = browserRequire("devtools/client/shared/components/reps/rep");
let { Func } = browserRequire("devtools/client/shared/components/reps/function");
const componentUnderTest = Func;
try {
// Test that correct rep is chosen
const gripStub = getGripStub("testNamed");
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
is(renderedRep.type, Func.rep, `Rep correctly selects ${Func.rep.displayName}`);
yield testNamed();
yield testVarNamed();
yield testAnon();
yield testLongName();
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
function testNamed() {
// Test declaration: `function testName{ let innerVar = "foo" }`
const testName = "testNamed";
const defaultOutput = `testName()`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
}
];
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function testVarNamed() {
// Test declaration: `let testVarName = function() { }`
const testName = "testVarNamed";
const defaultOutput = `testVarName()`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
}
];
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function testAnon() {
// Test declaration: `() => {}`
const testName = "testAnon";
const defaultOutput = `function()`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
}
];
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function testLongName() {
// Test declaration: `let f = function loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong() { }`
const testName = "testLongName";
const defaultOutput = `looooooooooooooooooooooooooooooooooooooooooooooooo\u2026ooooooooooooooooooooooooooooooooooooooooooooong()`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
}
];
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function getGripStub(functionName) {
switch (functionName) {
case "testNamed":
return {
"type": "object",
"class": "Function",
"actor": "server1.conn6.obj35",
"extensible": true,
"frozen": false,
"sealed": false,
"name": "testName",
"displayName": "testName",
"location": {
"url": "debugger eval code",
"line": 1
}
};
case "testVarNamed":
return {
"type": "object",
"class": "Function",
"actor": "server1.conn7.obj41",
"extensible": true,
"frozen": false,
"sealed": false,
"displayName": "testVarName",
"location": {
"url": "debugger eval code",
"line": 1
}
};
case "testAnon":
return {
"type": "object",
"class": "Function",
"actor": "server1.conn7.obj45",
"extensible": true,
"frozen": false,
"sealed": false,
"location": {
"url": "debugger eval code",
"line": 1
}
};
case "testLongName":
return {
"type": "object",
"class": "Function",
"actor": "server1.conn7.obj67",
"extensible": true,
"frozen": false,
"sealed": false,
"name": "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong",
"displayName": "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong",
"location": {
"url": "debugger eval code",
"line": 1
}
};
}
}
});
</script>
</pre>
</body>
</html>

View File

@ -18,6 +18,8 @@ window.onload = Task.async(function* () {
let { Rep } = browserRequire("devtools/client/shared/components/reps/rep");
let { Grip } = browserRequire("devtools/client/shared/components/reps/grip");
const componentUnderTest = Grip;
try {
yield testBasic();
@ -66,7 +68,7 @@ window.onload = Task.async(function* () {
}
];
testRenderingInMode(modeTests, testName);
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function testMaxProps() {
@ -94,7 +96,7 @@ window.onload = Task.async(function* () {
}
];
testRenderingInMode(modeTests, testName);
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function testMoreThanMaxProps() {
@ -131,7 +133,7 @@ window.onload = Task.async(function* () {
}
];
testRenderingInMode(modeTests, testName);
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function testUninterestingProps() {
@ -166,7 +168,7 @@ window.onload = Task.async(function* () {
}
];
testRenderingInMode(modeTests, testName);
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function testNestedArray() {
@ -194,20 +196,7 @@ window.onload = Task.async(function* () {
}
];
testRenderingInMode(modeTests, testName);
}
function testRenderingInMode(modeTests, testName) {
modeTests.forEach(({mode, expectedOutput, message}) => {
const modeString = typeof mode === "undefined" ? "no mode" : mode;
if (!message) {
message = `${testName}: ${modeString} renders correctly.`
}
const gripStub = getGripStub(testName);
const rendered = renderComponent(Grip.rep, { object: gripStub, mode });
is(rendered.textContent, expectedOutput, message);
});
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function getGripStub(functionName) {

View File

@ -128,14 +128,16 @@ VariablesView.prototype = {
*
* @param string aName
* The scope's name (e.g. "Local", "Global" etc.).
* @param string aCustomClass
* An additional class name for the containing element.
* @return Scope
* The newly created Scope instance.
*/
addScope: function (aName = "") {
addScope: function (aName = "", aCustomClass = "") {
this._removeEmptyNotice();
this._toggleSearchVisibility(true);
let scope = new Scope(this, aName);
let scope = new Scope(this, aName, { customClass: aCustomClass });
this._store.push(scope);
this._itemsByElement.set(scope._target, scope);
this._currHierarchy.set(aName, scope);
@ -1792,7 +1794,8 @@ Scope.prototype = {
*/
_init: function (aName, aFlags) {
this._idString = generateId(this._nameString = aName);
this._displayScope(aName, this.targetClassName, "devtools-toolbar");
this._displayScope(aName, `${this.targetClassName} ${aFlags.customClass}`,
"devtools-toolbar");
this._addEventListeners();
this.parentNode.appendChild(this._target);
},
@ -1820,6 +1823,7 @@ Scope.prototype = {
let name = this._name = document.createElement("label");
name.className = "plain name";
name.setAttribute("value", aName);
name.setAttribute("crop", "end");
let title = this._title = document.createElement("hbox");
title.className = "title " + aTitleClassName;

View File

@ -5,7 +5,7 @@ code, and optionally help with indentation.
# Upgrade
Currently used version is 5.15.2. To upgrade, download a new version of
Currently used version is 5.16.0. To upgrade, download a new version of
CodeMirror from the project's page [1] and replace all JavaScript and
CSS files inside the codemirror directory [2].

View File

@ -29,7 +29,7 @@ CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
}
if (pass == 1 && found < start.ch) return;
if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) &&
(lineText.slice(found - endToken.length, found) == endToken ||
(found == 0 || lineText.slice(found - endToken.length, found) == endToken ||
!/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) {
startCh = found + startToken.length;
break;

View File

@ -49,7 +49,7 @@
});
var myRange = cm.markText(range.from, range.to, {
replacedWith: myWidget,
clearOnEnter: true,
clearOnEnter: getOption(cm, options, "clearOnEnter"),
__isFold: true
});
myRange.on("clear", function(from, to) {
@ -129,7 +129,8 @@
rangeFinder: CodeMirror.fold.auto,
widget: "\u2194",
minFoldSize: 0,
scanUp: false
scanUp: false,
clearOnEnter: true
};
CodeMirror.defineOption("foldOptions", null);

View File

@ -50,7 +50,7 @@
}
function isFolded(cm, line) {
var marks = cm.findMarksAt(Pos(line));
var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
}

View File

@ -229,6 +229,7 @@
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
(completion.options.container || document.body).appendChild(hints);
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
var scrolls = hints.scrollHeight > hints.clientHeight + 1
if (overlapY > 0) {
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
if (curTop - height > 0) { // Fits above cursor
@ -253,6 +254,8 @@
}
hints.style.left = (left = pos.left - overlapX) + "px";
}
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
node.style.paddingRight = cm.display.nativeBarWidth + "px"
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },

View File

@ -420,6 +420,34 @@
map[cK + ctrl + "Backspace"] = "delLineLeft";
cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
if (cm.somethingSelected()) return CodeMirror.Pass;
cm.operation(function() {
var cursors = cm.listSelections();
var indentUnit = cm.getOption("indentUnit");
for (var i = cursors.length - 1; i >= 0; i--) {
var cursor = cursors[i].head;
var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor);
var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize"));
// Delete by one character by default
var deletePos = cm.findPosH(cursor, -1, "char", false);
if (toStartOfLine && !/\S/.test(toStartOfLine) && column % indentUnit == 0) {
var prevIndent = new Pos(cursor.line,
CodeMirror.findColumn(toStartOfLine, column - indentUnit, indentUnit));
// Smart delete only if we found a valid prevIndent location
if (prevIndent.ch != cursor.ch) deletePos = prevIndent;
}
cm.replaceRange("", deletePos, cursor, "+delete");
}
});
};
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
@ -472,7 +500,8 @@
cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
};
cmds[map["Shift-Alt-Up"] = "selectLinesUpward"] = function(cm) {
var selectLinesCombo = mac ? "Ctrl-Shift-" : "Ctrl-Alt-";
cmds[map[selectLinesCombo + "Up"] = "selectLinesUpward"] = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
@ -482,7 +511,7 @@
}
});
};
cmds[map["Shift-Alt-Down"] = "selectLinesDownward"] = function(cm) {
cmds[map[selectLinesCombo + "Down"] = "selectLinesDownward"] = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {

View File

@ -88,8 +88,14 @@
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
@ -291,7 +297,10 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
visibility: hidden;
}
.CodeMirror-cursor { position: absolute; }
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {

View File

@ -2933,10 +2933,23 @@
for (;;) {
if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
var ch = x < fromX || x - fromX <= toX - x ? from : to;
var outside = ch == from ? fromOutside : toOutside
var xDiff = x - (ch == from ? fromX : toX);
// This is a kludge to handle the case where the coordinates
// are after a line-wrapped line. We should replace it with a
// more general handling of cursor positions around line
// breaks. (Issue #4078)
if (toOutside && !bidi && !/\s/.test(lineObj.text.charAt(ch)) && xDiff > 0 &&
ch < lineObj.text.length && preparedMeasure.view.measure.heights.length > 1) {
var charSize = measureCharPrepared(cm, preparedMeasure, ch, "right");
if (innerOff <= charSize.bottom && innerOff >= charSize.top && Math.abs(x - charSize.right) < xDiff) {
outside = false
ch++
xDiff = x - charSize.right
}
}
while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
var pos = PosWithInfo(lineNo, ch, outside, xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
return pos;
}
var step = Math.ceil(dist / 2), middle = from + step;
@ -3660,6 +3673,7 @@
// Let the drag handler handle this.
if (webkit) display.scroller.draggable = true;
cm.state.draggingText = dragEnd;
dragEnd.copy = mac ? e.altKey : e.ctrlKey
// IE's approach to draggable
if (display.scroller.dragDrop) display.scroller.dragDrop();
on(document, "mouseup", dragEnd);
@ -3890,7 +3904,7 @@
try {
var text = e.dataTransfer.getData("Text");
if (text) {
if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey))
if (cm.state.draggingText && !cm.state.draggingText.copy)
var selected = cm.listSelections();
setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
if (selected) for (var i = 0; i < selected.length; ++i)
@ -8902,7 +8916,7 @@
// THE END
CodeMirror.version = "5.15.2";
CodeMirror.version = "5.16.0";
return CodeMirror;
});

View File

@ -274,6 +274,10 @@
"clearBookmarks",
Pos(0, 0), "selectBookmarks", at(0, 0));
stTest("smartBackspace", " foo\n bar",
setSel(0, 2, 0, 2, 1, 4, 1, 4, 1, 6, 1, 6), "smartBackspace",
val("foo\n br"))
stTest("upAndDowncaseAtCursor", "abc\ndef x\nghI",
setSel(0, 1, 0, 3,
1, 1, 1, 1,

View File

@ -15,7 +15,7 @@ const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const Editor = require("devtools/client/sourceeditor/editor");
const promise = require("promise");
const defer = require("devtools/shared/defer");
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const {shortSource, prettifyCSS} = require("devtools/shared/inspector/css-logic");
const {console} = require("resource://gre/modules/Console.jsm");
const Services = require("Services");
const EventEmitter = require("devtools/shared/event-emitter");
@ -196,7 +196,7 @@ StyleSheetEditor.prototype = {
if (!this._friendlyName) {
let sheetURI = this.styleSheet.href;
this._friendlyName = CssLogic.shortSource({ href: sheetURI });
this._friendlyName = shortSource({ href: sheetURI });
try {
this._friendlyName = decodeURI(this._friendlyName);
} catch (ex) {
@ -262,9 +262,8 @@ StyleSheetEditor.prototype = {
/**
* A helper function that fetches the source text from the style
* sheet. The text is possibly prettified using
* CssLogic.prettifyCSS. This also sets |this._state.text| to the
* new text.
* sheet. The text is possibly prettified using prettifyCSS. This
* also sets |this._state.text| to the new text.
*
* @return {Promise} a promise that resolves to the new text
*/
@ -274,7 +273,7 @@ StyleSheetEditor.prototype = {
}).then((source) => {
let ruleCount = this.styleSheet.ruleCount;
if (!this.styleSheet.isOriginalSource) {
source = CssLogic.prettifyCSS(source, ruleCount);
source = prettifyCSS(source, ruleCount);
}
this._state.text = source;
return source;

View File

@ -5,5 +5,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'camera-click.mp3',
'shutter.wav',
)

Binary file not shown.

View File

@ -4,6 +4,10 @@
# 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/.
DIRS += [
'audio',
]
DevToolsModules(
'common.css',
'variables.css',

View File

@ -627,6 +627,12 @@ widgets.css is overwritten. */
margin-top: -1px;
}
/* Custom scope stylings */
.variables-view-watch-expressions .title > .name {
max-width: 14em;
}
.theme-firebug .variables-view-scope > .title {
height: auto;
border: none;

View File

@ -18,7 +18,7 @@ loader.lazyGetter(this, "DOMUtils", () => {
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
});
loader.lazyRequireGetter(this, "stylesheets", "devtools/server/actors/stylesheets");
loader.lazyRequireGetter(this, "CssLogic", "devtools/shared/inspector/css-logic", true);
loader.lazyRequireGetter(this, "prettifyCSS", "devtools/shared/inspector/css-logic", true);
const CSSRule = Ci.nsIDOMCSSRule;
@ -397,7 +397,7 @@ var CSSUsageActor = protocol.ActorClassWithSpec(cssUsageSpec, {
shortUrl: rule.url.split("/").slice(-1)[0],
start: { line: rule.line, column: rule.column },
selectorText: ruleData.selectorText,
formattedCssText: CssLogic.prettifyCSS(ruleData.cssText)
formattedCssText: prettifyCSS(ruleData.cssText)
};
};

View File

@ -12,7 +12,7 @@ const { on, emit } = require("sdk/event/core");
const lazyContainer = {};
loader.lazyRequireGetter(lazyContainer, "CssLogic",
"devtools/shared/inspector/css-logic", true);
"devtools/server/css-logic", true);
exports.getComputedStyle = (node) =>
lazyContainer.CssLogic.getComputedStyle(node);

View File

@ -150,7 +150,7 @@ loader.lazyGetter(this, "eventListenerService", function () {
.getService(Ci.nsIEventListenerService);
});
loader.lazyGetter(this, "CssLogic", () => require("devtools/shared/inspector/css-logic").CssLogic);
loader.lazyGetter(this, "CssLogic", () => require("devtools/server/css-logic").CssLogic);
/**
* We only send nodeValue up to a certain size by default. This stuff

View File

@ -33,7 +33,7 @@ loader.lazyGetter(this, "Debugger", () => {
hackDebugger(Debugger);
return Debugger;
});
loader.lazyRequireGetter(this, "CssLogic", "devtools/shared/inspector/css-logic", true);
loader.lazyRequireGetter(this, "CssLogic", "devtools/server/css-logic", true);
loader.lazyRequireGetter(this, "events", "sdk/event/core");
loader.lazyRequireGetter(this, "mapURIToAddonID", "devtools/server/actors/utils/map-uri-to-addon-id");

View File

@ -14,7 +14,7 @@ const {Arg, method, RetVal} = protocol;
const {fetch} = require("devtools/shared/DevToolsUtils");
const {oldStyleSheetSpec, styleEditorSpec} = require("devtools/shared/specs/styleeditor");
loader.lazyGetter(this, "CssLogic", () => require("devtools/shared/inspector/css-logic").CssLogic);
loader.lazyGetter(this, "CssLogic", () => require("devtools/shared/inspector/css-logic"));
var TRANSITION_CLASS = "moz-styleeditor-transitioning";
var TRANSITION_DURATION_MS = 500;

View File

@ -19,7 +19,8 @@ const {UPDATE_PRESERVING_RULES, UPDATE_GENERAL} = require("devtools/server/actor
const {pageStyleSpec, styleRuleSpec, ELEMENT_STYLE} = require("devtools/shared/specs/styles");
loader.lazyRequireGetter(this, "CSS", "CSS");
loader.lazyGetter(this, "CssLogic", () => require("devtools/shared/inspector/css-logic").CssLogic);
loader.lazyGetter(this, "CssLogic", () => require("devtools/server/css-logic").CssLogic);
loader.lazyGetter(this, "SharedCssLogic", () => require("devtools/shared/inspector/css-logic"));
loader.lazyGetter(this, "DOMUtils", () => Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils));
// When gathering rules to read for pseudo elements, we will skip
@ -202,7 +203,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
getComputed: function (node, options) {
let ret = Object.create(null);
this.cssLogic.sourceFilter = options.filter || CssLogic.FILTER.UA;
this.cssLogic.sourceFilter = options.filter || SharedCssLogic.FILTER.UA;
this.cssLogic.highlight(node.rawNode);
let computed = this.cssLogic.computedStyle || [];
@ -380,7 +381,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
* }
*/
getMatchedSelectors: function (node, property, options) {
this.cssLogic.sourceFilter = options.filter || CssLogic.FILTER.UA;
this.cssLogic.sourceFilter = options.filter || SharedCssLogic.FILTER.UA;
this.cssLogic.highlight(node.rawNode);
let rules = new Set();
@ -577,9 +578,9 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
for (let i = domRules.Count() - 1; i >= 0; i--) {
let domRule = domRules.GetElementAt(i);
let isSystem = !CssLogic.isContentStylesheet(domRule.parentStyleSheet);
let isSystem = !SharedCssLogic.isContentStylesheet(domRule.parentStyleSheet);
if (isSystem && options.filter != CssLogic.FILTER.UA) {
if (isSystem && options.filter != SharedCssLogic.FILTER.UA) {
continue;
}

View File

@ -18,7 +18,7 @@ const {originalSourceSpec, mediaRuleSpec, styleSheetSpec,
styleSheetsSpec} = require("devtools/shared/specs/stylesheets");
const {SourceMapConsumer} = require("source-map");
loader.lazyGetter(this, "CssLogic", () => require("devtools/shared/inspector/css-logic").CssLogic);
loader.lazyGetter(this, "CssLogic", () => require("devtools/shared/inspector/css-logic"));
XPCOMUtils.defineLazyGetter(this, "DOMUtils", function () {
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);

1544
devtools/server/css-logic.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -649,24 +649,3 @@ This will require some matching work on the front:
}, {
impl: "_clearTemporaryChildren"
})
Telemetry
---------
You can specify a telemetry probe id in your method spec:
// spec:
methods: {
echo: {
request: { str: Arg(0) },
response: { str: RetVal() },
telemetry: "ECHO"
}
}
// implementation:
echo: function (str) {
return str;
}
... and the time to execute that request will be included as a telemetry probe.

View File

@ -32,6 +32,7 @@ DevToolsModules(
'child.js',
'content-globals.js',
'content-server.jsm',
'css-logic.js',
'main.js',
'primitive.js',
'service-worker-child.js',

View File

@ -29,7 +29,6 @@ skip-if = buildapp == 'mulet'
[test_connectToChild.html]
skip-if = buildapp == 'mulet'
[test_css-logic.html]
[test_css-logic-inheritance.html]
[test_css-logic-media-queries.html]
[test_css-logic-specificity.html]
[test_css-properties.html]

View File

@ -1,46 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
Test that css-logic handles inherited properties correctly
-->
<head>
<meta charset="utf-8">
<title>Test css-logic inheritance</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<div style="margin-left:10px; font-size: 5px">
<div id="innerdiv">Inner div</div>
</div>
<script type="application/javascript;version=1.8">
window.onload = function() {
var { classes: Cc, utils: Cu, interfaces: Ci } = Components;
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
var Services = require("Services");
const {CssLogic} = require("devtools/shared/inspector/css-logic");
SimpleTest.waitForExplicitFinish();
let cssLogic = new CssLogic(DOMUtils.isInheritedProperty);
cssLogic.highlight(document.getElementById("innerdiv"));
let marginProp = cssLogic.getPropertyInfo("margin-left");
is(marginProp.matchedRuleCount, 0,
"margin-left should not be included in matched selectors.");
let fontSizeProp = cssLogic.getPropertyInfo("font-size");
is(fontSizeProp.matchedRuleCount, 1,
"font-size should be included in matched selectors.");
SimpleTest.finish();
}
</script>
</body>
</html>

View File

@ -33,7 +33,7 @@ Test that css-logic handles media-queries correctly
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
var Services = require("Services");
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const {CssLogic} = require("devtools/server/css-logic");
SimpleTest.waitForExplicitFinish();

View File

@ -15,7 +15,7 @@ Test that css-logic calculates CSS specificity properly
var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const {CssLogic, CssSelector} = require("devtools/shared/inspector/css-logic");
const {CssLogic, CssSelector} = require("devtools/server/css-logic");
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
<script type="application/javascript;version=1.8">
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const {CssLogic} = require("devtools/server/css-logic");
window.onload = function() {
SimpleTest.waitForExplicitFinish();

View File

@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
<script type="application/javascript;version=1.8">
const inspector = require("devtools/server/actors/inspector");
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const CssLogic = require("devtools/shared/inspector/css-logic");
window.onload = function() {
SimpleTest.waitForExplicitFinish();

View File

@ -57,7 +57,6 @@ const childSpec = protocol.generateActorSpec({
echo: {
request: { str: Arg(0) },
response: { str: RetVal("string") },
telemetry: "ECHO"
},
getDetail1: {
// This also exercises return-value-as-packet.

View File

@ -234,8 +234,6 @@ const DebuggerClient = exports.DebuggerClient = function (aTransport)
* @param aPacketSkeleton
* The form of the packet to send. Can specify fields to be filled from
* the parameters by using the |args| function.
* @param telemetry
* The unique suffix of the telemetry histogram id.
* @param before
* The function to call before sending the packet. Is passed the packet,
* and the return value is used as the new packet. The |this| context is
@ -250,18 +248,8 @@ const DebuggerClient = exports.DebuggerClient = function (aTransport)
* we receive the response. (See request method for more details)
*/
DebuggerClient.requester = function (aPacketSkeleton, config = {}) {
let { telemetry, before, after } = config;
let { before, after } = config;
return DevToolsUtils.makeInfallible(function (...args) {
let histogram, startTime;
if (telemetry) {
let transportType = this._transport.onOutputStreamReady === undefined
? "LOCAL_"
: "REMOTE_";
let histogramId = "DEVTOOLS_DEBUGGER_RDP_"
+ transportType + telemetry + "_MS";
histogram = Services.telemetry.getHistogramById(histogramId);
startTime = +new Date;
}
let outgoingPacket = {
to: aPacketSkeleton.to || this.actor
};
@ -295,10 +283,6 @@ DebuggerClient.requester = function (aPacketSkeleton, config = {}) {
if (thisCallback) {
thisCallback(aResponse);
}
if (histogram) {
histogram.add(+new Date - startTime);
}
}, "DebuggerClient.requester request callback"));
}, "DebuggerClient.requester");
};
@ -649,8 +633,6 @@ DebuggerClient.prototype = {
release: DebuggerClient.requester({
to: args(0),
type: "release"
}, {
telemetry: "RELEASE"
}),
/**
@ -1314,7 +1296,6 @@ TabClient.prototype = {
this.client.unregisterClient(this);
return aResponse;
},
telemetry: "TABDETACH"
}),
/**
@ -1337,8 +1318,6 @@ TabClient.prototype = {
_reload: DebuggerClient.requester({
type: "reload",
options: args(0)
}, {
telemetry: "RELOAD"
}),
/**
@ -1350,8 +1329,6 @@ TabClient.prototype = {
navigateTo: DebuggerClient.requester({
type: "navigateTo",
url: args(0)
}, {
telemetry: "NAVIGATETO"
}),
/**
@ -1365,14 +1342,10 @@ TabClient.prototype = {
reconfigure: DebuggerClient.requester({
type: "reconfigure",
options: args(0)
}, {
telemetry: "RECONFIGURETAB"
}),
listWorkers: DebuggerClient.requester({
type: "listWorkers"
}, {
telemetry: "LISTWORKERS"
}),
attachWorker: function (aWorkerActor, aOnResponse) {
@ -1437,8 +1410,6 @@ WorkerClient.prototype = {
this.client.unregisterClient(this);
return aResponse;
},
telemetry: "WORKERDETACH"
}),
attachThread: function (aOptions = {}, aOnResponse = noop) {
@ -1530,7 +1501,6 @@ AddonClient.prototype = {
this._client.unregisterClient(this);
return aResponse;
},
telemetry: "ADDONDETACH"
})
};
@ -1571,8 +1541,7 @@ RootClient.prototype = {
* @param function aOnResponse
* Called with the response packet.
*/
listTabs: DebuggerClient.requester({ type: "listTabs" },
{ telemetry: "LISTTABS" }),
listTabs: DebuggerClient.requester({ type: "listTabs" }),
/**
* List the installed addons.
@ -1580,8 +1549,7 @@ RootClient.prototype = {
* @param function aOnResponse
* Called with the response packet.
*/
listAddons: DebuggerClient.requester({ type: "listAddons" },
{ telemetry: "LISTADDONS" }),
listAddons: DebuggerClient.requester({ type: "listAddons" }),
/**
* List the registered workers.
@ -1589,8 +1557,7 @@ RootClient.prototype = {
* @param function aOnResponse
* Called with the response packet.
*/
listWorkers: DebuggerClient.requester({ type: "listWorkers" },
{ telemetry: "LISTWORKERS" }),
listWorkers: DebuggerClient.requester({ type: "listWorkers" }),
/**
* List the registered service workers.
@ -1598,8 +1565,9 @@ RootClient.prototype = {
* @param function aOnResponse
* Called with the response packet.
*/
listServiceWorkerRegistrations: DebuggerClient.requester({ type: "listServiceWorkerRegistrations" },
{ telemetry: "LISTSERVICEWORKERREGISTRATIONS" }),
listServiceWorkerRegistrations: DebuggerClient.requester({
type: "listServiceWorkerRegistrations"
}),
/**
* List the running processes.
@ -1607,8 +1575,7 @@ RootClient.prototype = {
* @param function aOnResponse
* Called with the response packet.
*/
listProcesses: DebuggerClient.requester({ type: "listProcesses" },
{ telemetry: "LISTPROCESSES" }),
listProcesses: DebuggerClient.requester({ type: "listProcesses" }),
/**
* Fetch the TabActor for the currently selected tab, or for a specific
@ -1664,8 +1631,7 @@ RootClient.prototype = {
* @param function aOnResponse
* Called with the response packet.
*/
protocolDescription: DebuggerClient.requester({ type: "protocolDescription" },
{ telemetry: "PROTOCOLDESCRIPTION" }),
protocolDescription: DebuggerClient.requester({ type: "protocolDescription" }),
/*
* Methods constructed by DebuggerClient.requester require these forwards
@ -1757,7 +1723,6 @@ ThreadClient.prototype = {
}
return aResponse;
},
telemetry: "RESUME"
}),
/**
@ -1771,8 +1736,6 @@ ThreadClient.prototype = {
reconfigure: DebuggerClient.requester({
type: "reconfigure",
options: args(0)
}, {
telemetry: "RECONFIGURETHREAD"
}),
/**
@ -1851,8 +1814,6 @@ ThreadClient.prototype = {
_doInterrupt: DebuggerClient.requester({
type: "interrupt",
when: args(0)
}, {
telemetry: "INTERRUPT"
}),
/**
@ -1947,7 +1908,6 @@ ThreadClient.prototype = {
}
return aResponse;
},
telemetry: "CLIENTEVALUATE"
}),
/**
@ -1964,7 +1924,6 @@ ThreadClient.prototype = {
this._parent.thread = null;
return aResponse;
},
telemetry: "THREADDETACH"
}),
/**
@ -1978,8 +1937,6 @@ ThreadClient.prototype = {
releaseMany: DebuggerClient.requester({
type: "releaseMany",
actors: args(0),
}, {
telemetry: "RELEASEMANY"
}),
/**
@ -1991,8 +1948,6 @@ ThreadClient.prototype = {
threadGrips: DebuggerClient.requester({
type: "threadGrips",
actors: args(0)
}, {
telemetry: "THREADGRIPS"
}),
/**
@ -2003,8 +1958,6 @@ ThreadClient.prototype = {
*/
eventListeners: DebuggerClient.requester({
type: "eventListeners"
}, {
telemetry: "EVENTLISTENERS"
}),
/**
@ -2015,8 +1968,6 @@ ThreadClient.prototype = {
*/
getSources: DebuggerClient.requester({
type: "sources"
}, {
telemetry: "SOURCES"
}),
/**
@ -2046,8 +1997,6 @@ ThreadClient.prototype = {
type: "frames",
start: args(0),
count: args(1)
}, {
telemetry: "FRAMES"
}),
/**
@ -2264,8 +2213,6 @@ ThreadClient.prototype = {
getPrototypesAndProperties: DebuggerClient.requester({
type: "prototypesAndProperties",
actors: args(0)
}, {
telemetry: "PROTOTYPESANDPROPERTIES"
}),
events: ["newSource"]
@ -2310,7 +2257,6 @@ TraceClient.prototype = {
this._client.unregisterClient(this);
return aResponse;
},
telemetry: "TRACERDETACH"
}),
/**
@ -2343,7 +2289,6 @@ TraceClient.prototype = {
return aResponse;
},
telemetry: "STARTTRACE"
}),
/**
@ -2369,7 +2314,6 @@ TraceClient.prototype = {
return aResponse;
},
telemetry: "STOPTRACE"
})
};
@ -2433,7 +2377,6 @@ ObjectClient.prototype = {
}
return aPacket;
},
telemetry: "PARAMETERNAMES"
}),
/**
@ -2444,8 +2387,6 @@ ObjectClient.prototype = {
*/
getOwnPropertyNames: DebuggerClient.requester({
type: "ownPropertyNames"
}, {
telemetry: "OWNPROPERTYNAMES"
}),
/**
@ -2455,8 +2396,6 @@ ObjectClient.prototype = {
*/
getPrototypeAndProperties: DebuggerClient.requester({
type: "prototypeAndProperties"
}, {
telemetry: "PROTOTYPEANDPROPERTIES"
}),
/**
@ -2487,7 +2426,6 @@ ObjectClient.prototype = {
}
return aResponse;
},
telemetry: "ENUMPROPERTIES"
}),
/**
@ -2524,8 +2462,6 @@ ObjectClient.prototype = {
getProperty: DebuggerClient.requester({
type: "property",
name: args(0)
}, {
telemetry: "PROPERTY"
}),
/**
@ -2535,8 +2471,6 @@ ObjectClient.prototype = {
*/
getPrototype: DebuggerClient.requester({
type: "prototype"
}, {
telemetry: "PROTOTYPE"
}),
/**
@ -2546,8 +2480,6 @@ ObjectClient.prototype = {
*/
getDisplayString: DebuggerClient.requester({
type: "displayString"
}, {
telemetry: "DISPLAYSTRING"
}),
/**
@ -2564,7 +2496,6 @@ ObjectClient.prototype = {
}
return aPacket;
},
telemetry: "SCOPE"
}),
/**
@ -2733,8 +2664,6 @@ LongStringClient.prototype = {
type: "substring",
start: args(0),
end: args(1)
}, {
telemetry: "SUBSTRING"
}),
};
@ -2783,7 +2712,6 @@ SourceClient.prototype = {
blackBox: DebuggerClient.requester({
type: "blackbox"
}, {
telemetry: "BLACKBOX",
after: function (aResponse) {
if (!aResponse.error) {
this._isBlackBoxed = true;
@ -2804,7 +2732,6 @@ SourceClient.prototype = {
unblackBox: DebuggerClient.requester({
type: "unblackbox"
}, {
telemetry: "UNBLACKBOX",
after: function (aResponse) {
if (!aResponse.error) {
this._isBlackBoxed = false;
@ -3028,8 +2955,6 @@ BreakpointClient.prototype = {
*/
remove: DebuggerClient.requester({
type: "delete"
}, {
telemetry: "DELETE"
}),
/**
@ -3136,8 +3061,6 @@ EnvironmentClient.prototype = {
*/
getBindings: DebuggerClient.requester({
type: "bindings"
}, {
telemetry: "BINDINGS"
}),
/**
@ -3148,8 +3071,6 @@ EnvironmentClient.prototype = {
type: "assign",
name: args(0),
value: args(1)
}, {
telemetry: "ASSIGN"
})
};

View File

@ -4,7 +4,7 @@
"use strict";
const { Cc, Ci, Cr } = require("chrome");
const { Cc, Ci, Cr, Cu } = require("chrome");
const l10n = require("gcli/l10n");
const Services = require("Services");
const { NetUtil } = require("resource://gre/modules/NetUtil.jsm");
@ -191,7 +191,7 @@ exports.items = [
]
},
],
exec: function(args, context) {
exec: function (args, context) {
if (args.chrome && args.selector) {
// Node screenshot with chrome option does not work as intended
// Refer https://bugzilla.mozilla.org/show_bug.cgi?id=659268#c7
@ -209,7 +209,7 @@ exports.items = [
} else {
capture = captureScreenshot(args, context.environment.chromeDocument);
}
simulateCameraEffect(context.environment.chromeDocument, "shutter");
return capture.then(saveScreenshot.bind(null, args, context));
},
},
@ -220,12 +220,27 @@ exports.items = [
hidden: true,
returnType: "imageSummary",
params: [ filenameParam, standardParams ],
exec: function(args, context) {
exec: function (args, context) {
return captureScreenshot(args, context.environment.document);
},
}
];
/**
* This function is called to simulate camera effects
*/
function simulateCameraEffect(document, effect) {
let window = document.defaultView;
if (effect === "shutter") {
const audioCamera = new window.Audio("resource://devtools/client/themes/audio/shutter.wav");
audioCamera.play();
}
if (effect == "flash") {
const frames = Cu.cloneInto({ opacity: [ 0, 1 ] }, window);
document.documentElement.animate(frames, 500);
}
}
/**
* This function simply handles the --delay argument before calling
* createScreenshotData
@ -321,6 +336,8 @@ function createScreenshotData(document, args) {
window.scrollTo(currentX, currentY);
}
simulateCameraEffect(document, "flash");
return Promise.resolve({
destinations: [],
data: data,

File diff suppressed because it is too large Load Diff

View File

@ -934,7 +934,6 @@ exports.Actor = Actor;
* request (object): a request template.
* response (object): a response template.
* oneway (bool): 'true' if no response should be sent.
* telemetry (string): Telemetry probe ID for measuring completion time.
*/
exports.method = function (fn, spec = {}) {
fn._methodSpec = Object.freeze(spec);
@ -976,7 +975,6 @@ var generateActorSpec = function (actorDesc) {
spec.name = methodSpec.name || name;
spec.request = Request(object.merge({type: spec.name}, methodSpec.request || undefined));
spec.response = Response(methodSpec.response || undefined);
spec.telemetry = methodSpec.telemetry;
spec.release = methodSpec.release;
spec.oneway = methodSpec.oneway;
@ -993,7 +991,6 @@ var generateActorSpec = function (actorDesc) {
spec.name = methodSpec.name || name;
spec.request = Request(object.merge({type: spec.name}, methodSpec.request || undefined));
spec.response = Response(methodSpec.response || undefined);
spec.telemetry = methodSpec.telemetry;
spec.release = methodSpec.release;
spec.oneway = methodSpec.oneway;
@ -1346,27 +1343,6 @@ var generateRequestMethods = function (actorSpec, frontProto) {
}
frontProto[name] = function (...args) {
let histogram, startTime;
if (spec.telemetry) {
if (spec.oneway) {
// That just doesn't make sense.
throw Error("Telemetry specified for a oneway request");
}
let transportType = this.conn.localTransport
? "LOCAL_"
: "REMOTE_";
let histogramId = "DEVTOOLS_DEBUGGER_RDP_"
+ transportType + spec.telemetry + "_MS";
try {
histogram = Services.telemetry.getHistogramById(histogramId);
startTime = new Date();
} catch (ex) {
// XXX: Is this expected in xpcshell tests?
console.error(ex);
spec.telemetry = false;
}
}
let packet;
try {
packet = spec.request.write(args, this);
@ -1388,11 +1364,6 @@ var generateRequestMethods = function (actorSpec, frontProto) {
console.error("Error reading response to: " + name);
throw ex;
}
if (histogram) {
histogram.add(+new Date - startTime);
}
return ret;
});
};

View File

@ -12,7 +12,6 @@ const addonsSpec = generateActorSpec({
installTemporaryAddon: {
request: { addonPath: Arg(0, "string") },
response: { addon: RetVal("json") },
telemetry: "INSTALL_TEMPORARY_ADDON"
},
},
});

View File

@ -5,7 +5,7 @@
"use strict";
const {CssLogic} = require("devtools/shared/inspector/css-logic");
const {prettifyCSS} = require("devtools/shared/inspector/css-logic");
const TESTS = [
{ name: "simple test",
@ -52,17 +52,17 @@ const TESTS = [
];
function run_test() {
// Note that CssLogic.LINE_SEPARATOR is computed lazily, so we
// Note that prettifyCSS.LINE_SEPARATOR is computed lazily, so we
// ensure it is set.
CssLogic.prettifyCSS("");
prettifyCSS("");
for (let test of TESTS) {
do_print(test.name);
let input = test.input.split("\n").join(CssLogic.LINE_SEPARATOR);
let output = CssLogic.prettifyCSS(input);
let expected = test.expected.join(CssLogic.LINE_SEPARATOR) +
CssLogic.LINE_SEPARATOR;
let input = test.input.split("\n").join(prettifyCSS.LINE_SEPARATOR);
let output = prettifyCSS(input);
let expected = test.expected.join(prettifyCSS.LINE_SEPARATOR) +
prettifyCSS.LINE_SEPARATOR;
equal(output, expected, test.name);
}
}

View File

@ -1579,8 +1579,6 @@ nsDocument::~nsDocument()
}
Accumulate(Telemetry::MIXED_CONTENT_PAGE_LOAD, mixedContentLevel);
Accumulate(Telemetry::SCROLL_LINKED_EFFECT_FOUND, mHasScrollLinkedEffect);
// record mixed object subrequest telemetry
if (mHasMixedContentObjectSubrequest) {
/* mixed object subrequest loaded on page*/
@ -4799,7 +4797,9 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
}
MaybeRescheduleAnimationFrameNotifications();
mRegistry = new Registry();
if (Preferences::GetBool("dom.webcomponents.enabled")) {
mRegistry = new Registry();
}
}
// Remember the pointer to our window (or lack there of), to avoid
@ -5695,8 +5695,10 @@ nsDocument::CreateElement(const nsAString& aTagName,
return nullptr;
}
if (!aTagName.Equals(aTypeExtension)) {
// Custom element type can not extend itself.
if (!aTypeExtension.IsVoid() &&
!aTagName.Equals(aTypeExtension)) {
// do not process 'is' if it is null or the extended type is the same as
// the localName
SetupCustomElement(elem, GetDefaultNamespaceID(), &aTypeExtension);
}
@ -5753,6 +5755,13 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
return nullptr;
}
if (aTypeExtension.IsVoid() ||
aQualifiedName.Equals(aTypeExtension)) {
// do not process 'is' if it is null or the extended type is the same as
// the localName
return elem.forget();
}
int32_t nameSpaceId = kNameSpaceID_Wildcard;
if (!aNamespaceURI.EqualsLiteral("*")) {
rv = nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
@ -5762,10 +5771,7 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
}
}
if (!aQualifiedName.Equals(aTypeExtension)) {
// A custom element type can not extend itself.
SetupCustomElement(elem, nameSpaceId, &aTypeExtension);
}
SetupCustomElement(elem, nameSpaceId, &aTypeExtension);
return elem.forget();
}

View File

@ -249,15 +249,7 @@ class TestWebIDLCodegenManager(unittest.TestCase):
args = self._get_manager_args()
m1 = WebIDLCodegenManager(**args)
with MockedOpen({fake_path: '# Original content'}):
old_exists = os.path.exists
try:
def exists(p):
if p == fake_path:
return True
return old_exists(p)
os.path.exists = exists
result = m1.generate_build_files()
l = len(result.inputs)
@ -271,7 +263,6 @@ class TestWebIDLCodegenManager(unittest.TestCase):
result = m2.generate_build_files()
self.assertEqual(len(result.inputs), 0)
finally:
os.path.exists = old_exists
del sys.modules['mozwebidlcodegen.fakemodule']
def test_copy_input(self):

View File

@ -57,7 +57,8 @@ HttpServer::Init(int32_t aPort, bool aHttps, HttpServerListener* aListener)
if (mHttps) {
nsCOMPtr<nsILocalCertService> lcs =
do_CreateInstance("@mozilla.org/security/local-cert-service;1");
nsresult rv = lcs->GetOrCreateCert(NS_LITERAL_CSTRING("flyweb"), this);
nsresult rv = lcs->GetOrCreateCert(NS_LITERAL_CSTRING("flyweb"), this,
nsILocalCertService::KEY_TYPE_EC);
if (NS_FAILED(rv)) {
NotifyStarted(rv);
}

View File

@ -4,56 +4,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/.
EXPORTS.mozilla.dom += [
'Gamepad.h',
'GamepadButton.h',
'GamepadManager.h',
'GamepadMonitoring.h',
'GamepadPlatformService.h',
'GamepadServiceTest.h',
'ipc/GamepadEventChannelChild.h',
'ipc/GamepadEventChannelParent.h',
'ipc/GamepadTestChannelChild.h',
'ipc/GamepadTestChannelParent.h'
]
UNIFIED_SOURCES = [
'Gamepad.cpp',
'GamepadButton.cpp',
'GamepadManager.cpp',
'GamepadMonitoring.cpp',
'GamepadPlatformService.cpp',
'GamepadServiceTest.cpp',
'ipc/GamepadEventChannelChild.cpp',
'ipc/GamepadEventChannelParent.cpp',
'ipc/GamepadTestChannelChild.cpp',
'ipc/GamepadTestChannelParent.cpp'
]
if CONFIG['MOZ_GAMEPAD_BACKEND'] == 'stub':
UNIFIED_SOURCES += [
'fallback/FallbackGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'cocoa':
UNIFIED_SOURCES += [
'cocoa/CocoaGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'windows':
UNIFIED_SOURCES += [
'windows/WindowsGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'linux':
UNIFIED_SOURCES += [
'linux/LinuxGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'android':
UNIFIED_SOURCES += [
'android/AndroidGamepad.cpp'
]
LOCAL_INCLUDES += [
'ipc',
]
IPDL_SOURCES += [
'ipc/GamepadEventTypes.ipdlh',
@ -61,14 +11,66 @@ IPDL_SOURCES += [
'ipc/PGamepadTestChannel.ipdl'
]
include('/ipc/chromium/chromium-config.mozbuild')
if CONFIG['MOZ_GAMEPAD']:
EXPORTS.mozilla.dom += [
'Gamepad.h',
'GamepadButton.h',
'GamepadManager.h',
'GamepadMonitoring.h',
'GamepadPlatformService.h',
'GamepadServiceTest.h',
'ipc/GamepadEventChannelChild.h',
'ipc/GamepadEventChannelParent.h',
'ipc/GamepadTestChannelChild.h',
'ipc/GamepadTestChannelParent.h'
]
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
]
UNIFIED_SOURCES = [
'Gamepad.cpp',
'GamepadButton.cpp',
'GamepadManager.cpp',
'GamepadMonitoring.cpp',
'GamepadPlatformService.cpp',
'GamepadServiceTest.cpp',
'ipc/GamepadEventChannelChild.cpp',
'ipc/GamepadEventChannelParent.cpp',
'ipc/GamepadTestChannelChild.cpp',
'ipc/GamepadTestChannelParent.cpp'
]
CFLAGS += CONFIG['GLIB_CFLAGS']
CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
if CONFIG['MOZ_GAMEPAD_BACKEND'] == 'stub':
UNIFIED_SOURCES += [
'fallback/FallbackGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'cocoa':
UNIFIED_SOURCES += [
'cocoa/CocoaGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'windows':
UNIFIED_SOURCES += [
'windows/WindowsGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'linux':
UNIFIED_SOURCES += [
'linux/LinuxGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'android':
UNIFIED_SOURCES += [
'android/AndroidGamepad.cpp'
]
LOCAL_INCLUDES += [
'ipc',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
]
CFLAGS += CONFIG['GLIB_CFLAGS']
CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']

View File

@ -304,7 +304,7 @@ public:
private:
RefPtr<HTMLMediaElement> mElement;
nsCOMPtr<nsIStreamListener> mNextListener;
uint32_t mLoadID;
const uint32_t mLoadID;
};
NS_IMPL_ISUPPORTS(HTMLMediaElement::MediaLoadListener, nsIRequestObserver,
@ -313,7 +313,8 @@ NS_IMPL_ISUPPORTS(HTMLMediaElement::MediaLoadListener, nsIRequestObserver,
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::Observe(nsISupports* aSubject,
const char* aTopic, const char16_t* aData)
const char* aTopic,
const char16_t* aData)
{
nsContentUtils::UnregisterShutdownObserver(this);
@ -322,21 +323,9 @@ HTMLMediaElement::MediaLoadListener::Observe(nsISupports* aSubject,
return NS_OK;
}
void HTMLMediaElement::ReportLoadError(const char* aMsg,
const char16_t** aParams,
uint32_t aParamCount)
{
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("Media"),
OwnerDoc(),
nsContentUtils::eDOM_PROPERTIES,
aMsg,
aParams,
aParamCount);
}
NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest,
nsISupports* aContext)
{
nsContentUtils::UnregisterShutdownObserver(this);
@ -394,14 +383,12 @@ NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aR
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (channel &&
element &&
NS_SUCCEEDED(rv = element->InitializeDecoderForChannel(channel, getter_AddRefs(mNextListener))) &&
mNextListener) {
rv = mNextListener->OnStartRequest(aRequest, aContext);
} else {
// If InitializeDecoderForChannel() returned an error, fire a network
// error.
if (NS_FAILED(rv) && !mNextListener && element) {
// If InitializeDecoderForChannel() returned an error, fire a network error.
if (NS_FAILED(rv) && !mNextListener) {
// Load failed, attempt to load the next candidate resource. If there
// are none, this will trigger a MEDIA_ERR_SRC_NOT_SUPPORTED error.
element->NotifyLoadError();
@ -415,8 +402,10 @@ NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aR
return rv;
}
NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
nsresult aStatus)
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatus)
{
if (mNextListener) {
return mNextListener->OnStopRequest(aRequest, aContext, aStatus);
@ -438,27 +427,210 @@ HTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest* aRequest,
return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, aCount);
}
NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
uint32_t aFlags,
nsIAsyncVerifyRedirectCallback* cb)
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
uint32_t aFlags,
nsIAsyncVerifyRedirectCallback* cb)
{
// TODO is this really correct?? See bug #579329.
if (mElement)
if (mElement) {
mElement->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
}
nsCOMPtr<nsIChannelEventSink> sink = do_QueryInterface(mNextListener);
if (sink)
if (sink) {
return sink->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, cb);
}
cb->OnRedirectVerifyCallback(NS_OK);
return NS_OK;
}
NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::GetInterface(const nsIID & aIID, void **aResult)
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::GetInterface(const nsIID& aIID,
void** aResult)
{
return QueryInterface(aIID, aResult);
}
void HTMLMediaElement::ReportLoadError(const char* aMsg,
const char16_t** aParams,
uint32_t aParamCount)
{
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("Media"),
OwnerDoc(),
nsContentUtils::eDOM_PROPERTIES,
aMsg,
aParams,
aParamCount);
}
class HTMLMediaElement::ChannelLoader final {
public:
NS_INLINE_DECL_REFCOUNTING(ChannelLoader);
void LoadInternal(HTMLMediaElement* aElement)
{
if (mCancelled) {
return;
}
// determine what security checks need to be performed in AsyncOpen2().
nsSecurityFlags securityFlags = aElement->ShouldCheckAllowOrigin()
? nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS :
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
if (aElement->GetCORSMode() == CORS_USE_CREDENTIALS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
}
MOZ_ASSERT(aElement->IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video));
nsContentPolicyType contentPolicyType = aElement->IsHTMLElement(nsGkAtoms::audio)
? nsIContentPolicy::TYPE_INTERNAL_AUDIO :
nsIContentPolicy::TYPE_INTERNAL_VIDEO;
nsCOMPtr<nsIDocShell> docShell = aElement->OwnerDoc()->GetDocShell();
if (docShell) {
nsDocShell* docShellPtr = nsDocShell::Cast(docShell);
bool privateBrowsing;
docShellPtr->GetUsePrivateBrowsing(&privateBrowsing);
if (privateBrowsing) {
securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
}
}
nsCOMPtr<nsILoadGroup> loadGroup = aElement->GetDocumentLoadGroup();
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
aElement->mLoadingSrc,
static_cast<Element*>(aElement),
securityFlags,
contentPolicyType,
loadGroup,
nullptr, // aCallbacks
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE |
nsIChannel::LOAD_CLASSIFY_URI |
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS);
if (NS_FAILED(rv)) {
// Notify load error so the element will try next resource candidate.
aElement->NotifyLoadError();
return;
}
// This is a workaround and it will be fix in bug 1264230.
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo) {
NeckoOriginAttributes originAttrs;
NS_GetOriginAttributes(channel, originAttrs);
loadInfo->SetOriginAttributes(originAttrs);
}
// The listener holds a strong reference to us. This creates a
// reference cycle, once we've set mChannel, which is manually broken
// in the listener's OnStartRequest method after it is finished with
// the element. The cycle will also be broken if we get a shutdown
// notification before OnStartRequest fires. Necko guarantees that
// OnStartRequest will eventually fire if we don't shut down first.
RefPtr<MediaLoadListener> loadListener = new MediaLoadListener(aElement);
channel->SetNotificationCallbacks(loadListener);
nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(channel);
if (hc) {
// Use a byte range request from the start of the resource.
// This enables us to detect if the stream supports byte range
// requests, and therefore seeking, early.
hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
NS_LITERAL_CSTRING("bytes=0-"),
false);
aElement->SetRequestHeaders(hc);
}
rv = channel->AsyncOpen2(loadListener);
if (NS_FAILED(rv)) {
// Notify load error so the element will try next resource candidate.
aElement->NotifyLoadError();
return;
}
// Else the channel must be open and starting to download. If it encounters
// a non-catastrophic failure, it will set a new task to continue loading
// another candidate. It's safe to set it as mChannel now.
mChannel = channel;
// loadListener will be unregistered either on shutdown or when
// OnStartRequest for the channel we just opened fires.
nsContentUtils::RegisterShutdownObserver(loadListener);
}
nsresult Load(HTMLMediaElement* aElement)
{
// Per bug 1235183 comment 8, we can't spin the event loop from stable
// state. Defer NS_NewChannel() to a new regular runnable.
return NS_DispatchToMainThread(NewRunnableMethod<HTMLMediaElement*>(
this, &ChannelLoader::LoadInternal, aElement));
}
void Cancel()
{
mCancelled = true;
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
mChannel = nullptr;
}
}
void Done() {
MOZ_ASSERT(mChannel);
// Decoder successfully created, the decoder now owns the MediaResource
// which owns the channel.
mChannel = nullptr;
}
nsresult Redirect(nsIChannel* aChannel,
nsIChannel* aNewChannel,
uint32_t aFlags)
{
NS_ASSERTION(aChannel == mChannel, "Channels should match!");
mChannel = aNewChannel;
// Handle forwarding of Range header so that the intial detection
// of seeking support (via result code 206) works across redirects.
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aChannel);
NS_ENSURE_STATE(http);
NS_NAMED_LITERAL_CSTRING(rangeHdr, "Range");
nsAutoCString rangeVal;
if (NS_SUCCEEDED(http->GetRequestHeader(rangeHdr, rangeVal))) {
NS_ENSURE_STATE(!rangeVal.IsEmpty());
http = do_QueryInterface(aNewChannel);
NS_ENSURE_STATE(http);
nsresult rv = http->SetRequestHeader(rangeHdr, rangeVal, false);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
private:
~ChannelLoader()
{
MOZ_ASSERT(!mChannel);
}
// Holds a reference to the first channel we open to the media resource.
// Once the decoder is created, control over the channel passes to the
// decoder, and we null out this reference. We must store this in case
// we need to cancel the channel before control of it passes to the decoder.
nsCOMPtr<nsIChannel> mChannel;
bool mCancelled = false;
};
NS_IMPL_ADDREF_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_RELEASE_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
@ -672,28 +844,8 @@ HTMLMediaElement::OnChannelRedirect(nsIChannel* aChannel,
nsIChannel* aNewChannel,
uint32_t aFlags)
{
NS_ASSERTION(aChannel == mChannel, "Channels should match!");
mChannel = aNewChannel;
// Handle forwarding of Range header so that the intial detection
// of seeking support (via result code 206) works across redirects.
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aChannel);
NS_ENSURE_STATE(http);
NS_NAMED_LITERAL_CSTRING(rangeHdr, "Range");
nsAutoCString rangeVal;
if (NS_SUCCEEDED(http->GetRequestHeader(rangeHdr, rangeVal))) {
NS_ENSURE_STATE(!rangeVal.IsEmpty());
http = do_QueryInterface(aNewChannel);
NS_ENSURE_STATE(http);
nsresult rv = http->SetRequestHeader(rangeHdr, rangeVal, false);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
MOZ_ASSERT(mChannelLoader);
return mChannelLoader->Redirect(aChannel, aNewChannel, aFlags);
}
void HTMLMediaElement::ShutdownDecoder()
@ -721,6 +873,11 @@ void HTMLMediaElement::AbortExistingLoads()
// with a different load ID to silently be cancelled.
mCurrentLoadID++;
if (mChannelLoader) {
mChannelLoader->Cancel();
mChannelLoader = nullptr;
}
bool fireTimeUpdate = false;
// When aborting the existing loads, empty the objects in audio track list and
@ -1250,9 +1407,9 @@ nsresult HTMLMediaElement::LoadResource()
NS_ASSERTION(mDelayingLoadEvent,
"Should delay load event (if in document) during load");
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
mChannel = nullptr;
if (mChannelLoader) {
mChannelLoader->Cancel();
mChannelLoader = nullptr;
}
// Check if media is allowed for the docshell.
@ -1308,87 +1465,12 @@ nsresult HTMLMediaElement::LoadResource()
return FinishDecoderSetup(decoder, resource, nullptr);
}
// determine what security checks need to be performed in AsyncOpen2().
nsSecurityFlags securityFlags =
ShouldCheckAllowOrigin() ? nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS :
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
if (GetCORSMode() == CORS_USE_CREDENTIALS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
RefPtr<ChannelLoader> loader = new ChannelLoader;
nsresult rv = loader->Load(this);
if (NS_SUCCEEDED(rv)) {
mChannelLoader = loader.forget();
}
MOZ_ASSERT(IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video));
nsContentPolicyType contentPolicyType = IsHTMLElement(nsGkAtoms::audio) ?
nsIContentPolicy::TYPE_INTERNAL_AUDIO : nsIContentPolicy::TYPE_INTERNAL_VIDEO;
nsDocShell* docShellPtr;
if (docShell) {
docShellPtr = nsDocShell::Cast(docShell);
bool privateBrowsing;
docShellPtr->GetUsePrivateBrowsing(&privateBrowsing);
if (privateBrowsing) {
securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
}
}
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
mLoadingSrc,
static_cast<Element*>(this),
securityFlags,
contentPolicyType,
loadGroup,
nullptr, // aCallbacks
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE |
nsIChannel::LOAD_CLASSIFY_URI |
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS);
NS_ENSURE_SUCCESS(rv,rv);
// This is a workaround and it will be fix in bug 1264230.
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo) {
NeckoOriginAttributes originAttrs;
NS_GetOriginAttributes(channel, originAttrs);
loadInfo->SetOriginAttributes(originAttrs);
}
// The listener holds a strong reference to us. This creates a
// reference cycle, once we've set mChannel, which is manually broken
// in the listener's OnStartRequest method after it is finished with
// the element. The cycle will also be broken if we get a shutdown
// notification before OnStartRequest fires. Necko guarantees that
// OnStartRequest will eventually fire if we don't shut down first.
RefPtr<MediaLoadListener> loadListener = new MediaLoadListener(this);
channel->SetNotificationCallbacks(loadListener);
nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(channel);
if (hc) {
// Use a byte range request from the start of the resource.
// This enables us to detect if the stream supports byte range
// requests, and therefore seeking, early.
hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
NS_LITERAL_CSTRING("bytes=0-"),
false);
SetRequestHeaders(hc);
}
rv = channel->AsyncOpen2(loadListener);
NS_ENSURE_SUCCESS(rv, rv);
// Else the channel must be open and starting to download. If it encounters
// a non-catastrophic failure, it will set a new task to continue loading
// another candidate. It's safe to set it as mChannel now.
mChannel = channel;
// loadListener will be unregistered either on shutdown or when
// OnStartRequest for the channel we just opened fires.
nsContentUtils::RegisterShutdownObserver(loadListener);
return NS_OK;
return rv;
}
nsresult HTMLMediaElement::LoadWithChannel(nsIChannel* aChannel,
@ -2400,8 +2482,8 @@ HTMLMediaElement::~HTMLMediaElement()
NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
"Destroyed media element should no longer be in element table");
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
if (mChannelLoader) {
mChannelLoader->Cancel();
}
WakeLockRelease();
@ -3056,8 +3138,10 @@ nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
if (!resource)
return NS_ERROR_OUT_OF_MEMORY;
// stream successfully created, the stream now owns the channel.
mChannel = nullptr;
if (mChannelLoader) {
mChannelLoader->Done();
mChannelLoader = nullptr;
}
// We postpone the |FinishDecoderSetup| function call until we get
// |OnConnected| signal from MediaStreamController which is held by
@ -3121,13 +3205,20 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
#ifdef MOZ_EME
if (mMediaKeys) {
mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
if (mMediaKeys->GetCDMProxy()) {
mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
} else {
// CDM must have crashed.
ShutdownDecoder();
return NS_ERROR_FAILURE;
}
}
#endif
// Decoder successfully created, the decoder now owns the MediaResource
// which owns the channel.
mChannel = nullptr;
if (mChannelLoader) {
mChannelLoader->Done();
mChannelLoader = nullptr;
}
AddMediaElementToURITable();
@ -5411,6 +5502,12 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
// 5.3. If mediaKeys is not null, run the following steps:
if (aMediaKeys) {
if (!aMediaKeys->GetCDMProxy()) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("CDM crashed before binding MediaKeys object to HTMLMediaElement"));
return promise.forget();
}
// 5.3.1 Associate the CDM instance represented by mediaKeys with the
// media element for decrypting media data.
if (NS_FAILED(aMediaKeys->Bind(this))) {

View File

@ -732,6 +732,7 @@ public:
protected:
virtual ~HTMLMediaElement();
class ChannelLoader;
class MediaLoadListener;
class MediaStreamTracksAvailableCallback;
class MediaStreamTrackListener;
@ -1255,11 +1256,7 @@ protected:
// that resolved to a MediaSource.
RefPtr<MediaSource> mMediaSource;
// Holds a reference to the first channel we open to the media resource.
// Once the decoder is created, control over the channel passes to the
// decoder, and we null out this reference. We must store this in case
// we need to cancel the channel before control of it passes to the decoder.
nsCOMPtr<nsIChannel> mChannel;
RefPtr<ChannelLoader> mChannelLoader;
// Error attribute
RefPtr<MediaError> mError;

View File

@ -1713,6 +1713,7 @@ void
MediaDecoder::SetCDMProxy(CDMProxy* aProxy)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aProxy);
mCDMProxyPromiseHolder.ResolveIfExists(aProxy, __func__);
}

View File

@ -22,8 +22,8 @@ already_AddRefed<MediaDataDecoder>
GonkDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
{
RefPtr<MediaDataDecoder> decoder =
new GonkMediaDataDecoder(new GonkVideoDecoderManager(aImageContainer, aConfig),
aCallback);
new GonkMediaDataDecoder(new GonkVideoDecoderManager(aParams.mImageContainer, aParams.VideoConfig()),
aParams.mCallback);
return decoder.forget();
}
@ -31,8 +31,8 @@ already_AddRefed<MediaDataDecoder>
GonkDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
{
RefPtr<MediaDataDecoder> decoder =
new GonkMediaDataDecoder(new GonkAudioDecoderManager(aConfig),
aCallback);
new GonkMediaDataDecoder(new GonkAudioDecoderManager(aParams.AudioConfig()),
aParams.mCallback);
return decoder.forget();
}

View File

@ -61,6 +61,7 @@ DIRS += [
'filesystem',
'flyweb',
'fmradio',
'gamepad',
'geolocation',
'html',
'icc',
@ -135,9 +136,6 @@ if CONFIG['MOZ_B2G_RIL']:
if CONFIG['MOZ_PAY']:
DIRS += ['payment']
if CONFIG['MOZ_GAMEPAD']:
DIRS += ['gamepad']
if CONFIG['MOZ_NFC']:
DIRS += ['nfc']

View File

@ -5,6 +5,7 @@ support-files =
[test_bug900724.html]
[test_bug1017896.html]
[test_bug1176757.html]
[test_bug1276240.html]
[test_content_element.html]
[test_custom_element_adopt_callbacks.html]
[test_custom_element_callback_innerhtml.html]

View File

@ -0,0 +1,55 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
-->
<head>
<title>Test for Bug 1276240</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1276240">Mozilla Bug 1276240</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 1276240 **/
// when passing null for the second argument, it would be ignored
function test() {
var e = document.createElement("p", null);
is(e.getAttribute("is"), null);
e = document.createElement("p", undefined);
is(e.getAttribute("is"), null);
e = document.createElementNS("http://www.w3.org/1999/xhtml", "p", null);
is(e.getAttribute("is"), null);
e = document.createElementNS("http://www.w3.org/1999/xhtml", "p", undefined);
is(e.getAttribute("is"), null);
}
function runTest() {
test();
SimpleTest.finish();
}
// test with webcomponents enabled
test();
// test with webcomponents disabled
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ 'set': [["dom.webcomponents.enabled", false]]}, runTest);
</script>
</pre>
</body>
</html>

View File

@ -263,9 +263,9 @@ partial interface Document {
//http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-document-register
partial interface Document {
[NewObject, Throws]
Element createElement(DOMString localName, DOMString typeExtension);
Element createElement(DOMString localName, DOMString? typeExtension);
[NewObject, Throws]
Element createElementNS(DOMString? namespace, DOMString qualifiedName, DOMString typeExtension);
Element createElementNS(DOMString? namespace, DOMString qualifiedName, DOMString? typeExtension);
};
// http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#sec-document-interface

View File

@ -1982,12 +1982,12 @@ Layer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
ToString(anchor).c_str()).get();
}
if (GetIsStickyPosition()) {
aStream << nsPrintfCString(" [isStickyPosition scrollId=%d outer=%f,%f %fx%f "
"inner=%f,%f %fx%f]", mStickyPositionData->mScrollId,
aStream << nsPrintfCString(" [isStickyPosition scrollId=%d outer=(%.3f,%.3f)-(%.3f,%.3f) "
"inner=(%.3f,%.3f)-(%.3f,%.3f)]", mStickyPositionData->mScrollId,
mStickyPositionData->mOuter.x, mStickyPositionData->mOuter.y,
mStickyPositionData->mOuter.width, mStickyPositionData->mOuter.height,
mStickyPositionData->mOuter.XMost(), mStickyPositionData->mOuter.YMost(),
mStickyPositionData->mInner.x, mStickyPositionData->mInner.y,
mStickyPositionData->mInner.width, mStickyPositionData->mInner.height).get();
mStickyPositionData->mInner.XMost(), mStickyPositionData->mInner.YMost()).get();
}
if (mMaskLayer) {
aStream << nsPrintfCString(" [mMaskLayer=%p]", mMaskLayer.get()).get();

View File

@ -96,6 +96,25 @@ function findRcdNode(apzcTree) {
return null;
}
// Return whether an element whose id includes |elementId| has been layerized.
// Assumes |elementId| will be present in the content description for the
// element, and not in the content descriptions of other elements.
function isLayerized(elementId) {
var contentTestData = SpecialPowers.getDOMWindowUtils(window).getContentAPZTestData();
ok(contentTestData.paints.length > 0, "expected at least one paint");
var seqno = contentTestData.paints[contentTestData.paints.length - 1].sequenceNumber;
contentTestData = convertTestData(contentTestData);
var paint = contentTestData.paints[seqno];
for (var scrollId in paint) {
if ("contentDescription" in paint[scrollId]) {
if (paint[scrollId]["contentDescription"].includes(elementId)) {
return true;
}
}
}
return false;
}
function flushApzRepaints(aCallback, aWindow = window) {
if (!aCallback) {
throw "A callback must be provided!";

Some files were not shown because too many files have changed in this diff Show More