Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-02-25 11:59:56 +01:00
commit efcd855704
440 changed files with 22171 additions and 18135 deletions

View File

@ -66,19 +66,19 @@ CLOBBER: $(topsrcdir)/CLOBBER
@exit 1
endif
$(topsrcdir)/configure: $(topsrcdir)/configure.in
$(topsrcdir)/js/src/configure: $(topsrcdir)/js/src/configure.in
$(topsrcdir)/configure: $(topsrcdir)/configure.in $(topsrcdir)/old-configure.in
$(topsrcdir)/js/src/configure: $(topsrcdir)/js/src/configure.in $(topsrcdir)/js/src/old-configure.in
$(topsrcdir)/configure $(topsrcdir)/js/src/configure:
@echo 'STOP! $^ has changed, and your configure is out of date.'
@echo 'STOP! $? has changed, and your configure is out of date.'
@echo 'Please rerun autoconf and re-configure your build directory.'
@echo 'To ignore this message, touch "$@",'
@echo 'but your build might not succeed.'
@exit 1
config.status: $(configure_dir)/configure
js/src/config.status: $(topsrcdir)/js/src/configure
config.status: $(configure_dir)/configure $(configure_dir)/old-configure
js/src/config.status: $(topsrcdir)/js/src/configure $(topsrcdir)/js/src/old-configure
config.status js/src/config.status:
@echo 'STOP! $^ has changed and needs to be run again.'
@echo 'STOP! $? has changed and needs to be run again.'
@echo 'Please rerun it.'
@echo 'To ignore this message, touch "$(CURDIR)/$@",'
@echo 'but your build might not succeed.'

View File

@ -107,9 +107,14 @@ TreeWalker::Next(ChildrenIterator* aIter, Accessible** aAccesible,
*aSkipSubtree = false;
if (childEl) {
Accessible* accessible = mFlags & eWalkCache ?
mDoc->GetAccessible(childEl) :
GetAccService()->GetOrCreateAccessible(childEl, mContext, aSkipSubtree);
Accessible* accessible = nullptr;
if (mFlags & eWalkCache) {
accessible = mDoc->GetAccessible(childEl);
}
else if (mContext->IsAcceptableChild(childEl)) {
accessible = GetAccService()->
GetOrCreateAccessible(childEl, mContext, aSkipSubtree);
}
// Ignore the accessible and its subtree if it was repositioned by means of
// aria-owns.

View File

@ -1105,9 +1105,6 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
}
newAcc = CreateAccessibleByFrameType(frame, content, aContext);
if (!aContext->IsAcceptableChild(newAcc))
return nullptr;
document->BindToDocument(newAcc, nullptr);
newAcc->AsTextLeaf()->SetText(text.mString);
return newAcc;
@ -1131,9 +1128,6 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
}
newAcc = new HyperTextAccessibleWrap(content, document);
if (!aContext->IsAcceptableChild(newAcc))
return nullptr;
document->BindToDocument(newAcc, aria::GetRoleMap(aNode));
return newAcc;
}
@ -1291,10 +1285,9 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
}
}
if (!newAcc || !aContext->IsAcceptableChild(newAcc))
return nullptr;
if (newAcc) {
document->BindToDocument(newAcc, roleMapEntry);
}
return newAcc;
}
@ -1414,13 +1407,7 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
DocAccessible* aDoc)
{
nsAutoString role;
for (const nsXBLBinding* binding = aContent->GetXBLBinding(); binding; binding = binding->GetBaseBinding()) {
nsIContent* bindingElm = binding->PrototypeBinding()->GetBindingElement();
bindingElm->GetAttr(kNameSpaceID_None, nsGkAtoms::role, role);
if (!role.IsEmpty())
break;
}
nsCoreUtils::XBLBindingRole(aContent, role);
if (role.IsEmpty() || role.EqualsLiteral("none"))
return nullptr;

View File

@ -686,3 +686,15 @@ nsCoreUtils::DispatchAccEvent(RefPtr<nsIAccessibleEvent> event)
obsService->NotifyObservers(event, NS_ACCESSIBLE_EVENT_TOPIC, nullptr);
}
void
nsCoreUtils::XBLBindingRole(const nsIContent* aEl, nsAString& aRole)
{
for (const nsXBLBinding* binding = aEl->GetXBLBinding(); binding;
binding = binding->GetBaseBinding()) {
nsIContent* bindingElm = binding->PrototypeBinding()->GetBindingElement();
bindingElm->GetAttr(kNameSpaceID_None, nsGkAtoms::role, aRole);
if (!aRole.IsEmpty())
break;
}
}

View File

@ -330,6 +330,11 @@ public:
* Notify accessible event observers of an event.
*/
static void DispatchAccEvent(RefPtr<nsIAccessibleEvent> aEvent);
/**
* Return a role attribute on XBL bindings of the element.
*/
static void XBLBindingRole(const nsIContent* aEl, nsAString& aRole);
};
#endif

View File

@ -497,7 +497,8 @@ public:
/**
* Return true if the accessible is an acceptable child.
*/
virtual bool IsAcceptableChild(Accessible* aPossibleChild) const { return true; }
virtual bool IsAcceptableChild(nsIContent* aEl) const
{ return true; }
/**
* Returns text of accessible if accessible has text role otherwise empty

View File

@ -100,7 +100,7 @@ a11y::GetProxyUnignoredChildren(const ProxyAccessible* aProxy,
// If element is ignored, then add its children as substitutes.
if (IsProxyIgnored(childProxy)) {
GetProxyUnignoredChildren(aProxy, aChildrenArray);
GetProxyUnignoredChildren(childProxy, aChildrenArray);
continue;
}

View File

@ -380,14 +380,7 @@ function testAccessibleTree(aAccOrElmOrID, aAccTree, aFlags)
var accTree = aAccTree;
// Support of simplified accessible tree object.
var key = Object.keys(accTree)[0];
var roleName = "ROLE_" + key;
if (roleName in nsIAccessibleRole) {
accTree = {
role: nsIAccessibleRole[roleName],
children: accTree[key]
};
}
accTree = normalizeAccTreeObj(accTree);
// Test accessible properties.
for (var prop in accTree) {
@ -486,15 +479,7 @@ function testAccessibleTree(aAccOrElmOrID, aAccTree, aFlags)
continue;
}
var key = Object.keys(testChild)[0];
var roleName = "ROLE_" + key;
if (roleName in nsIAccessibleRole) {
testChild = {
role: nsIAccessibleRole[roleName],
children: testChild[key]
};
}
testChild = normalizeAccTreeObj(testChild);
if (accChild.role !== testChild.role) {
ok(false, prettyName(accTree) + " and " + prettyName(acc) +
" have different children at index " + i + " : " +
@ -505,7 +490,8 @@ function testAccessibleTree(aAccOrElmOrID, aAccTree, aFlags)
} catch (e) {
ok(false, prettyName(accTree) + " is expected to have a child at index " + i +
" : " + prettyName(testChild) + ", " + e);
" : " + prettyName(testChild) + ", original tested: " +
prettyName(aAccOrElmOrID) + ", " + e);
}
}
} else {
@ -776,6 +762,23 @@ function prettyName(aIdentifier)
return "[ " + getNodePrettyName(aIdentifier) + " ]";
if (aIdentifier && typeof aIdentifier === "object" ) {
var treeObj = normalizeAccTreeObj(aIdentifier);
if ("role" in treeObj) {
function stringifyTree(aObj) {
var text = roleToString(aObj.role) + ": [ ";
if ("children" in aObj) {
for (var i = 0; i < aObj.children.length; i++) {
var c = normalizeAccTreeObj(aObj.children[i]);
text += stringifyTree(c);
if (i < aObj.children.length - 1) {
text += ", ";
}
}
}
return text + "] ";
}
return `{ ${stringifyTree(treeObj)} }`;
}
return JSON.stringify(aIdentifier);
}
@ -880,3 +883,16 @@ function getTestPluginTag(aPluginName)
ok(false, "Could not find plugin tag with plugin name '" + name + "'");
return null;
}
function normalizeAccTreeObj(aObj)
{
var key = Object.keys(aObj)[0];
var roleName = "ROLE_" + key;
if (roleName in nsIAccessibleRole) {
return {
role: nsIAccessibleRole[roleName],
children: aObj[key]
};
}
return aObj;
}

View File

@ -5,6 +5,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Accessible-inl.h"
#include "mozilla/a11y/DocAccessibleParent.h"
#include "nsAccUtils.h"
#include "nsIAccessibleRelation.h"
#include "nsIAccessibleRole.h"
@ -216,10 +217,13 @@ xpcAccessible::GetState(uint32_t* aState, uint32_t* aExtraState)
{
NS_ENSURE_ARG_POINTER(aState);
if (!Intl())
if (IntlGeneric().IsNull())
nsAccUtils::To32States(states::DEFUNCT, aState, aExtraState);
else
else if (Intl())
nsAccUtils::To32States(Intl()->State(), aState, aExtraState);
else
nsAccUtils::To32States(IntlGeneric().AsProxy()->State(), aState,
aExtraState);
return NS_OK;
}
@ -229,11 +233,16 @@ xpcAccessible::GetName(nsAString& aName)
{
aName.Truncate();
if (!Intl())
if (IntlGeneric().IsNull())
return NS_ERROR_FAILURE;
nsAutoString name;
if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
proxy->Name(name);
} else {
Intl()->Name(name);
}
aName.Assign(name);
return NS_OK;
@ -242,11 +251,16 @@ xpcAccessible::GetName(nsAString& aName)
NS_IMETHODIMP
xpcAccessible::GetDescription(nsAString& aDescription)
{
if (!Intl())
if (IntlGeneric().IsNull())
return NS_ERROR_FAILURE;
nsAutoString desc;
if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
proxy->Description(desc);
} else {
Intl()->Description(desc);
}
aDescription.Assign(desc);
return NS_OK;
@ -255,21 +269,33 @@ xpcAccessible::GetDescription(nsAString& aDescription)
NS_IMETHODIMP
xpcAccessible::GetLanguage(nsAString& aLanguage)
{
if (!Intl())
if (IntlGeneric().IsNull())
return NS_ERROR_FAILURE;
Intl()->Language(aLanguage);
nsAutoString lang;
if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
proxy->Language(lang);
} else {
Intl()->Language(lang);
}
aLanguage.Assign(lang);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessible::GetValue(nsAString& aValue)
{
if (!Intl())
if (IntlGeneric().IsNull())
return NS_ERROR_FAILURE;
nsAutoString value;
if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
proxy->Value(value);
} else {
Intl()->Value(value);
}
aValue.Assign(value);
return NS_OK;
@ -317,12 +343,29 @@ xpcAccessible::GetAttributes(nsIPersistentProperties** aAttributes)
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nullptr;
if (!Intl())
if (IntlGeneric().IsNull()) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIPersistentProperties> attributes = Intl()->Attributes();
if (Accessible* acc = Intl()) {
nsCOMPtr<nsIPersistentProperties> attributes = acc->Attributes();
attributes.swap(*aAttributes);
return NS_OK;
}
ProxyAccessible* proxy = IntlGeneric().AsProxy();
AutoTArray<Attribute, 10> attrs;
proxy->Attributes(&attrs);
nsCOMPtr<nsIPersistentProperties> props =
do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
uint32_t attrCount = attrs.Length();
nsAutoString unused;
for (uint32_t i = 0; i < attrCount; i++) {
props->SetStringProperty(attrs[i].Name(), attrs[i].Value(), unused);
}
props.forget(aAttributes);
return NS_OK;
}
@ -339,10 +382,16 @@ xpcAccessible::GetBounds(int32_t* aX, int32_t* aY,
NS_ENSURE_ARG_POINTER(aHeight);
*aHeight = 0;
if (!Intl())
if (IntlGeneric().IsNull())
return NS_ERROR_FAILURE;
nsIntRect rect = Intl()->Bounds();
nsIntRect rect;
if (Accessible* acc = IntlGeneric().AsAccessible()) {
rect = acc->Bounds();
} else {
rect = IntlGeneric().AsProxy()->Bounds();
}
*aX = rect.x;
*aY = rect.y;
*aWidth = rect.width;

View File

@ -130,10 +130,14 @@ XULColorPickerAccessible::AreItemsOperable() const
}
////////////////////////////////////////////////////////////////////////////////
// XULColorPickerAccessible: protected Accessible
// XULColorPickerAccessible: Accessible
bool
XULColorPickerAccessible::IsAcceptableChild(Accessible* aPossibleChild) const
XULColorPickerAccessible::IsAcceptableChild(nsIContent* aEl) const
{
return roles::ALERT == aPossibleChild->Role();
nsAutoString role;
nsCoreUtils::XBLBindingRole(aEl, role);
return role.EqualsLiteral("xul:panel") &&
aEl->AttrValueIs(kNameSpaceID_None, nsGkAtoms::noautofocus,
nsGkAtoms::_true, eCaseMatters);
}

View File

@ -48,7 +48,7 @@ public:
virtual bool IsActiveWidget() const override;
virtual bool AreItemsOperable() const override;
virtual bool IsAcceptableChild(Accessible* aPossibleChild) const override;
virtual bool IsAcceptableChild(nsIContent* aEl) const override;
};
} // namespace a11y

View File

@ -165,7 +165,7 @@ XULButtonAccessible::ContainerWidget() const
}
bool
XULButtonAccessible::IsAcceptableChild(Accessible* aPossibleChild) const
XULButtonAccessible::IsAcceptableChild(nsIContent* aEl) const
{
// In general XUL button has not accessible children. Nevertheless menu
// buttons can have button (@type="menu-button") and popup accessibles
@ -173,17 +173,21 @@ XULButtonAccessible::IsAcceptableChild(Accessible* aPossibleChild) const
// XXX: no children until the button is menu button. Probably it's not
// totally correct but in general AT wants to have leaf buttons.
roles::Role role = aPossibleChild->Role();
nsAutoString role;
nsCoreUtils::XBLBindingRole(aEl, role);
// Get an accessible for menupopup or panel elements.
if (role == roles::MENUPOPUP)
if (role.EqualsLiteral("xul:menupopup")) {
return true;
}
// Button type="menu-button" contains a real button. Get an accessible
// for it. Ignore dropmarker button which is placed as a last child.
if (role != roles::PUSHBUTTON ||
aPossibleChild->GetContent()->IsXULElement(nsGkAtoms::dropMarker))
if ((!role.EqualsLiteral("xul:button") &&
!role.EqualsLiteral("xul:toolbarbutton")) ||
aEl->IsXULElement(nsGkAtoms::dropMarker)) {
return false;
}
return mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
nsGkAtoms::menuButton, eCaseMatters);

View File

@ -50,7 +50,7 @@ public:
virtual bool AreItemsOperable() const override;
virtual Accessible* ContainerWidget() const override;
virtual bool IsAcceptableChild(Accessible* aPossibleChild) const override;
virtual bool IsAcceptableChild(nsIContent* aEl) const override;
protected:
virtual ~XULButtonAccessible();

View File

@ -0,0 +1,13 @@
MOZ_AUTOMATION_L10N_CHECK=0
MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
MOZ_AUTOMATION_UPDATE_PACKAGING=0
MOZ_AUTOMATION_SDK=0
. "$topsrcdir/browser/config/mozconfigs/linux64/nightly"
ac_add_options --enable-application=b2g/dev
ac_add_options --with-compiler-wrapper=$(cd $topsrcdir/sixgill/usr/libexec/sixgill/scripts/wrap_gcc && echo $PWD)/basecc
ac_add_options --without-ccache
ac_add_options --disable-warnings-as-errors
# Include Firefox OS fonts.
MOZTTDIR=$topsrcdir/moz-tt

View File

@ -1,7 +1,8 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"version": "gcc 4.9.3",
"size": 102421980,
"digest": "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true

View File

@ -1528,8 +1528,7 @@ pref("media.eme.apiVisible", true);
// Decode using Gecko Media Plugins in <video>, if a system decoder is not
// availble and the preferred GMP is available.
// NOTE: Disabled until Bug 1236756 is fixed by Adobe.
pref("media.gmp.decoder.enabled", false);
pref("media.gmp.decoder.enabled", true);
// If decoding-via-GMP is turned on for <video>, use Adobe's GMP for decoding,
// if it's available. Note: We won't fallback to another GMP if Adobe's is not
@ -1605,6 +1604,11 @@ pref("layers.async-pan-zoom.enabled", true);
pref("extensions.interposition.enabled", true);
pref("extensions.interposition.prefetching", true);
// Enable blocking of e10s for add-on users on beta/release.
#ifdef RELEASE_BUILD
pref("extensions.e10sBlocksEnabling", true);
#endif
pref("browser.defaultbrowser.notificationbar", false);
// How often to check for CPOW timeouts. CPOWs are only timed out by

View File

@ -1,7 +1,6 @@
"use strict";
let tab;
let notification;
let notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
add_task(function* test_notificationClose() {
@ -12,16 +11,14 @@ add_task(function* test_notificationClose() {
gBrowser,
url: notificationURL
}, function* dummyTabTask(aBrowser) {
let win = aBrowser.contentWindow.wrappedJSObject;
notification = win.showNotification2();
yield BrowserTestUtils.waitForEvent(notification, "show");
yield openNotification(aBrowser, "showNotification2");
info("Notification alert showing");
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
if (!alertWindow) {
ok(true, "Notifications don't use XUL windows on all platforms.");
notification.close();
yield closeNotification(aBrowser);
return;
}

View File

@ -1,8 +1,6 @@
"use strict";
var tab;
var notification;
var notification2;
var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
const ALERT_SERVICE = Cc["@mozilla.org/alerts-service;1"]
@ -44,20 +42,16 @@ function test () {
function onLoad() {
tab.linkedBrowser.removeEventListener("load", onLoad, true);
let win = tab.linkedBrowser.contentWindow.wrappedJSObject;
notification = win.showNotification2();
notification.addEventListener("show", onAlertShowing);
openNotification(tab.linkedBrowser, "showNotification2").then(onAlertShowing);
}
function onAlertShowing() {
info("Notification alert showing");
notification.removeEventListener("show", onAlertShowing);
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
if (!alertWindow) {
ok(true, "Notifications don't use XUL windows on all platforms.");
notification.close();
finish();
closeNotification(tab.linkedBrowser).then(finish);
return;
}
let doNotDisturbMenuItem = alertWindow.document.getElementById("doNotDisturbMenuItem");
@ -71,21 +65,16 @@ function onAlertClosing(event) {
event.target.removeEventListener("beforeunload", onAlertClosing);
ok(ALERT_SERVICE.manualDoNotDisturb, "Alert service should be disabled after clicking menuitem");
let win = tab.linkedBrowser.contentWindow.wrappedJSObject;
notification2 = win.showNotification2();
notification2.addEventListener("show", onAlert2Showing);
// The notification should not appear, but there is
// no way from the client-side to know that it was
// blocked, except for waiting some time and realizing
// that the "onshow" event never fired.
setTimeout(function() {
notification2.removeEventListener("show", onAlert2Showing);
finish();
}, 2000);
openNotification(tab.linkedBrowser, "showNotification2", 2000)
.then(onAlert2Showing, finish);
}
function onAlert2Showing() {
ok(false, "the second alert should not have been shown");
notification2.close();
closeNotification(tab.linkedBrowser).then(finish);
}

View File

@ -29,15 +29,13 @@ add_task(function* test_settingsOpen_button() {
gBrowser,
url: notificationURL
}, function* tabTask(aBrowser) {
let notification = aBrowser.contentWindow.wrappedJSObject.showNotification2();
info("Waiting for notification");
yield BrowserTestUtils.waitForEvent(notification, "show");
yield openNotification(aBrowser, "showNotification2");
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
if (!alertWindow) {
ok(true, "Notifications don't use XUL windows on all platforms.");
notification.close();
yield closeNotification(aBrowser);
return;
}

View File

@ -1,7 +1,6 @@
"use strict";
var tab;
var notification;
var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
var alertWindowClosed = false;
var permRemoved = false;
@ -25,20 +24,16 @@ function test () {
function onLoad() {
tab.linkedBrowser.removeEventListener("load", onLoad, true);
let win = tab.linkedBrowser.contentWindow.wrappedJSObject;
notification = win.showNotification2();
notification.addEventListener("show", onAlertShowing);
openNotification(tab.linkedBrowser, "showNotification2").then(onAlertShowing);
}
function onAlertShowing() {
info("Notification alert showing");
notification.removeEventListener("show", onAlertShowing);
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
if (!alertWindow) {
ok(true, "Notifications don't use XUL windows on all platforms.");
notification.close();
finish();
closeNotification(tab.linkedBrowser).then(finish);
return;
}
ok(Services.perms.testExactPermission(makeURI(notificationURL), "desktop-notification"),
@ -75,5 +70,3 @@ function onAlertClosing(event) {
finish();
}
}

View File

@ -23,30 +23,44 @@ add_task(function* test_notificationPreventDefaultAndSwitchTabs() {
isnot(gBrowser.selectedBrowser, aBrowser, "Notification page loaded as a background tab");
// First, show a notification that will be have the tab-switching prevented.
let win = aBrowser.contentWindow.wrappedJSObject;
let notification = win.showNotification1();
yield BrowserTestUtils.waitForEvent(notification, "show");
function promiseNotificationEvent(evt) {
return ContentTask.spawn(aBrowser, evt, function* (evt) {
return yield new Promise(resolve => {
let notification = content.wrappedJSObject._notification;
notification.addEventListener(evt, function l(event) {
notification.removeEventListener(evt, l);
resolve({ defaultPrevented: event.defaultPrevented });
});
});
});
}
yield openNotification(aBrowser, "showNotification1");
info("Notification alert showing");
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
if (!alertWindow) {
ok(true, "Notifications don't use XUL windows on all platforms.");
notification.close();
yield closeNotification(aBrowser);
return;
}
info("Clicking on notification");
let promiseClickEvent = BrowserTestUtils.waitForEvent(notification, "click");
let promiseClickEvent = promiseNotificationEvent("click");
// NB: This executeSoon is needed to allow the non-e10s runs of this test
// a chance to set the event listener on the page. Otherwise, we
// synchronously fire the click event before we listen for the event.
executeSoon(() => {
EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"),
{},
alertWindow);
{}, alertWindow);
});
let clickEvent = yield promiseClickEvent;
ok(clickEvent.defaultPrevented, "The event handler for the first notification cancels the event");
isnot(gBrowser.selectedBrowser, aBrowser, "Notification page still a background tab");
notification.close();
yield BrowserTestUtils.waitForEvent(notification, "close");
let notificationClosed = promiseNotificationEvent("close");
yield closeNotification(aBrowser);
yield notificationClosed;
// Second, show a notification that will cause the tab to get switched.
let notification2 = win.showNotification2();
yield BrowserTestUtils.waitForEvent(notification2, "show");
yield openNotification(aBrowser, "showNotification2");
alertWindow = Services.wm.getMostRecentWindow("alert:alert");
let promiseTabSelect = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabSelect");
EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"),
@ -55,8 +69,9 @@ add_task(function* test_notificationPreventDefaultAndSwitchTabs() {
yield promiseTabSelect;
is(gBrowser.selectedBrowser.currentURI.spec, notificationURL,
"Clicking on the second notification should select its originating tab");
notification2.close();
yield BrowserTestUtils.waitForEvent(notification2, "close");
notificationClosed = promiseNotificationEvent("close");
yield closeNotification(aBrowser);
yield notificationClosed;
});
});

View File

@ -32,3 +32,40 @@ function promiseWindowClosed(window) {
});
});
}
/**
* These two functions work with file_dom_notifications.html to open the
* notification and close it.
*
* |fn| can be showNotification1 or showNotification2.
* if |timeout| is passed, then the promise returned from this function is
* rejected after the requested number of miliseconds.
*/
function openNotification(aBrowser, fn, timeout) {
return ContentTask.spawn(aBrowser, { fn, timeout }, function* ({ fn, timeout }) {
let win = content.wrappedJSObject;
let notification = win[fn]();
win._notification = notification;
yield new Promise((resolve, reject) => {
function listener() {
notification.removeEventListener("show", listener);
resolve();
}
notification.addEventListener("show", listener);
if (timeout) {
content.setTimeout(() => {
notification.removeEventListener("show", listener);
reject("timed out");
}, timeout);
}
});
});
}
function closeNotification(aBrowser) {
return ContentTask.spawn(aBrowser, null, function() {
content.wrappedJSObject._notification.close();
});
}

View File

@ -155,6 +155,7 @@ skip-if = os == "mac" # The Fitt's Law back button is not supported on OS X
[browser_beforeunload_duplicate_dialogs.js]
[browser_blob-channelname.js]
[browser_bookmark_popup.js]
skip-if = (os == "linux" && debug) # mouseover not reliable on linux debug builds
[browser_bookmark_titles.js]
skip-if = buildapp == 'mulet' || toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341)
[browser_bug304198.js]

View File

@ -303,6 +303,21 @@ def run(objdir):
relobjdir = os.path.relpath(objdir, os.getcwd())
if not skip_configure:
if mozpath.normsep(relobjdir) == 'js/src':
# Because configure is a shell script calling a python script
# calling a shell script, on Windows, with msys screwing the
# environment, we lose the benefits from our own efforts in this
# script to get past the msys problems. So manually call the python
# script instead, so that we don't do a native->msys transition
# here. Then the python configure will still have the right
# environment when calling the shell configure.
command = [
sys.executable,
os.path.join(os.path.dirname(__file__), '..', 'configure.py'),
]
data['env']['OLD_CONFIGURE'] = os.path.join(
os.path.dirname(configure), 'old-configure')
else:
command = [data['shell'], configure]
for kind in ('target', 'build', 'host'):
if data.get(kind) is not None:

View File

@ -17,7 +17,6 @@
#include "nsString.h"
#include "nsQueryObject.h"
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/dom/URL.h"
#include "nsIConsoleService.h"
#include "nsIDocument.h"
@ -30,12 +29,14 @@
#include "nsIScriptError.h"
#include "nsIWindowMediator.h"
#include "nsIPrefService.h"
#include "mozilla/StyleSheetHandle.h"
#include "mozilla/StyleSheetHandleInlines.h"
nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
// DO NOT use namespace mozilla; it'll break due to a naming conflict between
// mozilla::TextRange and a TextRange in OSX headers.
using mozilla::CSSStyleSheet;
using mozilla::StyleSheetHandle;
using mozilla::dom::IsChromeURI;
////////////////////////////////////////////////////////////////////////////////
@ -401,19 +402,18 @@ nsresult nsChromeRegistry::RefreshWindow(nsPIDOMWindowOuter* aWindow)
nsCOMPtr<nsIPresShell> shell = document->GetShell();
if (shell) {
// Reload only the chrome URL agent style sheets.
nsTArray<RefPtr<CSSStyleSheet>> agentSheets;
nsTArray<StyleSheetHandle::RefPtr> agentSheets;
rv = shell->GetAgentStyleSheets(agentSheets);
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<RefPtr<CSSStyleSheet>> newAgentSheets;
for (CSSStyleSheet* sheet : agentSheets) {
nsTArray<StyleSheetHandle::RefPtr> newAgentSheets;
for (StyleSheetHandle sheet : agentSheets) {
nsIURI* uri = sheet->GetSheetURI();
if (IsChromeURI(uri)) {
// Reload the sheet.
RefPtr<CSSStyleSheet> newSheet;
rv = document->LoadChromeSheetSync(uri, true,
getter_AddRefs(newSheet));
StyleSheetHandle::RefPtr newSheet;
rv = document->LoadChromeSheetSync(uri, true, &newSheet);
if (NS_FAILED(rv)) return rv;
if (newSheet) {
rv = newAgentSheets.AppendElement(newSheet) ? NS_OK : NS_ERROR_FAILURE;
@ -433,27 +433,27 @@ nsresult nsChromeRegistry::RefreshWindow(nsPIDOMWindowOuter* aWindow)
int32_t count = document->GetNumberOfStyleSheets();
// Build an array of style sheets we need to reload.
nsTArray<RefPtr<CSSStyleSheet>> oldSheets(count);
nsTArray<RefPtr<CSSStyleSheet>> newSheets(count);
nsTArray<StyleSheetHandle::RefPtr> oldSheets(count);
nsTArray<StyleSheetHandle::RefPtr> newSheets(count);
// Iterate over the style sheets.
for (int32_t i = 0; i < count; i++) {
// Get the style sheet
CSSStyleSheet* styleSheet = document->GetStyleSheetAt(i);
StyleSheetHandle styleSheet = document->GetStyleSheetAt(i);
oldSheets.AppendElement(styleSheet);
}
// Iterate over our old sheets and kick off a sync load of the new
// sheet if and only if it's a chrome URL.
for (CSSStyleSheet* sheet : oldSheets) {
for (StyleSheetHandle sheet : oldSheets) {
nsIURI* uri = sheet ? sheet->GetOriginalURI() : nullptr;
if (uri && IsChromeURI(uri)) {
// Reload the sheet.
RefPtr<CSSStyleSheet> newSheet;
StyleSheetHandle::RefPtr newSheet;
// XXX what about chrome sheets that have a title or are disabled? This
// only works by sheer dumb luck.
document->LoadChromeSheetSync(uri, false, getter_AddRefs(newSheet));
document->LoadChromeSheetSync(uri, false, &newSheet);
// Even if it's null, we put in in there.
newSheets.AppendElement(newSheet);
} else {

View File

@ -291,8 +291,10 @@ CONFIG_CACHE = $(wildcard $(OBJDIR)/config.cache)
EXTRA_CONFIG_DEPS := \
$(TOPSRCDIR)/aclocal.m4 \
$(TOPSRCDIR)/old-configure.in \
$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
$(TOPSRCDIR)/js/src/aclocal.m4 \
$(TOPSRCDIR)/js/src/old-configure.in \
$(NULL)
$(CONFIGURES): %: %.in $(EXTRA_CONFIG_DEPS)

View File

@ -673,6 +673,7 @@ SSL_PeerCertificateChain
SSL_PeerStapledOCSPResponses
SSL_ResetHandshake
SSL_SetCanFalseStartCallback
SSL_SetDowngradeCheckVersion
SSL_SetNextProtoNego
SSL_SetPKCS11PinArg
SSL_SetSockPeerID

View File

@ -20,9 +20,11 @@ new
algorithm
atomic
deque
functional
ios
iosfwd
iostream
istream
iterator
limits
list

View File

@ -487,6 +487,7 @@ fstream
fstream.h
ft2build.h
fts.h
functional
gconf/gconf-client.h
Gdiplus.h
gdk/gdk.h
@ -565,6 +566,7 @@ ios
iosfwd
iostream
iostream.h
istream
iterator
JavaControl.h
JavaEmbedding/JavaControl.h

File diff suppressed because it is too large Load Diff

90
configure.py Normal file
View File

@ -0,0 +1,90 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import print_function, unicode_literals
import glob
import itertools
import os
import subprocess
import sys
base_dir = os.path.dirname(__file__)
sys.path.append(os.path.join(base_dir, 'python', 'which'))
from which import which, WhichError
# If feel dirty replicating this from python/mozbuild/mozbuild/mozconfig.py,
# but the end goal being that the configure script would go away...
shell = 'sh'
if 'MOZILLABUILD' in os.environ:
shell = os.environ['MOZILLABUILD'] + '/msys/bin/sh'
if sys.platform == 'win32':
shell = shell + '.exe'
def find_program(file):
try:
return which(file)
except WhichError:
return None
def autoconf_refresh(configure):
if os.path.exists(configure):
mtime = os.path.getmtime(configure)
aclocal = os.path.join(base_dir, 'build', 'autoconf', '*.m4')
for input in itertools.chain(
(configure + '.in',
os.path.join(os.path.dirname(configure), 'aclocal.m4')),
glob.iglob(aclocal),
):
if os.path.getmtime(input) > mtime:
break
else:
return
for ac in ('autoconf-2.13', 'autoconf2.13', 'autoconf213'):
autoconf = find_program(ac)
if autoconf:
break
else:
fink = find_program('fink')
if fink:
autoconf = os.path.normpath(os.path.join(
fink, '..', '..', 'lib', 'autoconf2.13', 'bin', 'autoconf'))
if not autoconf:
raise RuntimeError('Could not find autoconf 2.13')
print('Refreshing %s' % configure, file=sys.stderr)
with open(configure, 'wb') as fh:
subprocess.check_call([
shell, autoconf, '--localdir=%s' % os.path.dirname(configure),
configure + '.in'], stdout=fh)
def main(args):
old_configure = os.environ.get('OLD_CONFIGURE')
if not old_configure:
raise Exception('The OLD_CONFIGURE environment variable must be set')
# We need to replace backslashes with forward slashes on Windows because
# this path actually ends up literally as $0, which breaks autoconf's
# detection of the source directory.
old_configure = os.path.abspath(old_configure).replace(os.sep, '/')
try:
autoconf_refresh(old_configure)
except RuntimeError as e:
print(e.message, file=sys.stderr)
return 1
return subprocess.call([shell, old_configure] + args)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -19,6 +19,7 @@ loader.lazyRequireGetter(this, "ConsoleProgressListener", "devtools/shared/webco
loader.lazyRequireGetter(this, "events", "sdk/event/core");
loader.lazyRequireGetter(this, "ServerLoggingListener", "devtools/shared/webconsole/server-logger", true);
loader.lazyRequireGetter(this, "JSPropertyProvider", "devtools/shared/webconsole/js-property-provider", true);
loader.lazyRequireGetter(this, "Parser", "resource://devtools/shared/Parser.jsm", true);
for (let name of ["WebConsoleUtils", "ConsoleServiceListener",
"ConsoleAPIListener", "addWebConsoleCommands",
@ -1277,6 +1278,27 @@ WebConsoleActor.prototype =
}
else {
result = dbgWindow.executeInGlobalWithBindings(aString, bindings, evalOptions);
// Attempt to initialize any declarations found in the evaluated string
// since they may now be stuck in an "initializing" state due to the
// error. Already-initialized bindings will be ignored.
if ("throw" in result) {
let ast;
// Parse errors will raise an exception. We can/should ignore the error
// since it's already being handled elsewhere and we are only interested
// in initializing bindings.
try {
ast = Parser.reflectionAPI.parse(aString);
} catch (ex) {
ast = {"body": []};
}
for (let line of ast.body) {
if (line.type == "VariableDeclaration" &&
(line.kind == "let" || line.kind == "const")) {
for (let decl of line.declarations)
dbgWindow.forceLexicalInitializationByName(decl.id.name);
}
}
}
}
let helperResult = helpers.helperResult;

View File

@ -17,7 +17,7 @@
border-radius: 50%;
background: red;
animation: move 2s infinite;
animation: move 200s infinite;
}
.multiple-animations {
@ -28,7 +28,7 @@
border-radius: 50%;
background: #eee;
animation: move 2s infinite, glow 1s 5;
animation: move 200s infinite, glow 100s 5;
}
.transition {
@ -39,7 +39,7 @@
border-radius: 50%;
background: #f06;
transition: width 5s;
transition: width 500s;
}
.transition.get-round {
width: 200px;
@ -75,7 +75,7 @@
border-radius: 50%;
background: rebeccapurple;
animation: move 2s 5s infinite;
animation: move 200s 5s infinite;
}
.delayed-transition {
@ -86,7 +86,7 @@
border-radius: 50%;
background: black;
transition: width 5s 3s;
transition: width 500s 3s;
}
.delayed-transition.get-round {
width: 200px;
@ -111,7 +111,7 @@
border-radius: 50%;
background: blue;
animation: move .5s, glow 1s 2s infinite, grow 3s 1s 100;
animation: move .5s, glow 100s 2s infinite, grow 300s 1s 100;
}
.all-transitions {

View File

@ -30,10 +30,10 @@ add_task(function*() {
ok(true, "The mutations event was emitted");
is(changes.length, 2, "There are 2 changes in the mutation event");
ok(changes.every(({type}) => type === "added"), "Both changes are additions");
is(changes[0].player.initialState.name, "move",
"The first added animation is 'move'");
is(changes[1].player.initialState.name, "glow",
"The first added animation is 'glow'");
let names = changes.map(c => c.player.initialState.name).sort();
is(names[0], "glow", "The animation 'glow' was added");
is(names[1], "move", "The animation 'move' was added");
info("Store the 2 new players for comparing later");
let p1 = changes[0].player;

View File

@ -21,7 +21,7 @@ function* playerHasAnInitialState(walker, animations) {
let state = yield getAnimationStateForNode(walker, animations,
".delayed-multiple-animations", 0);
ok(state.duration, 500,
ok(state.duration, 50000,
"The duration of the first animation is correct");
ok(state.iterationCount, 10,
"The iterationCount of the first animation is correct");
@ -31,7 +31,7 @@ function* playerHasAnInitialState(walker, animations) {
state = yield getAnimationStateForNode(walker, animations,
".delayed-multiple-animations", 1);
ok(state.duration, 1000,
ok(state.duration, 100000,
"The duration of the secon animation is correct");
ok(state.iterationCount, 30,
"The iterationCount of the secon animation is correct");

View File

@ -36,14 +36,14 @@ add_task(function*() {
is(players.length, 2, "2 animations remain on the node");
is(players[0].state.duration, 1000,
is(players[0].state.duration, 100000,
"The duration of the first animation is correct");
is(players[0].state.delay, 2000,
"The delay of the first animation is correct");
is(players[0].state.iterationCount, null,
"The iterationCount of the first animation is correct");
is(players[1].state.duration, 3000,
is(players[1].state.duration, 300000,
"The duration of the second animation is correct");
is(players[1].state.delay, 1000,
"The delay of the second animation is correct");

View File

@ -35,6 +35,9 @@ add_task(function*() {
info("Wait for longer than the animation's duration");
yield wait(2000);
players = yield animations.getAnimationPlayersForNode(node);
is(players.length, 0, "The added animation is surely finished");
is(reportedMutations.length, 1, "Only one mutation was reported");
is(reportedMutations[0].type, "added", "The mutation was an addition");

View File

@ -44,7 +44,7 @@ function* playerStateIsCorrect(walker, animations) {
let state = yield getAnimationStateForNode(walker, animations,
".simple-animation", 0);
is(state.name, "move", "Name is correct");
is(state.duration, 2000, "Duration is correct");
is(state.duration, 200000, "Duration is correct");
// null = infinite count
is(state.iterationCount, null, "Iteration count is correct");
is(state.playState, "running", "PlayState is correct");
@ -55,7 +55,7 @@ function* playerStateIsCorrect(walker, animations) {
state = yield getAnimationStateForNode(walker, animations, ".transition", 0);
is(state.name, "width", "Transition name matches transition property");
is(state.duration, 5000, "Transition duration is correct");
is(state.duration, 500000, "Transition duration is correct");
// transitions run only once
is(state.iterationCount, 1, "Transition iteration count is correct");
is(state.playState, "running", "Transition playState is correct");
@ -68,7 +68,7 @@ function* playerStateIsCorrect(walker, animations) {
state = yield getAnimationStateForNode(walker, animations,
".multiple-animations", 1);
is(state.name, "glow", "The 2nd animation's name is correct");
is(state.duration, 1000, "The 2nd animation's duration is correct");
is(state.duration, 100000, "The 2nd animation's duration is correct");
is(state.iterationCount, 5, "The 2nd animation's iteration count is correct");
is(state.playState, "running", "The 2nd animation's playState is correct");
is(state.playbackRate, 1, "The 2nd animation's playbackRate is correct");

View File

@ -66,7 +66,8 @@ function onAttach(aState, aResponse)
let tests = [doSimpleEval, doWindowEval, doEvalWithException,
doEvalWithHelper, doEvalString, doEvalLongString,
doEvalWithBinding, doEvalWithBindingFrame].map(t => {
doEvalWithBinding, doEvalWithBindingFrame,
forceLexicalInit].map(t => {
return Task.async(t);
});
@ -223,6 +224,25 @@ function* doEvalWithBindingFrame() {
nextTest()
}
function* forceLexicalInit() {
info("test `let x = SomeError` results in x being initialized to undefined");
let response = yield evaluateJS("let foopie = wubbalubadubdub;");
checkObject(response, {
from: gState.actor,
input: "let foopie = wubbalubadubdub;",
result: undefined,
});
ok(response.exception, "expected exception");
let response2 = yield evaluateJS("foopie;");
checkObject(response2, {
from: gState.actor,
input: "foopie;",
result: undefined,
});
ok(!response2.exception, "unexpected exception");
nextTest();
}
function testEnd()
{
// If this is the first run, reload the page and do it again.

View File

@ -13,6 +13,8 @@
#include "mozilla/EffectSet.h"
#include "mozilla/InitializerList.h"
#include "mozilla/LayerAnimationInfo.h"
#include "mozilla/RestyleManagerHandle.h"
#include "mozilla/RestyleManagerHandleInlines.h"
#include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetPresShellForContent
#include "nsCSSPropertySet.h"
#include "nsCSSProps.h"
@ -22,7 +24,6 @@
#include "nsRuleNode.h" // For nsRuleNode::ComputePropertiesOverridingAnimation
#include "nsRuleProcessorData.h" // For ElementRuleProcessorData etc.
#include "nsTArray.h"
#include "RestyleManager.h"
using mozilla::dom::Animation;
using mozilla::dom::Element;
@ -161,7 +162,10 @@ EffectCompositor::RequestRestyle(dom::Element* aElement,
if (aRestyleType == RestyleType::Layer) {
// Prompt layers to re-sync their animations.
mPresContext->RestyleManager()->IncrementAnimationGeneration();
MOZ_ASSERT(mPresContext->RestyleManager()->IsGecko(),
"stylo: Servo-backed style system should not be using "
"EffectCompositor");
mPresContext->RestyleManager()->AsGecko()->IncrementAnimationGeneration();
EffectSet* effectSet =
EffectSet::GetEffectSet(aElement, aPseudoType);
if (effectSet) {
@ -252,7 +256,10 @@ EffectCompositor::GetAnimationRule(dom::Element* aElement,
return nullptr;
}
if (mPresContext->RestyleManager()->SkipAnimationRules()) {
MOZ_ASSERT(mPresContext->RestyleManager()->IsGecko(),
"stylo: Servo-backed style system should not be using "
"EffectCompositor");
if (mPresContext->RestyleManager()->AsGecko()->SkipAnimationRules()) {
// We don't need to worry about updating mElementsToRestyle in this case
// since this is not the animation restyle we requested when we called
// PostRestyleForAnimation (see comment at start of this method).

View File

@ -6,7 +6,8 @@
#include "EffectSet.h"
#include "mozilla/dom/Element.h" // For Element
#include "RestyleManager.h"
#include "mozilla/RestyleManagerHandle.h"
#include "mozilla/RestyleManagerHandleInlines.h"
#include "nsCSSPseudoElements.h" // For CSSPseudoElementType
#include "nsCycleCollectionNoteChild.h" // For CycleCollectionNoteChild
#include "nsPresContext.h"
@ -134,8 +135,11 @@ EffectSet::DestroyEffectSet(dom::Element* aElement,
void
EffectSet::UpdateAnimationGeneration(nsPresContext* aPresContext)
{
MOZ_ASSERT(aPresContext->RestyleManager()->IsGecko(),
"stylo: Servo-backed style system should not be using "
"EffectSet");
mAnimationGeneration =
aPresContext->RestyleManager()->GetAnimationGeneration();
aPresContext->RestyleManager()->AsGecko()->GetAnimationGeneration();
}
/* static */ nsIAtom**

View File

@ -452,9 +452,17 @@ KeyframeEffectReadOnly::HasAnimationOfProperties(
return false;
}
void
KeyframeEffectReadOnly::CopyPropertiesFrom(const KeyframeEffectReadOnly& aOther)
bool
KeyframeEffectReadOnly::UpdateProperties(
const InfallibleTArray<AnimationProperty>& aProperties)
{
// AnimationProperty::operator== does not compare mWinsInCascade and
// mIsRunningOnCompositor, we don't need to update anything here because
// we want to preserve
if (mProperties == aProperties) {
return false;
}
nsCSSPropertySet winningInCascadeProperties;
nsCSSPropertySet runningOnCompositorProperties;
@ -467,7 +475,7 @@ KeyframeEffectReadOnly::CopyPropertiesFrom(const KeyframeEffectReadOnly& aOther)
}
}
mProperties = aOther.mProperties;
mProperties = aProperties;
for (AnimationProperty& property : mProperties) {
property.mWinsInCascade =
@ -475,6 +483,18 @@ KeyframeEffectReadOnly::CopyPropertiesFrom(const KeyframeEffectReadOnly& aOther)
property.mIsRunningOnCompositor =
runningOnCompositorProperties.HasProperty(property.mProperty);
}
if (mAnimation) {
nsPresContext* presContext = GetPresContext();
if (presContext) {
presContext->EffectCompositor()->
RequestRestyle(mTarget, mPseudoType,
EffectCompositor::RestyleType::Layer,
mAnimation->CascadeLevel());
}
}
return true;
}
void

View File

@ -35,7 +35,6 @@ class nsPresContext;
namespace mozilla {
struct AnimationCollection;
class AnimValuesStyleRule;
enum class CSSPseudoElementType : uint8_t;
@ -138,7 +137,7 @@ struct AnimationProperty
// If true, the propery is currently being animated on the compositor.
//
// Note that when the owning Animation requests a non-throttled restyle, in
// between calling RequestRestyle on its AnimationCollection and when the
// between calling RequestRestyle on its EffectCompositor and when the
// restyle is performed, this member may temporarily become false even if
// the animation remains on the layer after the restyle.
//
@ -287,10 +286,12 @@ public:
InfallibleTArray<AnimationProperty>& Properties() {
return mProperties;
}
// Copies the properties from another keyframe effect whilst preserving
// the mWinsInCascade and mIsRunningOnCompositor state of matching
// Updates the set of properties using the supplied list whilst preserving
// the mWinsInCascade and mIsRunningOnCompositor state of any matching
// properties.
void CopyPropertiesFrom(const KeyframeEffectReadOnly& aOther);
// Returns true if we updated anything in the properties.
bool UpdateProperties(
const InfallibleTArray<AnimationProperty>& aProperties);
// Updates |aStyleRule| with the animation values produced by this
// AnimationEffect for the current time except any properties already
@ -321,8 +322,6 @@ public:
nsIDocument* GetRenderedDocument() const;
nsPresContext* GetPresContext() const;
inline AnimationCollection* GetCollection() const;
protected:
KeyframeEffectReadOnly(nsIDocument* aDocument,
Element* aTarget,

View File

@ -17,6 +17,8 @@
#include "mozilla/dom/HTMLContentElement.h"
#include "mozilla/dom/HTMLShadowElement.h"
#include "nsXBLPrototypeBinding.h"
#include "mozilla/StyleSheetHandle.h"
#include "mozilla/StyleSheetHandleInlines.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -130,7 +132,7 @@ ShadowRoot::StyleSheetChanged()
}
void
ShadowRoot::InsertSheet(CSSStyleSheet* aSheet,
ShadowRoot::InsertSheet(StyleSheetHandle aSheet,
nsIContent* aLinkingContent)
{
nsCOMPtr<nsIStyleSheetLinkingElement>
@ -148,8 +150,8 @@ ShadowRoot::InsertSheet(CSSStyleSheet* aSheet,
break;
}
nsINode* sheetOwnerNode = mProtoBinding->StyleSheetAt(i)->GetOwnerNode();
if (nsContentUtils::PositionIsBefore(aLinkingContent, sheetOwnerNode)) {
nsINode* sheetOwningNode = mProtoBinding->StyleSheetAt(i)->GetOwnerNode();
if (nsContentUtils::PositionIsBefore(aLinkingContent, sheetOwningNode)) {
mProtoBinding->InsertStyleSheetAt(i, aSheet);
break;
}
@ -161,7 +163,7 @@ ShadowRoot::InsertSheet(CSSStyleSheet* aSheet,
}
void
ShadowRoot::RemoveSheet(CSSStyleSheet* aSheet)
ShadowRoot::RemoveSheet(StyleSheetHandle aSheet)
{
mProtoBinding->RemoveStyleSheet(aSheet);
@ -752,7 +754,14 @@ ShadowRootStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound)
return nullptr;
}
return mShadowRoot->mProtoBinding->StyleSheetAt(aIndex);
// XXXheycam Return null until ServoStyleSheet implements the right
// DOM interfaces.
StyleSheetHandle sheet = mShadowRoot->mProtoBinding->StyleSheetAt(aIndex);
if (sheet->IsServo()) {
NS_ERROR("stylo: can't return ServoStyleSheets to script yet");
return nullptr;
}
return sheet->AsGecko();
}
uint32_t

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/StyleSheetList.h"
#include "mozilla/StyleSheetHandle.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsTHashtable.h"
@ -45,8 +46,8 @@ public:
void AddToIdTable(Element* aElement, nsIAtom* aId);
void RemoveFromIdTable(Element* aElement, nsIAtom* aId);
void InsertSheet(CSSStyleSheet* aSheet, nsIContent* aLinkingContent);
void RemoveSheet(CSSStyleSheet* aSheet);
void InsertSheet(StyleSheetHandle aSheet, nsIContent* aLinkingContent);
void RemoveSheet(StyleSheetHandle aSheet);
bool ApplyAuthorStyles();
void SetApplyAuthorStyles(bool aApplyAuthorStyles);
StyleSheetList* StyleSheets();

View File

@ -213,7 +213,7 @@ nsContentSink::Init(nsIDocument* aDoc,
}
NS_IMETHODIMP
nsContentSink::StyleSheetLoaded(CSSStyleSheet* aSheet,
nsContentSink::StyleSheetLoaded(StyleSheetHandle aSheet,
bool aWasAlternate,
nsresult aStatus)
{

View File

@ -85,7 +85,7 @@ class nsContentSink : public nsICSSLoaderObserver,
NS_DECL_NSITIMERCALLBACK
// nsICSSLoaderObserver
NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheetHandle aSheet,
bool aWasAlternate,
nsresult aStatus) override;

View File

@ -108,6 +108,7 @@
#include "mozilla/css/ImageLoader.h"
#include "mozilla/layers/APZCTreeManager.h" // for layers::ZoomToRectBehavior
#include "mozilla/dom/Promise.h"
#include "mozilla/CSSStyleSheet.h"
#ifdef XP_WIN
#undef GetClassName
@ -2467,6 +2468,8 @@ nsDOMWindowUtils::ZoomToFocusedInput()
uint32_t flags = layers::DISABLE_ZOOM_OUT;
if (!Preferences::GetBool("formhelper.autozoom")) {
flags |= layers::PAN_INTO_VIEW_ONLY;
} else {
flags |= layers::ONLY_ZOOM_TO_DEFAULT_SCALE;
}
CSSRect bounds = nsLayoutUtils::GetBoundingContentRect(content, rootScrollFrame);

View File

@ -243,6 +243,10 @@
#include "gfxVR.h"
#include "gfxPrefs.h"
#include "nsISupportsPrimitives.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "mozilla/StyleSheetHandle.h"
#include "mozilla/StyleSheetHandleInlines.h"
#include "mozilla/DocLoadingTimelineMarker.h"
@ -731,10 +735,16 @@ nsDOMStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound)
}
aFound = true;
CSSStyleSheet* sheet = mDocument->GetStyleSheetAt(aIndex);
StyleSheetHandle sheet = mDocument->GetStyleSheetAt(aIndex);
NS_ASSERTION(sheet, "Must have a sheet");
return static_cast<CSSStyleSheet*>(sheet);
// XXXheycam Return null until ServoStyleSheet implements the right DOM
// interfaces.
if (sheet->IsServo()) {
NS_ERROR("stylo: can't return a ServoStyleSheet to the DOM yet");
return nullptr;
}
return sheet->AsGecko();
}
void
@ -744,7 +754,7 @@ nsDOMStyleSheetList::NodeWillBeDestroyed(const nsINode *aNode)
}
void
nsDOMStyleSheetList::StyleSheetAdded(CSSStyleSheet* aStyleSheet,
nsDOMStyleSheetList::StyleSheetAdded(StyleSheetHandle aStyleSheet,
bool aDocumentSheet)
{
if (aDocumentSheet && -1 != mLength) {
@ -753,7 +763,7 @@ nsDOMStyleSheetList::StyleSheetAdded(CSSStyleSheet* aStyleSheet,
}
void
nsDOMStyleSheetList::StyleSheetRemoved(CSSStyleSheet* aStyleSheet,
nsDOMStyleSheetList::StyleSheetRemoved(StyleSheetHandle aStyleSheet,
bool aDocumentSheet)
{
if (aDocumentSheet && -1 != mLength) {
@ -1320,9 +1330,14 @@ nsDOMStyleSheetSetList::EnsureFresh()
int32_t count = mDocument->GetNumberOfStyleSheets();
nsAutoString title;
for (int32_t index = 0; index < count; index++) {
CSSStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
StyleSheetHandle sheet = mDocument->GetStyleSheetAt(index);
NS_ASSERTION(sheet, "Null sheet in sheet list!");
sheet->GetTitle(title);
// XXXheycam ServoStyleSheets don't expose their title yet.
if (sheet->IsServo()) {
NS_ERROR("stylo: ServoStyleSets don't expose their title yet");
continue;
}
sheet->AsGecko()->GetTitle(title);
if (!title.IsEmpty() && !mNames.Contains(title) && !Add(title)) {
return;
}
@ -1602,7 +1617,7 @@ nsDocument::~nsDocument()
mCachedRootElement = nullptr;
// Let the stylesheets know we're going away
for (CSSStyleSheet* sheet : mStyleSheets) {
for (StyleSheetHandle sheet : mStyleSheets) {
sheet->SetOwningDocument(nullptr);
}
if (mAttrStyleSheet) {
@ -2280,7 +2295,7 @@ void
nsDocument::RemoveDocStyleSheetsFromStyleSets()
{
// The stylesheets should forget us
for (CSSStyleSheet* sheet : Reversed(mStyleSheets)) {
for (StyleSheetHandle sheet : Reversed(mStyleSheets)) {
sheet->SetOwningDocument(nullptr);
if (sheet->IsApplicable()) {
@ -2295,11 +2310,11 @@ nsDocument::RemoveDocStyleSheetsFromStyleSets()
void
nsDocument::RemoveStyleSheetsFromStyleSets(
nsTArray<RefPtr<CSSStyleSheet>>& aSheets,
nsTArray<StyleSheetHandle::RefPtr>& aSheets,
SheetType aType)
{
// The stylesheets should forget us
for (CSSStyleSheet* sheet : Reversed(aSheets)) {
for (StyleSheetHandle sheet : Reversed(aSheets)) {
sheet->SetOwningDocument(nullptr);
if (sheet->IsApplicable()) {
@ -2365,24 +2380,24 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
}
static void
AppendSheetsToStyleSet(nsStyleSet* aStyleSet,
const nsTArray<RefPtr<CSSStyleSheet>>& aSheets,
AppendSheetsToStyleSet(StyleSetHandle aStyleSet,
const nsTArray<StyleSheetHandle::RefPtr>& aSheets,
SheetType aType)
{
for (CSSStyleSheet* sheet : Reversed(aSheets)) {
for (StyleSheetHandle sheet : Reversed(aSheets)) {
aStyleSet->AppendStyleSheet(aType, sheet);
}
}
void
nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
nsDocument::FillStyleSet(StyleSetHandle aStyleSet)
{
NS_PRECONDITION(aStyleSet, "Must have a style set");
NS_PRECONDITION(aStyleSet->SheetCount(SheetType::Doc) == 0,
"Style set already has document sheets?");
for (CSSStyleSheet* sheet : Reversed(mStyleSheets)) {
for (StyleSheetHandle sheet : Reversed(mStyleSheets)) {
if (sheet->IsApplicable()) {
aStyleSet->AddDocStyleSheet(sheet, this);
}
@ -2390,13 +2405,13 @@ nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
if (sheetService) {
for (CSSStyleSheet* sheet : *sheetService->AuthorStyleSheets()) {
for (StyleSheetHandle sheet : *sheetService->AuthorStyleSheets()) {
aStyleSet->AppendStyleSheet(SheetType::Doc, sheet);
}
}
// Iterate backwards to maintain order
for (CSSStyleSheet* sheet : Reversed(mOnDemandBuiltInUASheets)) {
for (StyleSheetHandle sheet : Reversed(mOnDemandBuiltInUASheets)) {
if (sheet->IsApplicable()) {
aStyleSet->PrependStyleSheet(SheetType::Agent, sheet);
}
@ -3719,7 +3734,7 @@ nsDocument::TryChannelCharset(nsIChannel *aChannel,
already_AddRefed<nsIPresShell>
nsDocument::CreateShell(nsPresContext* aContext, nsViewManager* aViewManager,
nsStyleSet* aStyleSet)
StyleSetHandle aStyleSet)
{
// Don't add anything here. Add it to |doCreateShell| instead.
// This exists so that subclasses can pass other values for the 4th
@ -3729,7 +3744,7 @@ nsDocument::CreateShell(nsPresContext* aContext, nsViewManager* aViewManager,
already_AddRefed<nsIPresShell>
nsDocument::doCreateShell(nsPresContext* aContext,
nsViewManager* aViewManager, nsStyleSet* aStyleSet)
nsViewManager* aViewManager, StyleSetHandle aStyleSet)
{
NS_ASSERTION(!mPresShell, "We have a presshell already!");
@ -4049,7 +4064,7 @@ nsDocument::RemoveChildAt(uint32_t aIndex, bool aNotify)
}
void
nsDocument::EnsureOnDemandBuiltInUASheet(CSSStyleSheet* aSheet)
nsDocument::EnsureOnDemandBuiltInUASheet(StyleSheetHandle aSheet)
{
if (mOnDemandBuiltInUASheets.Contains(aSheet)) {
return;
@ -4060,7 +4075,7 @@ nsDocument::EnsureOnDemandBuiltInUASheet(CSSStyleSheet* aSheet)
}
void
nsDocument::AddOnDemandBuiltInUASheet(CSSStyleSheet* aSheet)
nsDocument::AddOnDemandBuiltInUASheet(StyleSheetHandle aSheet)
{
MOZ_ASSERT(!mOnDemandBuiltInUASheets.Contains(aSheet));
@ -4089,20 +4104,20 @@ nsDocument::GetNumberOfStyleSheets() const
return mStyleSheets.Length();
}
CSSStyleSheet*
StyleSheetHandle
nsDocument::GetStyleSheetAt(int32_t aIndex) const
{
return mStyleSheets.SafeElementAt(aIndex, nullptr);
return mStyleSheets.SafeElementAt(aIndex, StyleSheetHandle());
}
int32_t
nsDocument::GetIndexOfStyleSheet(CSSStyleSheet* aSheet) const
nsDocument::GetIndexOfStyleSheet(StyleSheetHandle aSheet) const
{
return mStyleSheets.IndexOf(aSheet);
}
void
nsDocument::AddStyleSheetToStyleSets(CSSStyleSheet* aSheet)
nsDocument::AddStyleSheetToStyleSets(StyleSheetHandle aSheet)
{
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
@ -4115,7 +4130,11 @@ nsDocument::AddStyleSheetToStyleSets(CSSStyleSheet* aSheet)
className##Init init; \
init.mBubbles = true; \
init.mCancelable = true; \
init.mStylesheet = aSheet; \
/* XXXheycam ServoStyleSheet doesn't implement DOM interfaces yet */ \
if (aSheet->IsServo()) { \
NS_ERROR("stylo: can't dispatch events for ServoStyleSheets yet"); \
} \
init.mStylesheet = aSheet->IsGecko() ? aSheet->AsGecko() : nullptr; \
init.memberName = argName; \
\
RefPtr<className> event = \
@ -4129,7 +4148,7 @@ nsDocument::AddStyleSheetToStyleSets(CSSStyleSheet* aSheet)
} while (0);
void
nsDocument::NotifyStyleSheetAdded(CSSStyleSheet* aSheet, bool aDocumentSheet)
nsDocument::NotifyStyleSheetAdded(StyleSheetHandle aSheet, bool aDocumentSheet)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (aSheet, aDocumentSheet));
@ -4142,7 +4161,7 @@ nsDocument::NotifyStyleSheetAdded(CSSStyleSheet* aSheet, bool aDocumentSheet)
}
void
nsDocument::NotifyStyleSheetRemoved(CSSStyleSheet* aSheet, bool aDocumentSheet)
nsDocument::NotifyStyleSheetRemoved(StyleSheetHandle aSheet, bool aDocumentSheet)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetRemoved, (aSheet, aDocumentSheet));
@ -4155,7 +4174,7 @@ nsDocument::NotifyStyleSheetRemoved(CSSStyleSheet* aSheet, bool aDocumentSheet)
}
void
nsDocument::AddStyleSheet(CSSStyleSheet* aSheet)
nsDocument::AddStyleSheet(StyleSheetHandle aSheet)
{
NS_PRECONDITION(aSheet, "null arg");
mStyleSheets.AppendElement(aSheet);
@ -4169,7 +4188,7 @@ nsDocument::AddStyleSheet(CSSStyleSheet* aSheet)
}
void
nsDocument::RemoveStyleSheetFromStyleSets(CSSStyleSheet* aSheet)
nsDocument::RemoveStyleSheetFromStyleSets(StyleSheetHandle aSheet)
{
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
@ -4178,10 +4197,10 @@ nsDocument::RemoveStyleSheetFromStyleSets(CSSStyleSheet* aSheet)
}
void
nsDocument::RemoveStyleSheet(CSSStyleSheet* aSheet)
nsDocument::RemoveStyleSheet(StyleSheetHandle aSheet)
{
NS_PRECONDITION(aSheet, "null arg");
RefPtr<CSSStyleSheet> sheet = aSheet; // hold ref so it won't die too soon
StyleSheetHandle::RefPtr sheet = aSheet; // hold ref so it won't die too soon
if (!mStyleSheets.RemoveElement(aSheet)) {
NS_ASSERTION(mInUnlinkOrDeletion, "stylesheet not found");
@ -4200,8 +4219,8 @@ nsDocument::RemoveStyleSheet(CSSStyleSheet* aSheet)
}
void
nsDocument::UpdateStyleSheets(nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
nsDocument::UpdateStyleSheets(nsTArray<StyleSheetHandle::RefPtr>& aOldSheets,
nsTArray<StyleSheetHandle::RefPtr>& aNewSheets)
{
BeginUpdate(UPDATE_STYLE);
@ -4210,7 +4229,7 @@ nsDocument::UpdateStyleSheets(nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
"The lists must be the same length!");
int32_t count = aOldSheets.Length();
RefPtr<CSSStyleSheet> oldSheet;
StyleSheetHandle::RefPtr oldSheet;
int32_t i;
for (i = 0; i < count; ++i) {
oldSheet = aOldSheets[i];
@ -4221,7 +4240,7 @@ nsDocument::UpdateStyleSheets(nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
RemoveStyleSheet(oldSheet); // This does the right notifications
// Now put the new one in its place. If it's null, just ignore it.
CSSStyleSheet* newSheet = aNewSheets[i];
StyleSheetHandle newSheet = aNewSheets[i];
if (newSheet) {
mStyleSheets.InsertElementAt(oldIndex, newSheet);
newSheet->SetOwningDocument(this);
@ -4237,7 +4256,7 @@ nsDocument::UpdateStyleSheets(nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
}
void
nsDocument::InsertStyleSheetAt(CSSStyleSheet* aSheet, int32_t aIndex)
nsDocument::InsertStyleSheetAt(StyleSheetHandle aSheet, int32_t aIndex)
{
NS_PRECONDITION(aSheet, "null ptr");
@ -4254,7 +4273,7 @@ nsDocument::InsertStyleSheetAt(CSSStyleSheet* aSheet, int32_t aIndex)
void
nsDocument::SetStyleSheetApplicableState(CSSStyleSheet* aSheet,
nsDocument::SetStyleSheetApplicableState(StyleSheetHandle aSheet,
bool aApplicable)
{
NS_PRECONDITION(aSheet, "null arg");
@ -4320,7 +4339,7 @@ ConvertAdditionalSheetType(nsIDocument::additionalSheetType aType)
}
static int32_t
FindSheet(const nsTArray<RefPtr<CSSStyleSheet>>& aSheets, nsIURI* aSheetURI)
FindSheet(const nsTArray<StyleSheetHandle::RefPtr>& aSheets, nsIURI* aSheetURI)
{
for (int32_t i = aSheets.Length() - 1; i >= 0; i-- ) {
bool bEqual;
@ -4344,7 +4363,7 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
return NS_ERROR_INVALID_ARG;
// Loading the sheet sync.
RefPtr<css::Loader> loader = new css::Loader();
RefPtr<css::Loader> loader = new css::Loader(GetStyleBackendType());
css::SheetParsingMode parsingMode;
switch (aType) {
@ -4364,9 +4383,8 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
MOZ_CRASH("impossible value for aType");
}
RefPtr<CSSStyleSheet> sheet;
nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true,
getter_AddRefs(sheet));
StyleSheetHandle::RefPtr sheet;
nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, &sheet);
NS_ENSURE_SUCCESS(rv, rv);
sheet->SetOwningDocument(this);
@ -4376,7 +4394,7 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
}
nsresult
nsDocument::AddAdditionalStyleSheet(additionalSheetType aType, CSSStyleSheet* aSheet)
nsDocument::AddAdditionalStyleSheet(additionalSheetType aType, StyleSheetHandle aSheet)
{
if (mAdditionalSheets[aType].Contains(aSheet))
return NS_ERROR_INVALID_ARG;
@ -4405,11 +4423,11 @@ nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheet
{
MOZ_ASSERT(aSheetURI);
nsTArray<RefPtr<CSSStyleSheet>>& sheets = mAdditionalSheets[aType];
nsTArray<StyleSheetHandle::RefPtr>& sheets = mAdditionalSheets[aType];
int32_t i = FindSheet(mAdditionalSheets[aType], aSheetURI);
if (i >= 0) {
RefPtr<CSSStyleSheet> sheetRef = sheets[i];
StyleSheetHandle::RefPtr sheetRef = sheets[i];
sheets.RemoveElementAt(i);
BeginUpdate(UPDATE_STYLE);
@ -4431,10 +4449,10 @@ nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheet
}
}
CSSStyleSheet*
StyleSheetHandle
nsDocument::FirstAdditionalAuthorSheet()
{
return mAdditionalSheets[eAuthorSheet].SafeElementAt(0, nullptr);
return mAdditionalSheets[eAuthorSheet].SafeElementAt(0, StyleSheetHandle());
}
nsIGlobalObject*
@ -5190,7 +5208,7 @@ nsDocument::DocumentStatesChanged(EventStates aStateMask)
}
void
nsDocument::StyleRuleChanged(CSSStyleSheet* aSheet,
nsDocument::StyleRuleChanged(StyleSheetHandle aSheet,
css::Rule* aStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleChanged, (aSheet));
@ -5204,7 +5222,7 @@ nsDocument::StyleRuleChanged(CSSStyleSheet* aSheet,
}
void
nsDocument::StyleRuleAdded(CSSStyleSheet* aSheet,
nsDocument::StyleRuleAdded(StyleSheetHandle aSheet,
css::Rule* aStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleAdded, (aSheet));
@ -5219,7 +5237,7 @@ nsDocument::StyleRuleAdded(CSSStyleSheet* aSheet,
}
void
nsDocument::StyleRuleRemoved(CSSStyleSheet* aSheet,
nsDocument::StyleRuleRemoved(StyleSheetHandle aSheet,
css::Rule* aStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleRemoved, (aSheet));
@ -6460,17 +6478,23 @@ nsIDocument::GetSelectedStyleSheetSet(nsAString& aSheetSet)
int32_t count = GetNumberOfStyleSheets();
nsAutoString title;
for (int32_t index = 0; index < count; index++) {
CSSStyleSheet* sheet = GetStyleSheetAt(index);
StyleSheetHandle sheet = GetStyleSheetAt(index);
NS_ASSERTION(sheet, "Null sheet in sheet list!");
// XXXheycam Make this work with ServoStyleSheets.
if (sheet->IsServo()) {
NS_ERROR("stylo: can't handle alternate ServoStyleSheets yet");
continue;
}
bool disabled;
sheet->GetDisabled(&disabled);
sheet->AsGecko()->GetDisabled(&disabled);
if (disabled) {
// Disabled sheets don't affect the currently selected set
continue;
}
sheet->GetTitle(title);
sheet->AsGecko()->GetTitle(title);
if (aSheetSet.IsEmpty()) {
aSheetSet = title;
@ -6574,11 +6598,18 @@ nsDocument::EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
int32_t count = GetNumberOfStyleSheets();
nsAutoString title;
for (int32_t index = 0; index < count; index++) {
CSSStyleSheet* sheet = GetStyleSheetAt(index);
StyleSheetHandle sheet = GetStyleSheetAt(index);
NS_ASSERTION(sheet, "Null sheet in sheet list!");
sheet->GetTitle(title);
// XXXheycam Make this work with ServoStyleSheets.
if (sheet->IsServo()) {
NS_ERROR("stylo: can't handle alternate ServoStyleSheets yet");
continue;
}
sheet->AsGecko()->GetTitle(title);
if (!title.IsEmpty()) {
sheet->SetEnabled(title.Equals(aSheetSet));
sheet->AsGecko()->SetEnabled(title.Equals(aSheetSet));
}
}
if (aUpdateCSSLoader) {
@ -9852,7 +9883,7 @@ class StubCSSLoaderObserver final : public nsICSSLoaderObserver {
~StubCSSLoaderObserver() {}
public:
NS_IMETHOD
StyleSheetLoaded(CSSStyleSheet*, bool, nsresult) override
StyleSheetLoaded(StyleSheetHandle, bool, nsresult) override
{
return NS_OK;
}
@ -9881,12 +9912,12 @@ nsDocument::PreloadStyle(nsIURI* uri, const nsAString& charset,
nsresult
nsDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
CSSStyleSheet** sheet)
mozilla::StyleSheetHandle::RefPtr* aSheet)
{
css::SheetParsingMode mode =
isAgentSheet ? css::eAgentSheetFeatures
: css::eAuthorSheetFeatures;
return CSSLoader()->LoadSheetSync(uri, mode, isAgentSheet, sheet);
return CSSLoader()->LoadSheetSync(uri, mode, isAgentSheet, aSheet);
}
class nsDelayedEventDispatcher : public nsRunnable
@ -10212,29 +10243,39 @@ nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
int32_t sheetsCount = GetNumberOfStyleSheets();
for (int32_t i = 0; i < sheetsCount; ++i) {
RefPtr<CSSStyleSheet> sheet = GetStyleSheetAt(i);
StyleSheetHandle::RefPtr sheet = GetStyleSheetAt(i);
if (sheet) {
if (sheet->IsApplicable()) {
// XXXheycam Need to make ServoStyleSheet cloning work.
if (sheet->IsGecko()) {
RefPtr<CSSStyleSheet> clonedSheet =
sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
sheet->AsGecko()->Clone(nullptr, nullptr, clonedDoc, nullptr);
NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
if (clonedSheet) {
clonedDoc->AddStyleSheet(clonedSheet);
}
} else {
NS_ERROR("stylo: ServoStyleSheet doesn't support cloning");
}
}
}
}
// Iterate backwards to maintain order
for (CSSStyleSheet* sheet : Reversed(thisAsDoc->mOnDemandBuiltInUASheets)) {
for (StyleSheetHandle sheet : Reversed(thisAsDoc->mOnDemandBuiltInUASheets)) {
if (sheet) {
if (sheet->IsApplicable()) {
// XXXheycam Need to make ServoStyleSheet cloning work.
if (sheet->IsGecko()) {
RefPtr<CSSStyleSheet> clonedSheet =
sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
sheet->AsGecko()->Clone(nullptr, nullptr, clonedDoc, nullptr);
NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
if (clonedSheet) {
clonedDoc->AddOnDemandBuiltInUASheet(clonedSheet);
}
} else {
NS_ERROR("stylo: ServoStyleSheet doesn't support cloning");
}
}
}
}
@ -12364,7 +12405,7 @@ nsDocument::OnAppThemeChanged()
}
for (int32_t i = 0; i < GetNumberOfStyleSheets(); i++) {
RefPtr<CSSStyleSheet> sheet = GetStyleSheetAt(i);
StyleSheetHandle::RefPtr sheet = GetStyleSheetAt(i);
if (!sheet) {
continue;
}
@ -12731,12 +12772,12 @@ nsIDocument::DocAddSizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
}
static size_t
SizeOfOwnedSheetArrayExcludingThis(const nsTArray<RefPtr<CSSStyleSheet>>& aSheets,
SizeOfOwnedSheetArrayExcludingThis(const nsTArray<StyleSheetHandle::RefPtr>& aSheets,
MallocSizeOf aMallocSizeOf)
{
size_t n = 0;
n += aSheets.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (CSSStyleSheet* sheet : aSheets) {
for (StyleSheetHandle sheet : aSheets) {
if (!sheet->GetOwningDocument()) {
// Avoid over-reporting shared sheets.
continue;
@ -13327,9 +13368,16 @@ nsIDocument::FlushUserFontSet()
if (gfxPlatform::GetPlatform()->DownloadableFontsEnabled()) {
nsTArray<nsFontFaceRuleContainer> rules;
nsIPresShell* shell = GetShell();
if (shell && !shell->StyleSet()->AppendFontFaceRules(rules)) {
if (shell) {
// XXXheycam ServoStyleSets don't support exposing @font-face rules yet.
if (shell->StyleSet()->IsGecko()) {
if (!shell->StyleSet()->AsGecko()->AppendFontFaceRules(rules)) {
return;
}
} else {
NS_ERROR("stylo: ServoStyleSets cannot handle @font-face rules yet");
}
}
bool changed = false;
@ -13410,3 +13458,15 @@ nsIDocument::ReportHasScrollLinkedEffect()
this, nsContentUtils::eLAYOUT_PROPERTIES,
"ScrollLinkedEffectFound2");
}
mozilla::StyleBackendType
nsIDocument::GetStyleBackendType() const
{
if (!mPresShell) {
#ifdef MOZ_STYLO
NS_WARNING("GetStyleBackendType() called on document without a pres shell");
#endif
return StyleBackendType::Gecko;
}
return mPresShell->StyleSet()->BackendType();
}

View File

@ -44,7 +44,7 @@
#include "nsGkAtoms.h"
#include "nsIApplicationCache.h"
#include "nsIApplicationCacheContainer.h"
#include "nsStyleSet.h"
#include "mozilla/StyleSetHandle.h"
#include "PLDHashTable.h"
#include "nsAttrAndChildArray.h"
#include "nsDOMAttributeMap.h"
@ -776,9 +776,10 @@ public:
* its presentation context (presentation contexts <b>must not</b> be
* shared among multiple presentation shells).
*/
virtual already_AddRefed<nsIPresShell> CreateShell(nsPresContext* aContext,
virtual already_AddRefed<nsIPresShell> CreateShell(
nsPresContext* aContext,
nsViewManager* aViewManager,
nsStyleSet* aStyleSet) override;
mozilla::StyleSetHandle aStyleSet) override;
virtual void DeleteShell() override;
virtual nsresult GetAllowPlugins(bool* aAllowPlugins) override;
@ -796,36 +797,36 @@ public:
virtual Element* FindContentForSubDocument(nsIDocument *aDocument) const override;
virtual Element* GetRootElementInternal() const override;
virtual void EnsureOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet) override;
virtual void EnsureOnDemandBuiltInUASheet(mozilla::StyleSheetHandle aSheet) override;
/**
* Get the (document) style sheets owned by this document.
* These are ordered, highest priority last
*/
virtual int32_t GetNumberOfStyleSheets() const override;
virtual mozilla::CSSStyleSheet* GetStyleSheetAt(int32_t aIndex) const override;
virtual int32_t GetIndexOfStyleSheet(mozilla::CSSStyleSheet* aSheet) const override;
virtual void AddStyleSheet(mozilla::CSSStyleSheet* aSheet) override;
virtual void RemoveStyleSheet(mozilla::CSSStyleSheet* aSheet) override;
virtual mozilla::StyleSheetHandle GetStyleSheetAt(int32_t aIndex) const override;
virtual int32_t GetIndexOfStyleSheet(mozilla::StyleSheetHandle aSheet) const override;
virtual void AddStyleSheet(mozilla::StyleSheetHandle aSheet) override;
virtual void RemoveStyleSheet(mozilla::StyleSheetHandle aSheet) override;
virtual void UpdateStyleSheets(
nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aOldSheets,
nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets) override;
virtual void AddStyleSheetToStyleSets(mozilla::CSSStyleSheet* aSheet);
virtual void RemoveStyleSheetFromStyleSets(mozilla::CSSStyleSheet* aSheet);
nsTArray<mozilla::StyleSheetHandle::RefPtr>& aOldSheets,
nsTArray<mozilla::StyleSheetHandle::RefPtr>& aNewSheets) override;
virtual void AddStyleSheetToStyleSets(mozilla::StyleSheetHandle aSheet);
virtual void RemoveStyleSheetFromStyleSets(mozilla::StyleSheetHandle aSheet);
virtual void InsertStyleSheetAt(mozilla::CSSStyleSheet* aSheet,
virtual void InsertStyleSheetAt(mozilla::StyleSheetHandle aSheet,
int32_t aIndex) override;
virtual void SetStyleSheetApplicableState(mozilla::CSSStyleSheet* aSheet,
virtual void SetStyleSheetApplicableState(mozilla::StyleSheetHandle aSheet,
bool aApplicable) override;
virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType,
nsIURI* aSheetURI) override;
virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType,
mozilla::CSSStyleSheet* aSheet) override;
mozilla::StyleSheetHandle aSheet) override;
virtual void RemoveAdditionalStyleSheet(additionalSheetType aType,
nsIURI* sheetURI) override;
virtual mozilla::CSSStyleSheet* FirstAdditionalAuthorSheet() override;
virtual mozilla::StyleSheetHandle FirstAdditionalAuthorSheet() override;
virtual nsIChannel* GetChannel() const override {
return mChannel;
@ -885,11 +886,11 @@ public:
virtual void DocumentStatesChanged(
mozilla::EventStates aStateMask) override;
virtual void StyleRuleChanged(mozilla::CSSStyleSheet* aStyleSheet,
virtual void StyleRuleChanged(mozilla::StyleSheetHandle aStyleSheet,
mozilla::css::Rule* aStyleRule) override;
virtual void StyleRuleAdded(mozilla::CSSStyleSheet* aStyleSheet,
virtual void StyleRuleAdded(mozilla::StyleSheetHandle aStyleSheet,
mozilla::css::Rule* aStyleRule) override;
virtual void StyleRuleRemoved(mozilla::CSSStyleSheet* aStyleSheet,
virtual void StyleRuleRemoved(mozilla::StyleSheetHandle aStyleSheet,
mozilla::css::Rule* aStyleRule) override;
virtual void FlushPendingNotifications(mozFlushType aType) override;
@ -961,7 +962,7 @@ public:
void ReportUseCounters();
private:
void AddOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet);
void AddOnDemandBuiltInUASheet(mozilla::StyleSheetHandle aSheet);
nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
void SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages);
@ -1143,7 +1144,7 @@ public:
const nsAString& aIntegrity) override;
virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
mozilla::CSSStyleSheet** sheet) override;
mozilla::StyleSheetHandle::RefPtr* aSheet) override;
virtual nsISupports* GetCurrentContentSink() override;
@ -1489,14 +1490,14 @@ public:
protected:
already_AddRefed<nsIPresShell> doCreateShell(nsPresContext* aContext,
nsViewManager* aViewManager,
nsStyleSet* aStyleSet);
mozilla::StyleSetHandle aStyleSet);
void RemoveDocStyleSheetsFromStyleSets();
void RemoveStyleSheetsFromStyleSets(
nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aSheets,
nsTArray<mozilla::StyleSheetHandle::RefPtr>& aSheets,
mozilla::SheetType aType);
void ResetStylesheetsToURI(nsIURI* aURI);
void FillStyleSet(nsStyleSet* aStyleSet);
void FillStyleSet(mozilla::StyleSetHandle aStyleSet);
// Return whether all the presshells for this document are safe to flush
bool IsSafeToFlush() const;
@ -1547,9 +1548,9 @@ protected:
// EndLoad() has already happened.
nsWeakPtr mWeakSink;
nsTArray<RefPtr<mozilla::CSSStyleSheet>> mStyleSheets;
nsTArray<RefPtr<mozilla::CSSStyleSheet>> mOnDemandBuiltInUASheets;
nsTArray<RefPtr<mozilla::CSSStyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
nsTArray<mozilla::StyleSheetHandle::RefPtr> mStyleSheets;
nsTArray<mozilla::StyleSheetHandle::RefPtr> mOnDemandBuiltInUASheets;
nsTArray<mozilla::StyleSheetHandle::RefPtr> mAdditionalSheets[AdditionalSheetTypeCount];
// Array of observers
nsTObserverArray<nsIDocumentObserver*> mObservers;
@ -1708,8 +1709,8 @@ private:
friend class nsUnblockOnloadEvent;
// Recomputes the visibility state but doesn't set the new value.
mozilla::dom::VisibilityState GetVisibilityState() const;
void NotifyStyleSheetAdded(mozilla::CSSStyleSheet* aSheet, bool aDocumentSheet);
void NotifyStyleSheetRemoved(mozilla::CSSStyleSheet* aSheet, bool aDocumentSheet);
void NotifyStyleSheetAdded(mozilla::StyleSheetHandle aSheet, bool aDocumentSheet);
void NotifyStyleSheetRemoved(mozilla::StyleSheetHandle aSheet, bool aDocumentSheet);
void PostUnblockOnloadEvent();
void DoUnblockOnload();

View File

@ -1982,6 +1982,7 @@ GK_ATOM(letterFrame, "LetterFrame")
GK_ATOM(lineFrame, "LineFrame")
GK_ATOM(listControlFrame,"ListControlFrame")
GK_ATOM(menuFrame,"MenuFrame")
GK_ATOM(meterFrame, "MeterFrame")
GK_ATOM(menuPopupFrame,"MenuPopupFrame")
GK_ATOM(numberControlFrame, "NumberControlFrame")
GK_ATOM(objectFrame, "ObjectFrame")
@ -1990,6 +1991,7 @@ GK_ATOM(pageBreakFrame, "PageBreakFrame")
GK_ATOM(pageContentFrame, "PageContentFrame")
GK_ATOM(placeholderFrame, "PlaceholderFrame")
GK_ATOM(popupSetFrame, "PopupSetFrame")
GK_ATOM(progressFrame, "ProgressFrame")
GK_ATOM(canvasFrame, "CanvasFrame")
GK_ATOM(rangeFrame, "RangeFrame")
GK_ATOM(rootFrame, "RootFrame")

View File

@ -9527,6 +9527,24 @@ nsGlobalWindow::SetActive(bool aActive)
NotifyDocumentTree(mDoc, nullptr);
}
bool
nsGlobalWindow::IsTopLevelWindowActive()
{
nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShell());
if (!treeItem) {
return false;
}
nsCOMPtr<nsIDocShellTreeItem> rootItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
if (!rootItem) {
return false;
}
nsCOMPtr<nsPIDOMWindowOuter> domWindow = rootItem->GetWindow();
return domWindow && domWindow->IsActive();
}
void nsGlobalWindow::SetIsBackground(bool aIsBackground)
{
MOZ_ASSERT(IsOuterWindow());

View File

@ -422,6 +422,7 @@ public:
// Outer windows only.
virtual void ActivateOrDeactivate(bool aActivate) override;
virtual void SetActive(bool aActive) override;
virtual bool IsTopLevelWindowActive() override;
virtual void SetIsBackground(bool aIsBackground) override;
virtual void SetChromeEventHandler(mozilla::dom::EventTarget* aChromeEventHandler) override;

View File

@ -34,6 +34,8 @@
#include "prclist.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/CORSMode.h"
#include "mozilla/StyleBackendType.h"
#include "mozilla/StyleSheetHandle.h"
#include <bitset> // for member
class gfxUserFontSet;
@ -80,7 +82,6 @@ class nsPresContext;
class nsRange;
class nsScriptLoader;
class nsSMILAnimationController;
class nsStyleSet;
class nsTextNode;
class nsWindowSizes;
class nsDOMCaretPosition;
@ -93,6 +94,7 @@ class CSSStyleSheet;
class ErrorResult;
class EventStates;
class PendingAnimationTracker;
class StyleSetHandle;
class SVGAttrAnimationRuleProcessor;
template<typename> class OwningNonNull;
@ -672,9 +674,10 @@ public:
* method is responsible for calling BeginObservingDocument() on the
* presshell if the presshell should observe document mutations.
*/
virtual already_AddRefed<nsIPresShell> CreateShell(nsPresContext* aContext,
virtual already_AddRefed<nsIPresShell> CreateShell(
nsPresContext* aContext,
nsViewManager* aViewManager,
nsStyleSet* aStyleSet) = 0;
mozilla::StyleSetHandle aStyleSet) = 0;
virtual void DeleteShell() = 0;
nsIPresShell* GetShell() const
@ -917,7 +920,7 @@ public:
* TODO We can get rid of the whole concept of delayed loading if we fix
* bug 77999.
*/
virtual void EnsureOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet) = 0;
virtual void EnsureOnDemandBuiltInUASheet(mozilla::StyleSheetHandle aSheet) = 0;
/**
* Get the number of (document) stylesheets
@ -933,7 +936,7 @@ public:
* @return the stylesheet at aIndex. Null if aIndex is out of range.
* @throws no exceptions
*/
virtual mozilla::CSSStyleSheet* GetStyleSheetAt(int32_t aIndex) const = 0;
virtual mozilla::StyleSheetHandle GetStyleSheetAt(int32_t aIndex) const = 0;
/**
* Insert a sheet at a particular spot in the stylesheet list (zero-based)
@ -942,7 +945,7 @@ public:
* adjusted for the "special" sheets.
* @throws no exceptions
*/
virtual void InsertStyleSheetAt(mozilla::CSSStyleSheet* aSheet,
virtual void InsertStyleSheetAt(mozilla::StyleSheetHandle aSheet,
int32_t aIndex) = 0;
/**
@ -951,7 +954,7 @@ public:
* @param aSheet the sheet to get the index of
* @return aIndex the index of the sheet in the full list
*/
virtual int32_t GetIndexOfStyleSheet(mozilla::CSSStyleSheet* aSheet) const = 0;
virtual int32_t GetIndexOfStyleSheet(mozilla::StyleSheetHandle aSheet) const = 0;
/**
* Replace the stylesheets in aOldSheets with the stylesheets in
@ -962,24 +965,24 @@ public:
* will simply be removed.
*/
virtual void UpdateStyleSheets(
nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aOldSheets,
nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets) = 0;
nsTArray<mozilla::StyleSheetHandle::RefPtr>& aOldSheets,
nsTArray<mozilla::StyleSheetHandle::RefPtr>& aNewSheets) = 0;
/**
* Add a stylesheet to the document
*/
virtual void AddStyleSheet(mozilla::CSSStyleSheet* aSheet) = 0;
virtual void AddStyleSheet(mozilla::StyleSheetHandle aSheet) = 0;
/**
* Remove a stylesheet from the document
*/
virtual void RemoveStyleSheet(mozilla::CSSStyleSheet* aSheet) = 0;
virtual void RemoveStyleSheet(mozilla::StyleSheetHandle aSheet) = 0;
/**
* Notify the document that the applicable state of the sheet changed
* and that observers should be notified and style sets updated
*/
virtual void SetStyleSheetApplicableState(mozilla::CSSStyleSheet* aSheet,
virtual void SetStyleSheetApplicableState(mozilla::StyleSheetHandle aSheet,
bool aApplicable) = 0;
enum additionalSheetType {
@ -992,10 +995,10 @@ public:
virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType,
nsIURI* aSheetURI) = 0;
virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType,
mozilla::CSSStyleSheet* aSheet) = 0;
mozilla::StyleSheetHandle aSheet) = 0;
virtual void RemoveAdditionalStyleSheet(additionalSheetType aType,
nsIURI* sheetURI) = 0;
virtual mozilla::CSSStyleSheet* FirstAdditionalAuthorSheet() = 0;
virtual mozilla::StyleSheetHandle FirstAdditionalAuthorSheet() = 0;
/**
* Get this document's CSSLoader. This is guaranteed to not return null.
@ -1004,6 +1007,8 @@ public:
return mCSSLoader;
}
mozilla::StyleBackendType GetStyleBackendType() const;
/**
* Get this document's StyleImageLoader. This is guaranteed to not return null.
*/
@ -1291,11 +1296,11 @@ public:
// Observation hooks for style data to propagate notifications
// to document observers
virtual void StyleRuleChanged(mozilla::CSSStyleSheet* aStyleSheet,
virtual void StyleRuleChanged(mozilla::StyleSheetHandle aStyleSheet,
mozilla::css::Rule* aStyleRule) = 0;
virtual void StyleRuleAdded(mozilla::CSSStyleSheet* aStyleSheet,
virtual void StyleRuleAdded(mozilla::StyleSheetHandle aStyleSheet,
mozilla::css::Rule* aStyleRule) = 0;
virtual void StyleRuleRemoved(mozilla::CSSStyleSheet* aStyleSheet,
virtual void StyleRuleRemoved(mozilla::StyleSheetHandle aStyleSheet,
mozilla::css::Rule* aStyleRule) = 0;
/**
@ -2090,7 +2095,7 @@ public:
* DO NOT USE FOR UNTRUSTED CONTENT.
*/
virtual nsresult LoadChromeSheetSync(nsIURI* aURI, bool aIsAgentSheet,
mozilla::CSSStyleSheet** aSheet) = 0;
mozilla::StyleSheetHandle::RefPtr* aSheet) = 0;
/**
* Returns true if the locale used for the document specifies a direction of

View File

@ -7,6 +7,7 @@
#define nsIDocumentObserver_h___
#include "mozilla/EventStates.h"
#include "mozilla/StyleSheetHandle.h"
#include "nsISupports.h"
#include "nsIMutationObserver.h"
@ -14,7 +15,6 @@ class nsIContent;
class nsIDocument;
namespace mozilla {
class CSSStyleSheet;
namespace css {
class Rule;
} // namespace css
@ -100,7 +100,7 @@ public:
* @param aDocumentSheet True if sheet is in document's style sheet list,
* false if sheet is not (i.e., UA or user sheet)
*/
virtual void StyleSheetAdded(mozilla::CSSStyleSheet* aStyleSheet,
virtual void StyleSheetAdded(mozilla::StyleSheetHandle aStyleSheet,
bool aDocumentSheet) = 0;
/**
@ -113,7 +113,7 @@ public:
* @param aDocumentSheet True if sheet is in document's style sheet list,
* false if sheet is not (i.e., UA or user sheet)
*/
virtual void StyleSheetRemoved(mozilla::CSSStyleSheet* aStyleSheet,
virtual void StyleSheetRemoved(mozilla::StyleSheetHandle aStyleSheet,
bool aDocumentSheet) = 0;
/**
@ -125,7 +125,7 @@ public:
*
* @param aStyleSheet the StyleSheet that has changed state
*/
virtual void StyleSheetApplicableStateChanged(mozilla::CSSStyleSheet* aStyleSheet) = 0;
virtual void StyleSheetApplicableStateChanged(mozilla::StyleSheetHandle aStyleSheet) = 0;
/**
* A StyleRule has just been modified within a style sheet.
@ -136,7 +136,7 @@ public:
*
* @param aStyleSheet the StyleSheet that contians the rule
*/
virtual void StyleRuleChanged(mozilla::CSSStyleSheet* aStyleSheet) = 0;
virtual void StyleRuleChanged(mozilla::StyleSheetHandle aStyleSheet) = 0;
/**
* A StyleRule has just been added to a style sheet.
@ -147,7 +147,7 @@ public:
*
* @param aStyleSheet the StyleSheet that has been modified
*/
virtual void StyleRuleAdded(mozilla::CSSStyleSheet* aStyleSheet) = 0;
virtual void StyleRuleAdded(mozilla::StyleSheetHandle aStyleSheet) = 0;
/**
* A StyleRule has just been removed from a style sheet.
@ -158,7 +158,7 @@ public:
*
* @param aStyleSheet the StyleSheet that has been modified
*/
virtual void StyleRuleRemoved(mozilla::CSSStyleSheet* aStyleSheet) = 0;
virtual void StyleRuleRemoved(mozilla::StyleSheetHandle aStyleSheet) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
@ -186,25 +186,25 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
mozilla::EventStates aStateMask) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED \
virtual void StyleSheetAdded(mozilla::CSSStyleSheet* aStyleSheet, \
virtual void StyleSheetAdded(mozilla::StyleSheetHandle aStyleSheet, \
bool aDocumentSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED \
virtual void StyleSheetRemoved(mozilla::CSSStyleSheet* aStyleSheet, \
virtual void StyleSheetRemoved(mozilla::StyleSheetHandle aStyleSheet, \
bool aDocumentSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED \
virtual void StyleSheetApplicableStateChanged( \
mozilla::CSSStyleSheet* aStyleSheet) override;
mozilla::StyleSheetHandle aStyleSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED \
virtual void StyleRuleChanged(mozilla::CSSStyleSheet* aStyleSheet) override;
virtual void StyleRuleChanged(mozilla::StyleSheetHandle aStyleSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED \
virtual void StyleRuleAdded(mozilla::CSSStyleSheet* aStyleSheet) override;
virtual void StyleRuleAdded(mozilla::StyleSheetHandle aStyleSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED \
virtual void StyleRuleRemoved(mozilla::CSSStyleSheet* aStyleSheet) override;
virtual void StyleRuleRemoved(mozilla::StyleSheetHandle aStyleSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER \
NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE \
@ -262,29 +262,29 @@ NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class)
#define NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(_class) \
void \
_class::StyleSheetAdded(mozilla::CSSStyleSheet* aStyleSheet, \
_class::StyleSheetAdded(mozilla::StyleSheetHandle aStyleSheet, \
bool aDocumentSheet) \
{ \
} \
void \
_class::StyleSheetRemoved(mozilla::CSSStyleSheet* aStyleSheet, \
_class::StyleSheetRemoved(mozilla::StyleSheetHandle aStyleSheet, \
bool aDocumentSheet) \
{ \
} \
void \
_class::StyleSheetApplicableStateChanged(mozilla::CSSStyleSheet* aStyleSheet) \
_class::StyleSheetApplicableStateChanged(mozilla::StyleSheetHandle aStyleSheet) \
{ \
} \
void \
_class::StyleRuleChanged(mozilla::CSSStyleSheet* aStyleSheet) \
_class::StyleRuleChanged(mozilla::StyleSheetHandle aStyleSheet) \
{ \
} \
void \
_class::StyleRuleAdded(mozilla::CSSStyleSheet* aStyleSheet) \
_class::StyleRuleAdded(mozilla::StyleSheetHandle aStyleSheet) \
{ \
} \
void \
_class::StyleRuleRemoved(mozilla::CSSStyleSheet* aStyleSheet) \
_class::StyleRuleRemoved(mozilla::StyleSheetHandle aStyleSheet) \
{ \
}

View File

@ -20,6 +20,7 @@
#include "mozilla/InternalMutationEvent.h"
#include "mozilla/Likely.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/css/StyleRule.h"
@ -148,6 +149,12 @@ nsINode::~nsINode()
{
MOZ_ASSERT(!HasSlots(), "nsNodeUtils::LastRelease was not called?");
MOZ_ASSERT(mSubtreeRoot == this, "Didn't restore state properly?");
#ifdef MOZ_STYLO
if (mServoNodeData) {
Servo_DropNodeData(mServoNodeData);
}
#endif
}
void*

View File

@ -51,6 +51,7 @@ class nsIURI;
class nsNodeSupportsWeakRefTearoff;
class nsNodeWeakReference;
class nsDOMMutationObserver;
struct ServoNodeData;
namespace mozilla {
class EventListenerManager;
@ -313,14 +314,17 @@ public:
#ifdef MOZILLA_INTERNAL_API
explicit nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: mNodeInfo(aNodeInfo),
mParent(nullptr),
mBoolFlags(0),
mNextSibling(nullptr),
mPreviousSibling(nullptr),
mFirstChild(nullptr),
mSubtreeRoot(this),
mSlots(nullptr)
: mNodeInfo(aNodeInfo)
, mParent(nullptr)
, mBoolFlags(0)
, mNextSibling(nullptr)
, mPreviousSibling(nullptr)
, mFirstChild(nullptr)
, mSubtreeRoot(this)
, mSlots(nullptr)
#ifdef MOZ_STYLO
, mServoNodeData(nullptr)
#endif
{
}
#endif
@ -1971,6 +1975,23 @@ public:
#undef TOUCH_EVENT
#undef EVENT
ServoNodeData* GetServoNodeData() {
#ifdef MOZ_STYLO
return mServoNodeData;
#else
MOZ_CRASH("Accessing servo node data in non-stylo build");
#endif
}
void SetServoNodeData(ServoNodeData* aData) {
#ifdef MOZ_STYLO
MOZ_ASSERT(!mServoNodeData);
mServoNodeData = aData;
#else
MOZ_CRASH("Setting servo node data in non-stylo build");
#endif
}
protected:
static bool Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb);
static void Unlink(nsINode *tmp);
@ -2008,6 +2029,11 @@ protected:
// Storage for more members that are usually not needed; allocated lazily.
nsSlots* mSlots;
#ifdef MOZ_STYLO
// Layout data managed by Servo.
ServoNodeData* mServoNodeData;
#endif
};
inline nsIDOMNode* GetAsDOMNode(nsINode* aNode)

View File

@ -8,6 +8,7 @@
#include "nsISupports.h"
#include "mozilla/StyleSheetHandle.h"
class nsICSSLoaderObserver;
class nsIURI;
@ -16,10 +17,6 @@ class nsIURI;
{ 0xa8b79f3b, 0x9d18, 0x4f9c, \
{ 0xb1, 0xaa, 0x8c, 0x9b, 0x1b, 0xaa, 0xac, 0xad } }
namespace mozilla {
class CSSStyleSheet;
} // namespace mozilla
class nsIStyleSheetLinkingElement : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLESHEETLINKINGELEMENT_IID)
@ -31,14 +28,14 @@ public:
* @param aStyleSheet the style sheet associated with this
* element.
*/
NS_IMETHOD SetStyleSheet(mozilla::CSSStyleSheet* aStyleSheet) = 0;
NS_IMETHOD SetStyleSheet(mozilla::StyleSheetHandle aStyleSheet) = 0;
/**
* Used to obtain the style sheet linked in by this element.
*
* @return the style sheet associated with this element.
*/
NS_IMETHOD_(mozilla::CSSStyleSheet*) GetStyleSheet() = 0;
NS_IMETHOD_(mozilla::StyleSheetHandle) GetStyleSheet() = 0;
/**
* Initialize the stylesheet linking element. If aDontLoadStyle is

View File

@ -122,6 +122,8 @@ public:
virtual nsresult RegisterIdleObserver(nsIIdleObserver* aIdleObserver) = 0;
virtual nsresult UnregisterIdleObserver(nsIIdleObserver* aIdleObserver) = 0;
virtual bool IsTopLevelWindowActive() = 0;
// Outer windows only.
virtual void SetActive(bool aActive)
{

View File

@ -12,7 +12,8 @@
#include "nsStyleLinkElement.h"
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/StyleSheetHandle.h"
#include "mozilla/StyleSheetHandleInlines.h"
#include "mozilla/css/Loader.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FragmentOrElement.h"
@ -67,7 +68,7 @@ nsStyleLinkElement::Traverse(nsCycleCollectionTraversalCallback &cb)
}
NS_IMETHODIMP
nsStyleLinkElement::SetStyleSheet(CSSStyleSheet* aStyleSheet)
nsStyleLinkElement::SetStyleSheet(StyleSheetHandle aStyleSheet)
{
if (mStyleSheet) {
mStyleSheet->SetOwningNode(nullptr);
@ -84,7 +85,7 @@ nsStyleLinkElement::SetStyleSheet(CSSStyleSheet* aStyleSheet)
return NS_OK;
}
NS_IMETHODIMP_(CSSStyleSheet*)
NS_IMETHODIMP_(StyleSheetHandle)
nsStyleLinkElement::GetStyleSheet()
{
return mStyleSheet;
@ -316,8 +317,15 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
return NS_OK;
}
Element* oldScopeElement =
mStyleSheet ? mStyleSheet->GetScopeElement() : nullptr;
// XXXheycam ServoStyleSheets do not support <style scoped>.
Element* oldScopeElement = nullptr;
if (mStyleSheet) {
if (mStyleSheet->IsServo()) {
NS_ERROR("stylo: ServoStyleSheets don't support <style scoped>");
} else {
oldScopeElement = mStyleSheet->AsGecko()->GetScopeElement();
}
}
if (mStyleSheet && (aOldDocument || aOldShadowRoot)) {
MOZ_ASSERT(!(aOldDocument && aOldShadowRoot),
@ -465,10 +473,18 @@ nsStyleLinkElement::UpdateStyleSheetScopedness(bool aIsNowScoped)
return;
}
if (mStyleSheet->IsServo()) {
// XXXheycam ServoStyleSheets don't support <style scoped>.
NS_ERROR("stylo: ServoStyleSheets don't support <style scoped>");
return;
}
CSSStyleSheet* sheet = mStyleSheet->AsGecko();
nsCOMPtr<nsIContent> thisContent;
CallQueryInterface(this, getter_AddRefs(thisContent));
Element* oldScopeElement = mStyleSheet->GetScopeElement();
Element* oldScopeElement = sheet->GetScopeElement();
Element* newScopeElement = aIsNowScoped ?
thisContent->GetParentElement() :
nullptr;
@ -483,14 +499,14 @@ nsStyleLinkElement::UpdateStyleSheetScopedness(bool aIsNowScoped)
ShadowRoot* containingShadow = thisContent->GetContainingShadow();
containingShadow->RemoveSheet(mStyleSheet);
mStyleSheet->SetScopeElement(newScopeElement);
sheet->SetScopeElement(newScopeElement);
containingShadow->InsertSheet(mStyleSheet, thisContent);
} else {
document->BeginUpdate(UPDATE_STYLE);
document->RemoveStyleSheet(mStyleSheet);
mStyleSheet->SetScopeElement(newScopeElement);
sheet->SetScopeElement(newScopeElement);
document->AddStyleSheet(mStyleSheet);
document->EndUpdate(UPDATE_STYLE);

View File

@ -24,6 +24,7 @@ class nsIDocument;
class nsIURI;
namespace mozilla {
class CSSStyleSheet;
namespace dom {
class ShadowRoot;
} // namespace dom
@ -37,11 +38,19 @@ public:
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override = 0;
mozilla::CSSStyleSheet* GetSheet() const { return mStyleSheet; }
mozilla::CSSStyleSheet* GetSheet() const
{
// XXXheycam Return nullptr for ServoStyleSheets until we have a way of
// exposing them to script.
NS_ASSERTION(!mStyleSheet || mStyleSheet->IsGecko(),
"stylo: ServoStyleSheets can't be exposed to script yet");
return mStyleSheet && mStyleSheet->IsGecko() ? mStyleSheet->AsGecko() :
nullptr;
}
// nsIStyleSheetLinkingElement
NS_IMETHOD SetStyleSheet(mozilla::CSSStyleSheet* aStyleSheet) override;
NS_IMETHOD_(mozilla::CSSStyleSheet*) GetStyleSheet() override;
NS_IMETHOD SetStyleSheet(mozilla::StyleSheetHandle aStyleSheet) override;
NS_IMETHOD_(mozilla::StyleSheetHandle) GetStyleSheet() override;
NS_IMETHOD InitStyleLinkElement(bool aDontLoadStyle) override;
NS_IMETHOD UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
bool* aWillNotify,
@ -128,7 +137,7 @@ private:
bool* aIsAlternate,
bool aForceUpdate);
RefPtr<mozilla::CSSStyleSheet> mStyleSheet;
mozilla::StyleSheetHandle::RefPtr mStyleSheet;
protected:
bool mDontLoadStyle;
bool mUpdatesEnabled;

View File

@ -497,6 +497,22 @@ ErrorResult::SetPendingException(JSContext* cx)
SetPendingGenericErrorException(cx);
}
void
ErrorResult::StealExceptionFromJSContext(JSContext* cx)
{
MOZ_ASSERT(mMightHaveUnreportedJSException,
"Why didn't you tell us you planned to throw a JS exception?");
JS::Rooted<JS::Value> exn(cx);
if (!JS_GetPendingException(cx, &exn)) {
ThrowUncatchableException();
return;
}
ThrowJSException(cx, exn);
JS_ClearPendingException(cx);
}
namespace dom {
bool

View File

@ -184,6 +184,18 @@ public:
return true;
}
// Use StealExceptionFromJSContext to convert a pending exception on a
// JSContext to an ErrorResult. This function must be called only when a
// JSAPI operation failed. It assumes that lack of pending exception on the
// JSContext means an uncatchable exception was thrown.
//
// Codepaths that might call this method must call MightThrowJSException even
// if the relevant JSAPI calls do not fail.
//
// When this function returns, JS_IsExceptionPending(cx) will definitely be
// false.
void StealExceptionFromJSContext(JSContext* cx);
template<dom::ErrNum errorNumber, typename... Ts>
void ThrowTypeError(Ts&&... messageArgs)
{
@ -202,10 +214,10 @@ public:
// Facilities for throwing a preexisting JS exception value via this
// ErrorResult. The contract is that any code which might end up calling
// ThrowJSException() must call MightThrowJSException() even if no exception
// is being thrown. Code that conditionally calls ToJSValue on this
// ErrorResult only if Failed() must first call WouldReportJSException even if
// this ErrorResult has not failed.
// ThrowJSException() or StealExceptionFromJSContext() must call
// MightThrowJSException() even if no exception is being thrown. Code that
// conditionally calls ToJSValue on this ErrorResult only if Failed() must
// first call WouldReportJSException even if this ErrorResult has not failed.
//
// The exn argument to ThrowJSException can be in any compartment. It does
// not have to be in the compartment of cx. If someone later uses it, they

View File

@ -1124,7 +1124,10 @@ enum BluetoothGattStatus {
GATT_STATUS_INSUFFICIENT_ENCRYPTION,
GATT_STATUS_UNSUPPORTED_GROUP_TYPE,
GATT_STATUS_INSUFFICIENT_RESOURCES,
GATT_STATUS_UNKNOWN_ERROR
GATT_STATUS_UNKNOWN_ERROR,
GATT_STATUS_BEGIN_OF_APPLICATION_ERROR = 0x80,
GATT_STATUS_END_OF_APPLICATION_ERROR = 0x9f,
GATT_STATUS_END_OF_ERROR = 0x100
};
enum BluetoothGattAuthReq {

View File

@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothGattReplyRunnable.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/Promise.h"
using namespace mozilla::dom;
USING_BLUETOOTH_NAMESPACE
BluetoothGattReplyRunnable::BluetoothGattReplyRunnable(Promise* aPromise)
: BluetoothReplyRunnable(nullptr, aPromise)
{
MOZ_ASSERT(aPromise);
}
void
BluetoothGattReplyRunnable::GattStatusToDOMStatus(
const BluetoothGattStatus aGattStatus, nsresult& aDOMStatus)
{
/**
* https://webbluetoothcg.github.io/web-bluetooth/#error-handling
*
* ToDo:
* If the procedure times out or the ATT Bearer is terminated for any
* reason, return |NS_ERROR_DOM_NETWORK_ERR|.
*/
// Error Code Mapping
if ((aGattStatus >= GATT_STATUS_BEGIN_OF_APPLICATION_ERROR) &&
(aGattStatus <= GATT_STATUS_END_OF_APPLICATION_ERROR) &&
IsWrite()) {
aDOMStatus = NS_ERROR_DOM_INVALID_MODIFICATION_ERR;
return;
}
switch (aGattStatus) {
case GATT_STATUS_INVALID_ATTRIBUTE_LENGTH:
aDOMStatus = NS_ERROR_DOM_INVALID_MODIFICATION_ERR;
break;
case GATT_STATUS_ATTRIBUTE_NOT_LONG:
/**
* ToDo:
* While receiving |GATT_STATUS_ATTRIBUTE_NOT_LONG|, we need to check
* whether 'Long' sub-procedure has been used or not.
* If we have used 'Long' sub-procedure, we need to retry the step
* without using 'Long' sub-procedure (e.g. Read Blob Request) based on
* W3C reuqirements. If it fails again due to the length of the value
* being written, convert the error status to
* |NS_ERROR_DOM_INVALID_MODIFICATION_ERR|.
* If 'Long' sub-procedure has not been used, convert the error status to
* |NS_ERROR_DOM_NOT_SUPPORTED_ERR|.
*/
aDOMStatus = NS_ERROR_DOM_INVALID_MODIFICATION_ERR;
break;
case GATT_STATUS_INSUFFICIENT_AUTHENTICATION:
case GATT_STATUS_INSUFFICIENT_ENCRYPTION:
case GATT_STATUS_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
/**
* ToDo:
* In W3C requirement, UA SHOULD attempt to increase the security level
* of the connection while receiving those error statuses. If it fails or
* UA doesn't suuport return the |NS_ERROR_DOM_SECURITY_ERR|.
*
* Note: The Gecko have already attempted to increase the security level
* after receiving |GATT_STATUS_INSUFFICIENT_AUTHENTICATION| or
* |GATT_STATUS_INSUFFICIENT_ENCRYPTION|. Only need to handle
* |GATT_STATUS_INSUFFICIENT_ENCRYPTION_KEY_SIZE| in the future.
*/
aDOMStatus = NS_ERROR_DOM_SECURITY_ERR;
break;
case GATT_STATUS_INSUFFICIENT_AUTHORIZATION:
aDOMStatus = NS_ERROR_DOM_SECURITY_ERR;
break;
case GATT_STATUS_INVALID_HANDLE:
case GATT_STATUS_INVALID_PDU:
case GATT_STATUS_INVALID_OFFSET:
case GATT_STATUS_ATTRIBUTE_NOT_FOUND:
case GATT_STATUS_UNSUPPORTED_GROUP_TYPE:
case GATT_STATUS_READ_NOT_PERMITTED:
case GATT_STATUS_WRITE_NOT_PERMITTED:
case GATT_STATUS_REQUEST_NOT_SUPPORTED:
case GATT_STATUS_PREPARE_QUEUE_FULL:
case GATT_STATUS_INSUFFICIENT_RESOURCES:
case GATT_STATUS_UNLIKELY_ERROR:
default:
aDOMStatus = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
break;
}
}
nsresult
BluetoothGattReplyRunnable::FireErrorString()
{
MOZ_ASSERT(mReply);
if (!mPromise ||
mReply->type() != BluetoothReply::TBluetoothReplyError ||
mReply->get_BluetoothReplyError().errorStatus().type() !=
BluetoothErrorStatus::TBluetoothGattStatus) {
return BluetoothReplyRunnable::FireErrorString();
}
nsresult domStatus = NS_OK;
GattStatusToDOMStatus(
mReply->get_BluetoothReplyError().errorStatus().get_BluetoothGattStatus(),
domStatus);
nsresult rv = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM, domStatus);
mPromise->MaybeReject(rv);
return NS_OK;
}

View File

@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_BluetoothGattReplyRunnable_h
#define mozilla_dom_bluetooth_BluetoothGattReplyRunnable_h
#include "BluetoothReplyRunnable.h"
class nsIDOMDOMRequest;
namespace mozilla {
namespace dom {
class Promise;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReply;
class BluetoothGattReplyRunnable : public BluetoothReplyRunnable
{
public:
BluetoothGattReplyRunnable(Promise* aPromise);
protected:
virtual ~BluetoothGattReplyRunnable() {}
private:
virtual nsresult FireErrorString() override;
void GattStatusToDOMStatus(const BluetoothGattStatus aGattStatus,
nsresult& aDOMStatus);
virtual bool IsWrite()
{
return false;
}
};
class BluetoothGattVoidReplyRunnable : public BluetoothGattReplyRunnable
{
public:
BluetoothGattVoidReplyRunnable(Promise* aPromise)
: BluetoothGattReplyRunnable(aPromise) {}
~BluetoothGattVoidReplyRunnable() {}
protected:
virtual bool
ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) override
{
aValue.setUndefined();
return true;
}
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_BluetoothGattReplyRunnable_h

View File

@ -19,8 +19,8 @@ USING_BLUETOOTH_NAMESPACE
BluetoothReplyRunnable::BluetoothReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise)
: mDOMRequest(aReq)
, mPromise(aPromise)
: mPromise(aPromise)
, mDOMRequest(aReq)
, mErrorStatus(STATUS_FAIL)
{}
@ -97,8 +97,7 @@ BluetoothReplyRunnable::Run()
nsresult rv;
if (mReply->type() != BluetoothReply::TBluetoothReplySuccess) {
SetError(mReply->get_BluetoothReplyError().errorString(),
mReply->get_BluetoothReplyError().errorStatus());
ParseErrorStatus();
rv = FireErrorString();
} else if (!ParseSuccessfulReply(&v)) {
rv = FireErrorString();
@ -129,6 +128,22 @@ void
BluetoothReplyRunnable::OnErrorFired()
{}
void
BluetoothReplyRunnable::ParseErrorStatus()
{
MOZ_ASSERT(mReply);
MOZ_ASSERT(mReply->type() == BluetoothReply::TBluetoothReplyError);
if (mReply->get_BluetoothReplyError().errorStatus().type() ==
BluetoothErrorStatus::TBluetoothStatus) {
SetError(
mReply->get_BluetoothReplyError().errorString(),
mReply->get_BluetoothReplyError().errorStatus().get_BluetoothStatus());
} else {
SetError(mReply->get_BluetoothReplyError().errorString(), STATUS_FAIL);
}
}
BluetoothVoidReplyRunnable::BluetoothVoidReplyRunnable(nsIDOMDOMRequest* aReq,
Promise* aPromise)
: BluetoothReplyRunnable(aReq, aPromise)

View File

@ -48,14 +48,19 @@ protected:
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) = 0;
virtual nsresult FireErrorString();
// This is an autoptr so we don't have to bring the ipdl include into the
// header. We assume we'll only be running this once and it should die on
// scope out of Run() anyways.
nsAutoPtr<BluetoothReply> mReply;
RefPtr<Promise> mPromise;
private:
virtual void ParseErrorStatus();
nsresult FireReplySuccess(JS::Handle<JS::Value> aVal);
nsresult FireErrorString();
virtual void OnSuccessFired();
virtual void OnErrorFired();
@ -69,7 +74,6 @@ private:
* TODO: remove mDOMRequest once all methods adopt Promise.
*/
nsCOMPtr<nsIDOMDOMRequest> mDOMRequest;
RefPtr<Promise> mPromise;
BluetoothStatus mErrorStatus;
nsString mErrorString;

View File

@ -812,6 +812,20 @@ DispatchReplyError(BluetoothReplyRunnable* aRunnable,
NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(aRunnable)));
}
void
DispatchReplyError(BluetoothReplyRunnable* aRunnable,
const enum BluetoothGattStatus aGattStatus)
{
MOZ_ASSERT(aRunnable);
// Reply will be deleted by the runnable after running on main thread
BluetoothReply* reply =
new BluetoothReply(BluetoothReplyError(aGattStatus, EmptyString()));
aRunnable->SetReply(reply);
NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(aRunnable)));
}
void
DispatchStatusChangedEvent(const nsAString& aType,
const BluetoothAddress& aAddress,

View File

@ -379,6 +379,20 @@ void
DispatchReplyError(BluetoothReplyRunnable* aRunnable,
const enum BluetoothStatus aStatus);
/**
* Dispatch failed bluetooth reply with error bluetooth gatt status and
* string.
*
* This function is for bluetooth to return Promise as the error status is
* bluetooth gatt status.
*
* @param aRunnable the runnable to reply bluetooth request.
* @param aGattStatus the bluettoh gatt error status to reply failed request.
*/
void
DispatchReplyError(BluetoothReplyRunnable* aRunnable,
const enum BluetoothGattStatus aGattStatus);
void
DispatchStatusChangedEvent(const nsAString& aType,
const BluetoothAddress& aDeviceAddress,

View File

@ -367,6 +367,14 @@ struct ParamTraits<mozilla::dom::bluetooth::BluetoothGattAdvertisingData>
}
};
template <>
struct ParamTraits<mozilla::dom::bluetooth::BluetoothGattStatus>
: public ContiguousEnumSerializer<
mozilla::dom::bluetooth::BluetoothGattStatus,
mozilla::dom::bluetooth::GATT_STATUS_SUCCESS,
mozilla::dom::bluetooth::GATT_STATUS_END_OF_ERROR>
{ };
} // namespace IPC
#endif // mozilla_dom_bluetooth_ipc_BluetoothMessageUtils_h

View File

@ -20,6 +20,8 @@ using mozilla::dom::bluetooth::BluetoothGattResponse
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattServiceId
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattStatus
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothGattWriteType
from "mozilla/dom/bluetooth/BluetoothCommon.h";
using mozilla::dom::bluetooth::BluetoothRemoteName
@ -86,9 +88,15 @@ struct BluetoothReplySuccess
BluetoothValue value;
};
union BluetoothErrorStatus
{
BluetoothStatus;
BluetoothGattStatus;
};
struct BluetoothReplyError
{
BluetoothStatus errorStatus;
BluetoothErrorStatus errorStatus;
nsString errorString;
};

View File

@ -16,6 +16,7 @@ if CONFIG['MOZ_B2G_BT']:
]
SOURCES += [
'common/BluetoothGattReplyRunnable.cpp',
'common/BluetoothHidManager.cpp',
'common/BluetoothInterface.cpp',
'common/BluetoothProfileController.cpp',

View File

@ -119,6 +119,8 @@
#include "nsFontMetrics.h"
#include "Units.h"
#include "CanvasUtils.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#undef free // apparently defined by some windows header, clashing with a free()
// method in SkTypes.h
@ -2207,6 +2209,16 @@ GetFontParentStyleContext(Element* aElement, nsIPresShell* aPresShell,
}
// otherwise inherit from default (10px sans-serif)
nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
if (!styleSet) {
// XXXheycam ServoStyleSets do not support resolving style from a list of
// rules yet.
NS_ERROR("stylo: cannot resolve style for canvas from a ServoStyleSet yet");
aError.Throw(NS_ERROR_FAILURE);
return nullptr;
}
bool changed;
RefPtr<css::Declaration> parentRule =
CreateFontDeclaration(NS_LITERAL_STRING("10px sans-serif"),
@ -2215,7 +2227,7 @@ GetFontParentStyleContext(Element* aElement, nsIPresShell* aPresShell,
nsTArray<nsCOMPtr<nsIStyleRule>> parentRules;
parentRules.AppendElement(parentRule);
RefPtr<nsStyleContext> result =
aPresShell->StyleSet()->ResolveStyleForRules(nullptr, parentRules);
styleSet->ResolveStyleForRules(nullptr, parentRules);
if (!result) {
aError.Throw(NS_ERROR_FAILURE);
@ -2242,6 +2254,15 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
nsAString& aOutUsedFont,
ErrorResult& aError)
{
nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
if (!styleSet) {
// XXXheycam ServoStyleSets do not support resolving style from a list of
// rules yet.
NS_ERROR("stylo: cannot resolve style for canvas from a ServoStyleSet yet");
aError.Throw(NS_ERROR_FAILURE);
return nullptr;
}
bool fontParsedSuccessfully = false;
RefPtr<css::Declaration> decl =
CreateFontDeclaration(aFont, aPresShell->GetDocument(),
@ -2281,7 +2302,6 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
// add a rule to prevent text zoom from affecting the style
rules.AppendElement(new nsDisableTextZoomStyleRule);
nsStyleSet* styleSet = aPresShell->StyleSet();
RefPtr<nsStyleContext> sc =
styleSet->ResolveStyleForRules(parentContext, rules);
@ -2311,6 +2331,15 @@ ResolveStyleForFilter(const nsAString& aFilterString,
nsStyleContext* aParentContext,
ErrorResult& aError)
{
nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
if (!styleSet) {
// XXXheycam ServoStyleSets do not support resolving style from a list of
// rules yet.
NS_ERROR("stylo: cannot resolve style for canvas from a ServoStyleSet yet");
aError.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsIDocument* document = aPresShell->GetDocument();
bool filterChanged = false;
RefPtr<css::Declaration> decl =
@ -2331,7 +2360,7 @@ ResolveStyleForFilter(const nsAString& aFilterString,
rules.AppendElement(decl);
RefPtr<nsStyleContext> sc =
aPresShell->StyleSet()->ResolveStyleForRules(aParentContext, rules);
styleSet->ResolveStyleForRules(aParentContext, rules);
return sc.forget();
}

View File

@ -295,18 +295,20 @@ tags = offscreencanvas
tags = offscreencanvas
[test_offscreencanvas_dynamic_fallback.html]
tags = offscreencanvas
skip-if = (os == 'mac' && os_version == '10.6')
[test_offscreencanvas_sharedworker.html]
tags = offscreencanvas
skip-if = (os == 'mac' && os_version == '10.6')
[test_offscreencanvas_serviceworker.html]
tags = offscreencanvas
skip-if = buildapp == 'b2g'
skip-if = (buildapp == 'b2g' || (os == 'mac' && os_version == '10.6'))
[test_offscreencanvas_neuter.html]
tags = offscreencanvas
[test_offscreencanvas_many.html]
tags = offscreencanvas
skip-if = (toolkit == 'android' || toolkit == 'gonk' || toolkit == 'windows' || toolkit == 'gtk2' || toolkit == 'gtk3')
skip-if = (toolkit == 'android' || toolkit == 'gonk' || toolkit == 'windows' || toolkit == 'gtk2' || toolkit == 'gtk3' || (os == 'mac' && os_version == '10.6'))
[test_offscreencanvas_sizechange.html]
tags = offscreencanvas
[test_offscreencanvas_subworker.html]
tags = offscreencanvas
skip-if = (toolkit == 'android' || toolkit == 'gonk' || toolkit == 'windows' || toolkit == 'gtk2' || toolkit == 'gtk3')
skip-if = (toolkit == 'android' || toolkit == 'gonk' || toolkit == 'windows' || toolkit == 'gtk2' || toolkit == 'gtk3' || (os == 'mac' && os_version == '10.6'))

View File

@ -172,63 +172,83 @@ private:
#define NS_DEFINE_EVENT_STATE_MACRO(_val) \
(mozilla::EventStates(mozilla::EventStates::InternalType(1) << _val))
/*
* In order to efficiently convert Gecko EventState values into Servo
* ElementState values [1], we maintain the invariant that the low bits of
* EventState can be masked off to form an ElementState (this works so
* long as Servo never supports a state that Gecko doesn't).
*
* This is unfortunately rather fragile for now, but we should soon have
* the infrastructure to statically-assert that these match up. If you
* need to change these, please notify somebody involved with Stylo.
*
* [1] https://github.com/servo/servo/blob/master/components/style/element_state.rs
*/
// Mouse is down on content.
#define NS_EVENT_STATE_ACTIVE NS_DEFINE_EVENT_STATE_MACRO(0)
// Content has focus.
#define NS_EVENT_STATE_FOCUS NS_DEFINE_EVENT_STATE_MACRO(1)
// Mouse is hovering over content.
#define NS_EVENT_STATE_HOVER NS_DEFINE_EVENT_STATE_MACRO(2)
// Drag is hovering over content.
#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(3)
// Content is URL's target (ref).
#define NS_EVENT_STATE_URLTARGET NS_DEFINE_EVENT_STATE_MACRO(4)
// Content is enabled (and can be disabled).
#define NS_EVENT_STATE_ENABLED NS_DEFINE_EVENT_STATE_MACRO(3)
// Content is disabled.
#define NS_EVENT_STATE_DISABLED NS_DEFINE_EVENT_STATE_MACRO(4)
// Content is checked.
#define NS_EVENT_STATE_CHECKED NS_DEFINE_EVENT_STATE_MACRO(5)
// Content is enabled (and can be disabled).
#define NS_EVENT_STATE_ENABLED NS_DEFINE_EVENT_STATE_MACRO(6)
// Content is disabled.
#define NS_EVENT_STATE_DISABLED NS_DEFINE_EVENT_STATE_MACRO(7)
// Content is in the indeterminate state.
#define NS_EVENT_STATE_INDETERMINATE NS_DEFINE_EVENT_STATE_MACRO(6)
#define NS_EVENT_STATE_HIGHEST_SERVO_BIT 6
/*
* Bits below here do not have Servo-related ordering constraints.
*/
// Drag is hovering over content.
#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(7)
// Content is URL's target (ref).
#define NS_EVENT_STATE_URLTARGET NS_DEFINE_EVENT_STATE_MACRO(8)
// Content is required.
#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(8)
#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(9)
// Content is optional (and can be required).
#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(9)
#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(10)
// Link has been visited.
#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(10)
#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(11)
// Link hasn't been visited.
#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(11)
#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(12)
// Content is valid (and can be invalid).
#define NS_EVENT_STATE_VALID NS_DEFINE_EVENT_STATE_MACRO(12)
#define NS_EVENT_STATE_VALID NS_DEFINE_EVENT_STATE_MACRO(13)
// Content is invalid.
#define NS_EVENT_STATE_INVALID NS_DEFINE_EVENT_STATE_MACRO(13)
#define NS_EVENT_STATE_INVALID NS_DEFINE_EVENT_STATE_MACRO(14)
// Content value is in-range (and can be out-of-range).
#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(14)
#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(15)
// Content value is out-of-range.
#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(15)
#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(16)
// These two are temporary (see bug 302188)
// Content is read-only.
#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(16)
#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(17)
// Content is editable.
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(17)
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(18)
// Content is the default one (meaning depends of the context).
#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(18)
#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(19)
// Content could not be rendered (image/object/etc).
#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(19)
#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(20)
// Content disabled by the user (images turned off, say).
#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(20)
#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(21)
// Content suppressed by the user (ad blocking, etc).
#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(21)
#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(22)
// Content is still loading such that there is nothing to show the
// user (eg an image which hasn't started coming in yet).
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(22)
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(23)
// Content is of a type that gecko can't handle.
#define NS_EVENT_STATE_TYPE_UNSUPPORTED NS_DEFINE_EVENT_STATE_MACRO(23)
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(24)
#define NS_EVENT_STATE_TYPE_UNSUPPORTED NS_DEFINE_EVENT_STATE_MACRO(24)
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(25)
// Handler for the content has been blocked.
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(25)
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(26)
// Handler for the content has been disabled.
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(26)
// Content is in the indeterminate state.
#define NS_EVENT_STATE_INDETERMINATE NS_DEFINE_EVENT_STATE_MACRO(27)
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(27)
// Handler for the content has crashed
#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(28)
// Content has focus and should show a ring.

View File

@ -27,7 +27,6 @@
#include "nsPresContext.h"
#include "nsStyleContext.h"
#include "nsAutoPtr.h"
#include "nsStyleSet.h"
#include "nsIChannel.h"
#include "nsIContentPolicy.h"
#include "nsContentPolicyUtils.h"

View File

@ -107,6 +107,8 @@
#include "mozilla/dom/HTMLBodyElement.h"
#include "imgIContainer.h"
#include "nsComputedDOMStyle.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -3334,7 +3336,7 @@ IsOrHasAncestorWithDisplayNone(Element* aElement, nsIPresShell* aPresShell)
return false;
}
nsStyleSet* styleSet = aPresShell->StyleSet();
StyleSetHandle styleSet = aPresShell->StyleSet();
RefPtr<nsStyleContext> sc;
for (int32_t i = elementsToCheck.Length() - 1; i >= 0; --i) {
if (sc) {

View File

@ -114,6 +114,8 @@
#include "nsIFrame.h"
#include "nsIContent.h"
#include "nsLayoutStylesheetCache.h"
#include "mozilla/StyleSheetHandle.h"
#include "mozilla/StyleSheetHandleInlines.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -267,7 +269,7 @@ nsHTMLDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
already_AddRefed<nsIPresShell>
nsHTMLDocument::CreateShell(nsPresContext* aContext,
nsViewManager* aViewManager,
nsStyleSet* aStyleSet)
StyleSetHandle aStyleSet)
{
return doCreateShell(aContext, aViewManager, aStyleSet);
}
@ -2641,12 +2643,14 @@ nsHTMLDocument::TearingDownEditor(nsIEditor *aEditor)
if (!presShell)
return;
nsTArray<RefPtr<CSSStyleSheet>> agentSheets;
nsTArray<StyleSheetHandle::RefPtr> agentSheets;
presShell->GetAgentStyleSheets(agentSheets);
agentSheets.RemoveElement(nsLayoutStylesheetCache::ContentEditableSheet());
auto cache = nsLayoutStylesheetCache::For(GetStyleBackendType());
agentSheets.RemoveElement(cache->ContentEditableSheet());
if (oldState == eDesignMode)
agentSheets.RemoveElement(nsLayoutStylesheetCache::DesignModeSheet());
agentSheets.RemoveElement(cache->DesignModeSheet());
presShell->SetAgentStyleSheets(agentSheets);
@ -2780,12 +2784,13 @@ nsHTMLDocument::EditingStateChanged()
// Before making this window editable, we need to modify UA style sheet
// because new style may change whether focused element will be focusable
// or not.
nsTArray<RefPtr<CSSStyleSheet>> agentSheets;
nsTArray<StyleSheetHandle::RefPtr> agentSheets;
rv = presShell->GetAgentStyleSheets(agentSheets);
NS_ENSURE_SUCCESS(rv, rv);
CSSStyleSheet* contentEditableSheet =
nsLayoutStylesheetCache::ContentEditableSheet();
auto cache = nsLayoutStylesheetCache::For(GetStyleBackendType());
StyleSheetHandle contentEditableSheet = cache->ContentEditableSheet();
if (!agentSheets.Contains(contentEditableSheet)) {
agentSheets.AppendElement(contentEditableSheet);
@ -2796,8 +2801,7 @@ nsHTMLDocument::EditingStateChanged()
// specific states on the elements.
if (designMode) {
// designMode is being turned on (overrides contentEditable).
CSSStyleSheet* designModeSheet =
nsLayoutStylesheetCache::DesignModeSheet();
StyleSheetHandle designModeSheet = cache->DesignModeSheet();
if (!agentSheets.Contains(designModeSheet)) {
agentSheets.AppendElement(designModeSheet);
}
@ -2807,7 +2811,7 @@ nsHTMLDocument::EditingStateChanged()
}
else if (oldState == eDesignMode) {
// designMode is being turned off (contentEditable is still on).
agentSheets.RemoveElement(nsLayoutStylesheetCache::DesignModeSheet());
agentSheets.RemoveElement(cache->DesignModeSheet());
updateState = true;
}

View File

@ -53,9 +53,10 @@ public:
virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
nsIPrincipal* aPrincipal) override;
virtual already_AddRefed<nsIPresShell> CreateShell(nsPresContext* aContext,
virtual already_AddRefed<nsIPresShell> CreateShell(
nsPresContext* aContext,
nsViewManager* aViewManager,
nsStyleSet* aStyleSet) override;
mozilla::StyleSetHandle aStyleSet) override;
virtual nsresult StartDocumentLoad(const char* aCommand,
nsIChannel* aChannel,

View File

@ -2584,7 +2584,10 @@ static void
PreloadSlowThings()
{
// This fetches and creates all the built-in stylesheets.
nsLayoutStylesheetCache::UserContentSheet();
//
// XXXheycam In the future we might want to preload the Servo-flavoured
// UA sheets too, but for now that will be a waste of time.
nsLayoutStylesheetCache::For(StyleBackendType::Gecko)->UserContentSheet();
TabChild::PreloadSlowThings();

View File

@ -185,6 +185,8 @@
#include "nsPluginHost.h"
#include "nsPluginTags.h"
#include "nsIBlocklistService.h"
#include "mozilla/StyleSheetHandle.h"
#include "mozilla/StyleSheetHandleInlines.h"
#include "nsIBidiKeyboard.h"
@ -241,13 +243,6 @@ using namespace mozilla::system;
#include "mozilla/dom/SpeechSynthesisParent.h"
#endif
#ifdef ENABLE_TESTS
#include "BackgroundChildImpl.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
#endif
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX)
#include "mozilla/SandboxInfo.h"
#include "mozilla/SandboxBroker.h"
@ -305,130 +300,6 @@ using namespace mozilla::jsipc;
using namespace mozilla::psm;
using namespace mozilla::widget;
#ifdef ENABLE_TESTS
class BackgroundTester final : public nsIIPCBackgroundChildCreateCallback,
public nsIObserver
{
static uint32_t sCallbackCount;
private:
~BackgroundTester()
{ }
virtual void
ActorCreated(PBackgroundChild* aActor) override
{
MOZ_RELEASE_ASSERT(aActor,
"Failed to create a PBackgroundChild actor!");
NS_NAMED_LITERAL_CSTRING(testStr, "0123456789");
PBackgroundTestChild* testActor =
aActor->SendPBackgroundTestConstructor(testStr);
MOZ_RELEASE_ASSERT(testActor);
if (!sCallbackCount) {
PBackgroundChild* existingBackgroundChild =
BackgroundChild::GetForCurrentThread();
MOZ_RELEASE_ASSERT(existingBackgroundChild);
MOZ_RELEASE_ASSERT(existingBackgroundChild == aActor);
bool ok =
existingBackgroundChild->
SendPBackgroundTestConstructor(testStr);
MOZ_RELEASE_ASSERT(ok);
// Callback 3.
ok = BackgroundChild::GetOrCreateForCurrentThread(this);
MOZ_RELEASE_ASSERT(ok);
}
sCallbackCount++;
}
virtual void
ActorFailed() override
{
MOZ_CRASH("Failed to create a PBackgroundChild actor!");
}
NS_IMETHOD
Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
override
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_RELEASE_ASSERT(observerService);
nsresult rv = observerService->RemoveObserver(this, aTopic);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
if (!strcmp(aTopic, "profile-after-change")) {
if (mozilla::Preferences::GetBool("pbackground.testing", false)) {
rv = observerService->AddObserver(this, "xpcom-shutdown", false);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
// Callback 1.
bool ok = BackgroundChild::GetOrCreateForCurrentThread(this);
MOZ_RELEASE_ASSERT(ok);
BackgroundChildImpl::ThreadLocal* threadLocal =
BackgroundChildImpl::GetThreadLocalForCurrentThread();
MOZ_RELEASE_ASSERT(threadLocal);
// Callback 2.
ok = BackgroundChild::GetOrCreateForCurrentThread(this);
MOZ_RELEASE_ASSERT(ok);
}
return NS_OK;
}
if (!strcmp(aTopic, "xpcom-shutdown")) {
MOZ_RELEASE_ASSERT(sCallbackCount == 3);
return NS_OK;
}
MOZ_CRASH("Unknown observer topic!");
}
public:
NS_DECL_ISUPPORTS
};
uint32_t BackgroundTester::sCallbackCount = 0;
NS_IMPL_ISUPPORTS(BackgroundTester, nsIIPCBackgroundChildCreateCallback,
nsIObserver)
#endif // ENABLE_TESTS
void
MaybeTestPBackground()
{
#ifdef ENABLE_TESTS
// This test relies on running the event loop and XPCShell does not always
// do so. Bail out here if we detect that we're running in XPCShell.
if (PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) {
return;
}
// This is called too early at startup to test preferences directly. We have
// to install an observer to be notified when preferences are available.
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_RELEASE_ASSERT(observerService);
nsCOMPtr<nsIObserver> observer = new BackgroundTester();
nsresult rv = observerService->AddObserver(observer, "profile-after-change",
false);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
#endif
}
// XXX Workaround for bug 986973 to maintain the existing broken semantics
template<>
struct nsIConsoleService::COMTypeInfo<nsConsoleService, void> {
@ -862,10 +733,6 @@ ContentParent::StartUp()
// Try to preallocate a process that we can transform into an app later.
PreallocatedProcessManager::AllocateAfterDelay();
// Test the PBackground infrastructure on ENABLE_TESTS builds when a special
// testing preference is set.
MaybeTestPBackground();
sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
@ -2697,19 +2564,19 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
// This looks like a lot of work, but in a normal browser session we just
// send two loads.
for (CSSStyleSheet* sheet : *sheetService->AgentStyleSheets()) {
for (StyleSheetHandle sheet : *sheetService->AgentStyleSheets()) {
URIParams uri;
SerializeURI(sheet->GetSheetURI(), uri);
Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AGENT_SHEET);
}
for (CSSStyleSheet* sheet : *sheetService->UserStyleSheets()) {
for (StyleSheetHandle sheet : *sheetService->UserStyleSheets()) {
URIParams uri;
SerializeURI(sheet->GetSheetURI(), uri);
Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::USER_SHEET);
}
for (CSSStyleSheet* sheet : *sheetService->AuthorStyleSheets()) {
for (StyleSheetHandle sheet : *sheetService->AuthorStyleSheets()) {
URIParams uri;
SerializeURI(sheet->GetSheetURI(), uri);
Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AUTHOR_SHEET);
@ -3674,13 +3541,11 @@ ContentParent::DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParen
/* static */ void
ContentParent::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure)
{
#ifdef ENABLE_TESTS
// We don't want to time out the content process during XPCShell tests. This
// is the easiest way to ensure that.
if (PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) {
return;
}
#endif
auto self = static_cast<ContentParent*>(aClosure);
self->KillHard("ShutDownKill");

View File

@ -111,9 +111,9 @@ nsMathMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// Enable MathML and setup the style sheet during binding, not element
// construction, because we could move a MathML element from the document
// that created it to another document.
auto cache = nsLayoutStylesheetCache::For(doc->GetStyleBackendType());
doc->SetMathMLEnabled();
doc->
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::MathMLSheet());
doc->EnsureOnDemandBuiltInUASheet(cache->MathMLSheet());
// Rebuild style data for the presshell, because style system
// optimizations may have taken place assuming MathML was disabled.

View File

@ -179,19 +179,19 @@ HostInDomain(const nsCString &aHost, const nsCString &aPattern)
}
static bool
HostHasPermission(nsIURI &docURI)
HostIsHttps(nsIURI &docURI)
{
nsresult rv;
bool isHttps;
rv = docURI.SchemeIs("https",&isHttps);
nsresult rv = docURI.SchemeIs("https", &isHttps);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (!isHttps) {
return false;
return isHttps;
}
static bool
HostHasPermission(nsIURI &docURI)
{
nsAdoptingCString hostName;
docURI.GetAsciiHost(hostName); //normalize UTF8 to ASCII equivalent
nsAdoptingCString domainWhiteList =
@ -203,6 +203,7 @@ HostHasPermission(nsIURI &docURI)
}
// Get UTF8 to ASCII domain name normalization service
nsresult rv;
nsCOMPtr<nsIIDNService> idnService =
do_GetService("@mozilla.org/network/idn-service;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -224,7 +225,7 @@ HostHasPermission(nsIURI &docURI)
end = domainWhiteList.Length();
}
rv = idnService->ConvertUTF8toACE(Substring(domainWhiteList, begin, end),
rv = idnService->ConvertUTF8toACE(Substring(domainWhiteList, begin, end - begin),
domainName);
if (NS_SUCCEEDED(rv)) {
if (HostInDomain(hostName, domainName)) {
@ -1900,7 +1901,8 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
#endif
) ||
#endif
(!privileged && !HostHasPermission(*docURI))) {
(!privileged && !HostIsHttps(*docURI)) ||
!(loop || HostHasPermission(*docURI))) {
RefPtr<MediaStreamError> error =
new MediaStreamError(aWindow,
NS_LITERAL_STRING("SecurityError"));

View File

@ -236,14 +236,20 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
// Content-Range header tells us otherwise.
bool boundedSeekLimit = true;
// Check response code for byte-range requests (seeking, chunk requests).
if (!mByteRange.IsEmpty() && (responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) {
if (responseStatus == HTTP_PARTIAL_RESPONSE_CODE) {
// Parse Content-Range header.
int64_t rangeStart = 0;
int64_t rangeEnd = 0;
int64_t rangeTotal = 0;
rv = ParseContentRangeHeader(hc, rangeStart, rangeEnd, rangeTotal);
if (NS_FAILED(rv)) {
// Content-Range header text should be parse-able.
// We received 'Content-Range', so the server accepts range requests.
acceptsRanges = NS_SUCCEEDED(rv);
if (!mByteRange.IsEmpty()) {
if (!acceptsRanges) {
// Content-Range header text should be parse-able when processing a
// range requests.
CMLOG("Error processing \'Content-Range' for "
"HTTP_PARTIAL_RESPONSE_CODE: rv[%x] channel[%p] decoder[%p]",
rv, hc.get(), mCallback.get());
@ -251,7 +257,6 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
CloseChannel();
return NS_OK;
}
// Give some warnings if the ranges are unexpected.
// XXX These could be error conditions.
NS_WARN_IF_FALSE(mByteRange.mStart == rangeStart,
@ -269,10 +274,11 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
mCacheStream.NotifyDataLength(rangeTotal);
}
mCacheStream.NotifyDataStarted(rangeStart);
mOffset = rangeStart;
// We received 'Content-Range', so the server accepts range requests.
acceptsRanges = true;
} else if (contentLength < 0 && acceptsRanges && rangeTotal > 0) {
// Content-Length was unknown, use content-range instead.
contentLength = rangeTotal;
}
} else if (((mOffset > 0) || !mByteRange.IsEmpty())
&& (responseStatus == HTTP_OK_CODE)) {
// If we get an OK response but we were seeking, or requesting a byte
@ -283,13 +289,12 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
// The server claimed it supported range requests. It lied.
acceptsRanges = false;
} else if (mOffset == 0 &&
}
if (mOffset == 0 && contentLength >= 0 &&
(responseStatus == HTTP_OK_CODE ||
responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) {
if (contentLength >= 0) {
mCacheStream.NotifyDataLength(contentLength);
}
}
// XXX we probably should examine the Content-Range header in case
// the server gave us a range which is not quite what we asked for

View File

@ -1092,6 +1092,9 @@ RTCPeerConnection.prototype = {
var encodings = parameters.encodings || [];
encodings.reduce((uniqueRids, encoding) => {
if (encoding.scaleResolutionDownBy < 1.0) {
throw new this._win.RangeError("scaleResolutionDownBy must be >= 1.0");
}
if (!encoding.rid && encodings.length > 1) {
throw new this._win.DOMException("Missing rid", "TypeError");
}

View File

@ -1222,7 +1222,11 @@ GeckoMediaPluginServiceParent::IsPersistentStorageAllowed(const nsACString& aNod
{
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
NS_ENSURE_ARG(aOutAllowed);
*aOutAllowed = mPersistentStorageAllowed.Get(aNodeId);
// We disallow persistent storage for the NodeId used for shared GMP
// decoding, to prevent GMP decoding being used to track what a user
// watches somehow.
*aOutAllowed = !aNodeId.Equals(SHARED_GMP_DECODING_NODE_ID) &&
mPersistentStorageAllowed.Get(aNodeId);
return NS_OK;
}

View File

@ -136,7 +136,7 @@ GMPAudioDecoder::InitTags(nsTArray<nsCString>& aTags)
nsCString
GMPAudioDecoder::GetNodeId()
{
return NS_LITERAL_CSTRING("");
return SHARED_GMP_DECODING_NODE_ID;
}
void

View File

@ -10,6 +10,19 @@
#include "PlatformDecoderModule.h"
#include "mozilla/Maybe.h"
// The special NodeId we use when doing unencrypted decoding using the GMP's
// decoder. This ensures that each GMP MediaDataDecoder we create doesn't
// require spinning up a new process, but instead we run all instances of
// GMP decoders in the one process, to reduce overhead.
//
// Note: GMP storage is isolated by NodeId, and non persistent for this
// special NodeId, and the only way a GMP can communicate with the outside
// world is through the EME GMP APIs, and we never run EME with this NodeID
// (because NodeIds are random strings which can't contain the '-' character),
// so there's no way a malicious GMP can harvest, store, and then report any
// privacy sensitive data about what users are watching.
#define SHARED_GMP_DECODING_NODE_ID NS_LITERAL_CSTRING("gmp-shared-decoding")
namespace mozilla {
class GMPDecoderModule : public PlatformDecoderModule {

View File

@ -118,7 +118,7 @@ GMPVideoDecoder::InitTags(nsTArray<nsCString>& aTags)
nsCString
GMPVideoDecoder::GetNodeId()
{
return NS_LITERAL_CSTRING("");
return SHARED_GMP_DECODING_NODE_ID;
}
GMPUniquePtr<GMPVideoEncodedFrame>

View File

@ -35,6 +35,9 @@ extern mozilla::LogModule* GetPDMLog();
return NS_ERROR_FAILURE; \
} \
// Android proprietary value.
#define ANDROID_OMX_VIDEO_CodingVP8 (static_cast<OMX_VIDEO_CODINGTYPE>(9))
using namespace android;
namespace mozilla {
@ -360,7 +363,7 @@ GonkOmxPlatformLayer::AllocateOmxBuffer(OMX_DIRTYPE aType,
// Get port definition.
OMX_PARAM_PORTDEFINITIONTYPE def;
nsTArray<uint32_t> portindex;
GetOmxPortIndex(portindex);
GetPortIndices(portindex);
for (auto idx : portindex) {
InitOmxParameter(&def);
def.nPortIndex = idx;
@ -618,12 +621,16 @@ GonkOmxPlatformLayer::FindComponents(const nsACString& aMimeType,
useHardwareCodecOnly = true;
}
const char* mime = aMimeType.Data();
// Translate VP8 MIME type to Android format.
if (aMimeType.EqualsLiteral("video/webm; codecs=vp8")) {
mime = "video/x-vnd.on2.vp8";
}
size_t start = 0;
bool found = false;
while (true) {
ssize_t index = codecs->findCodecByType(aMimeType.Data(),
false /* encoder */,
start);
ssize_t index = codecs->findCodecByType(mime, false /* encoder */, start);
if (index < 0) {
break;
}
@ -652,4 +659,13 @@ GonkOmxPlatformLayer::FindComponents(const nsACString& aMimeType,
return found;
}
OMX_VIDEO_CODINGTYPE
GonkOmxPlatformLayer::CompressionFormat()
{
MOZ_ASSERT(mInfo);
return mInfo->mMimeType.EqualsLiteral("video/webm; codecs=vp8") ?
ANDROID_OMX_VIDEO_CodingVP8 : OmxPlatformLayer::CompressionFormat();
}
} // mozilla

View File

@ -156,6 +156,11 @@ public:
static bool FindComponents(const nsACString& aMimeType,
nsTArray<ComponentInfo>* aComponents = nullptr);
// Android/QCOM decoder uses its own OMX_VIDEO_CodingVP8 definition in
// frameworks/native/media/include/openmax/OMX_Video.h, not the one defined
// in OpenMAX v1.1.2 OMX_VideoExt.h
OMX_VIDEO_CODINGTYPE CompressionFormat() override;
protected:
friend GonkBufferData;

View File

@ -916,17 +916,9 @@ MediaDataHelper::MediaDataHelper(const TrackInfo* aTrackInfo,
, mAudioCompactor(mAudioQueue)
, mImageContainer(aImageContainer)
{
// Get latest port definition.
nsTArray<uint32_t> ports;
GetOmxPortIndex(ports);
for (auto idx : ports) {
InitOmxParameter(&mOutputPortDef);
mOutputPortDef.nPortIndex = idx;
mOutputPortDef.nPortIndex = aOmxLayer->OutputPortIndex();
aOmxLayer->GetParameter(OMX_IndexParamPortDefinition, &mOutputPortDef, sizeof(mOutputPortDef));
if (mOutputPortDef.eDir == OMX_DirOutput) {
break;
}
}
}
already_AddRefed<MediaData>

View File

@ -207,12 +207,6 @@ void InitOmxParameter(T* aParam)
aParam->nVersion.s.nVersionMajor = 1;
}
// There should be 2 ports and port number start from 0.
void GetOmxPortIndex(nsTArray<uint32_t>& aPortIndex) {
aPortIndex.AppendElement(0);
aPortIndex.AppendElement(1);
}
}
#endif /* OmxDataDecoder_h_ */

View File

@ -6,6 +6,8 @@
#include "OmxPlatformLayer.h"
#include "OMX_VideoExt.h" // For VP8.
#if defined(MOZ_WIDGET_GONK) && (ANDROID_VERSION == 20 || ANDROID_VERSION == 19)
#define OMX_PLATFORM_GONK
#include "GonkOmxPlatformLayer.h"
@ -45,6 +47,42 @@ typedef OmxConfig<VideoInfo> OmxVideoConfig;
template<typename ConfigType>
UniquePtr<ConfigType> ConfigForMime(const nsACString&);
static OMX_ERRORTYPE
ConfigAudioOutputPort(OmxPlatformLayer& aOmx, const AudioInfo& aInfo)
{
OMX_ERRORTYPE err;
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOmxParameter(&def);
def.nPortIndex = aOmx.OutputPortIndex();
err = aOmx.GetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
RETURN_IF_ERR(err);
def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
err = aOmx.SetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
RETURN_IF_ERR(err);
OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
InitOmxParameter(&pcmParams);
pcmParams.nPortIndex = def.nPortIndex;
err = aOmx.GetParameter(OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
RETURN_IF_ERR(err);
pcmParams.nChannels = aInfo.mChannels;
pcmParams.eNumData = OMX_NumericalDataSigned;
pcmParams.bInterleaved = OMX_TRUE;
pcmParams.nBitPerSample = 16;
pcmParams.nSamplingRate = aInfo.mRate;
pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
err = aOmx.SetParameter(OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
RETURN_IF_ERR(err);
LOG("Config OMX_IndexParamAudioPcm, channel %d, sample rate %d",
pcmParams.nChannels, pcmParams.nSamplingRate);
return OMX_ErrorNone;
}
class OmxAacConfig : public OmxAudioConfig
{
public:
@ -54,6 +92,7 @@ public:
OMX_AUDIO_PARAM_AACPROFILETYPE aacProfile;
InitOmxParameter(&aacProfile);
aacProfile.nPortIndex = aOmx.InputPortIndex();
err = aOmx.GetParameter(OMX_IndexParamAudioAac, &aacProfile, sizeof(aacProfile));
RETURN_IF_ERR(err);
@ -66,7 +105,62 @@ public:
LOG("Config OMX_IndexParamAudioAac, channel %d, sample rate %d, profile %d",
aacProfile.nChannels, aacProfile.nSampleRate, aacProfile.eAACProfile);
return OMX_ErrorNone;
return ConfigAudioOutputPort(aOmx, aInfo);
}
};
class OmxMp3Config : public OmxAudioConfig
{
public:
OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const AudioInfo& aInfo) override
{
OMX_ERRORTYPE err;
OMX_AUDIO_PARAM_MP3TYPE mp3Param;
InitOmxParameter(&mp3Param);
mp3Param.nPortIndex = aOmx.InputPortIndex();
err = aOmx.GetParameter(OMX_IndexParamAudioMp3, &mp3Param, sizeof(mp3Param));
RETURN_IF_ERR(err);
mp3Param.nChannels = aInfo.mChannels;
mp3Param.nSampleRate = aInfo.mRate;
err = aOmx.SetParameter(OMX_IndexParamAudioMp3, &mp3Param, sizeof(mp3Param));
RETURN_IF_ERR(err);
LOG("Config OMX_IndexParamAudioMp3, channel %d, sample rate %d",
mp3Param.nChannels, mp3Param.nSampleRate);
return ConfigAudioOutputPort(aOmx, aInfo);
}
};
enum OmxAmrSampleRate {
kNarrowBand = 8000,
kWideBand = 16000,
};
template <OmxAmrSampleRate R>
class OmxAmrConfig : public OmxAudioConfig
{
public:
OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const AudioInfo& aInfo) override
{
OMX_ERRORTYPE err;
OMX_AUDIO_PARAM_AMRTYPE def;
InitOmxParameter(&def);
def.nPortIndex = aOmx.InputPortIndex();
err = aOmx.GetParameter(OMX_IndexParamAudioAmr, &def, sizeof(def));
RETURN_IF_ERR(err);
def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
err = aOmx.SetParameter(OMX_IndexParamAudioAmr, &def, sizeof(def));
RETURN_IF_ERR(err);
MOZ_ASSERT(aInfo.mChannels == 1);
MOZ_ASSERT(aInfo.mRate == R);
return ConfigAudioOutputPort(aOmx, aInfo);
}
};
@ -79,6 +173,13 @@ ConfigForMime(const nsACString& aMimeType)
if (OmxPlatformLayer::SupportsMimeType(aMimeType)) {
if (aMimeType.EqualsLiteral("audio/mp4a-latm")) {
conf.reset(new OmxAacConfig());
} else if (aMimeType.EqualsLiteral("audio/mp3") ||
aMimeType.EqualsLiteral("audio/mpeg")) {
conf.reset(new OmxMp3Config());
} else if (aMimeType.EqualsLiteral("audio/3gpp")) {
conf.reset(new OmxAmrConfig<OmxAmrSampleRate::kNarrowBand>());
} else if (aMimeType.EqualsLiteral("audio/amr-wb")) {
conf.reset(new OmxAmrConfig<OmxAmrSampleRate::kWideBand>());
}
}
return Move(conf);
@ -90,9 +191,8 @@ ConfigForMime(const nsACString& aMimeType)
class OmxCommonVideoConfig : public OmxVideoConfig
{
public:
explicit OmxCommonVideoConfig(OMX_VIDEO_CODINGTYPE aCodec)
explicit OmxCommonVideoConfig()
: OmxVideoConfig()
, mCodec(aCodec)
{}
OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const VideoInfo& aInfo) override
@ -102,7 +202,7 @@ public:
// Set up in/out port definition.
nsTArray<uint32_t> ports;
GetOmxPortIndex(ports);
aOmx.GetPortIndices(ports);
for (auto idx : ports) {
InitOmxParameter(&def);
def.nPortIndex = idx;
@ -115,7 +215,7 @@ public:
def.format.video.nSliceHeight = aInfo.mImage.height;
if (def.eDir == OMX_DirInput) {
def.format.video.eCompressionFormat = mCodec;
def.format.video.eCompressionFormat = aOmx.CompressionFormat();
def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
if (def.nBufferSize < MIN_VIDEO_INPUT_BUFFER_SIZE) {
def.nBufferSize = aInfo.mImage.width * aInfo.mImage.height;
@ -129,9 +229,6 @@ public:
}
return err;
}
private:
const OMX_VIDEO_CODINGTYPE mCodec;
};
template<>
@ -141,14 +238,7 @@ ConfigForMime(const nsACString& aMimeType)
UniquePtr<OmxVideoConfig> conf;
if (OmxPlatformLayer::SupportsMimeType(aMimeType)) {
if (aMimeType.EqualsLiteral("video/avc")) {
conf.reset(new OmxCommonVideoConfig(OMX_VIDEO_CodingAVC));
} else if (aMimeType.EqualsLiteral("video/mp4v-es") ||
aMimeType.EqualsLiteral("video/mp4")) {
conf.reset(new OmxCommonVideoConfig(OMX_VIDEO_CodingMPEG4));
} else if (aMimeType.EqualsLiteral("video/3gpp")) {
conf.reset(new OmxCommonVideoConfig(OMX_VIDEO_CodingH263));
}
conf.reset(new OmxCommonVideoConfig());
}
return Move(conf);
}
@ -158,11 +248,16 @@ OmxPlatformLayer::Config()
{
MOZ_ASSERT(mInfo);
OMX_PORT_PARAM_TYPE portParam;
InitOmxParameter(&portParam);
if (mInfo->IsAudio()) {
GetParameter(OMX_IndexParamAudioInit, &portParam, sizeof(portParam));
mStartPortNumber = portParam.nStartPortNumber;
UniquePtr<OmxAudioConfig> conf(ConfigForMime<OmxAudioConfig>(mInfo->mMimeType));
MOZ_ASSERT(conf.get());
return conf->Apply(*this, *(mInfo->GetAsAudioInfo()));
} else if (mInfo->IsVideo()) {
GetParameter(OMX_IndexParamVideoInit, &portParam, sizeof(portParam));
UniquePtr<OmxVideoConfig> conf(ConfigForMime<OmxVideoConfig>(mInfo->mMimeType));
MOZ_ASSERT(conf.get());
return conf->Apply(*this, *(mInfo->GetAsVideoInfo()));
@ -172,6 +267,26 @@ OmxPlatformLayer::Config()
}
}
OMX_VIDEO_CODINGTYPE
OmxPlatformLayer::CompressionFormat()
{
MOZ_ASSERT(mInfo);
if (mInfo->mMimeType.EqualsLiteral("video/avc")) {
return OMX_VIDEO_CodingAVC;
} else if (mInfo->mMimeType.EqualsLiteral("video/mp4v-es") ||
mInfo->mMimeType.EqualsLiteral("video/mp4")) {
return OMX_VIDEO_CodingMPEG4;
} else if (mInfo->mMimeType.EqualsLiteral("video/3gpp")) {
return OMX_VIDEO_CodingH263;
} else if (mInfo->mMimeType.EqualsLiteral("video/webm; codecs=vp8")) {
return static_cast<OMX_VIDEO_CODINGTYPE>(OMX_VIDEO_CodingVP8);
} else {
MOZ_ASSERT_UNREACHABLE("Unsupported compression format");
return OMX_VIDEO_CodingUnused;
}
}
// Implementations for different platforms will be defined in their own files.
#ifdef OMX_PLATFORM_GONK

View File

@ -65,6 +65,19 @@ public:
virtual ~OmxPlatformLayer() {}
// For decoders, input port index is start port number and output port is next.
// See OpenMAX IL spec v1.1.2 section 8.6.1 & 8.8.1.
OMX_U32 InputPortIndex() { return mStartPortNumber; }
OMX_U32 OutputPortIndex() { return mStartPortNumber + 1; }
void GetPortIndices(nsTArray<uint32_t>& aPortIndex) {
aPortIndex.AppendElement(InputPortIndex());
aPortIndex.AppendElement(OutputPortIndex());
}
virtual OMX_VIDEO_CODINGTYPE CompressionFormat();
// Check if the platform implementation supports given MIME type.
static bool SupportsMimeType(const nsACString& aMimeType);
@ -75,10 +88,11 @@ public:
layers::ImageContainer* aImageContainer);
protected:
OmxPlatformLayer() : mInfo(nullptr) {}
OmxPlatformLayer() : mInfo(nullptr), mStartPortNumber(0) {}
// The pointee is held by |OmxDataDecoder::mTrackInfo| and will outlive this pointer.
const TrackInfo* mInfo;
OMX_U32 mStartPortNumber;
};
}

View File

@ -357,6 +357,18 @@ OmxPromiseLayer::SetParameter(OMX_INDEXTYPE aParamIndex,
aComponentParameterSize);
}
OMX_U32
OmxPromiseLayer::InputPortIndex()
{
return mPlatformLayer->InputPortIndex();
}
OMX_U32
OmxPromiseLayer::OutputPortIndex()
{
return mPlatformLayer->OutputPortIndex();
}
nsresult
OmxPromiseLayer::Shutdown()
{

View File

@ -110,6 +110,10 @@ public:
OMX_PTR aComponentParameterStructure,
OMX_U32 aComponentParameterSize);
OMX_U32 InputPortIndex();
OMX_U32 OutputPortIndex();
nsresult Shutdown();
// BufferData maintains the status of OMX buffer (OMX_BUFFERHEADERTYPE).

View File

@ -141,6 +141,8 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video suppo
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_promiseSendOnly.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_scaleResolution.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18') # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_simulcastOffer.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version # b2g(Bug 960442, video support for WebRTC is disabled on b2g), no simulcast support on android
#[test_peerConnection_relayOnly.html]

View File

@ -10,6 +10,13 @@
title: "getUserMedia Basic Screenshare Test",
bug: "1211656"
});
var mustFailWith = (msg, reason, f) =>
f().then(() => ok(false, msg + " must fail"),
e => is(e.name, reason, msg + " must fail: " + e.message));
var pushPrefs = (...p) => new Promise(r => SpecialPowers.pushPrefEnv({set: p}, r));
/**
* Run a test to verify that we can complete a start and stop media playback
* cycle for a screenshare LocalMediaStream on a video HTMLMediaElement.
@ -55,10 +62,20 @@
}
}
];
return getUserMedia(constraints).then(stream => {
return Promise.resolve()
.then(() => pushPrefs(["media.getusermedia.screensharing.allowed_domains",
"mozilla.github.io,*.bugzilla.mozilla.org"]))
.then(() => mustFailWith("Screensharing if absent in allowed_domains",
"SecurityError",
() => navigator.mediaDevices.getUserMedia({
video: videoConstraints[0], fake: false
})))
.then(() => pushPrefs(["media.getusermedia.screensharing.allowed_domains",
"mozilla.github.io,mochi.test,*.bugzilla.mozilla.org"]))
.then(() => getUserMedia(constraints).then(stream => {
var playback = new LocalMediaStreamPlayback(testVideo, stream);
return playback.playMediaWithDeprecatedStreamStop(false);
})
}))
.then(() => getUserMedia({video: videoConstraints[0], fake: false}))
.then(stream => {
var playback = new LocalMediaStreamPlayback(testVideo, stream);

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