Merge mozilla-central to inbound

This commit is contained in:
arthur.iakab 2018-08-07 12:41:15 +03:00
Родитель 768063d35d d39e02bf00
Коммит 2d528aa145
78 изменённых файлов: 1491 добавлений и 932 удалений

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

@ -244,13 +244,11 @@ nsAccUtils::GetSelectableContainer(Accessible* aAccessible, uint64_t aState)
}
bool
nsAccUtils::IsARIASelected(Accessible* aAccessible)
nsAccUtils::IsDOMAttrTrue(const Accessible* aAccessible, nsAtom* aAttr)
{
if (!aAccessible->GetContent()->IsElement())
return false;
return aAccessible->GetContent()->AsElement()->
AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_selected,
nsGkAtoms::_true, eCaseMatters);
dom::Element* el = aAccessible->Elm();
return el && el->AttrValueIs(kNameSpaceID_None, aAttr, nsGkAtoms::_true,
eCaseMatters);
}
Accessible*

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

@ -137,11 +137,27 @@ public:
static Accessible* TableFor(Accessible* aRow);
/**
* Return true if the DOM node of a given accessible has a given attribute
* with a value of "true".
*/
static bool IsDOMAttrTrue(const Accessible* aAccessible, nsAtom* aAttr);
/**
* Return true if the DOM node of given accessible has aria-selected="true"
* attribute.
*/
static bool IsARIASelected(Accessible* aAccessible);
static inline bool IsARIASelected(const Accessible* aAccessible) {
return IsDOMAttrTrue(aAccessible, nsGkAtoms::aria_selected);
}
/**
* Return true if the DOM node of given accessible has
* aria-multiselectable="true" attribute.
*/
static inline bool IsARIAMultiSelectable(const Accessible* aAccessible) {
return IsDOMAttrTrue(aAccessible, nsGkAtoms::aria_multiselectable);
}
/**
* Converts the given coordinates to coordinates relative screen.

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

@ -8,4 +8,5 @@ support-files =
[test_menu.xul]
[test_menulist.xul]
[test_select.html]
[test_tabs.xul]
[test_tree.xul]

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

@ -0,0 +1,94 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="XUL tabs selectable tests">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="../common.js" />
<script type="application/javascript"
src="../role.js" />
<script type="application/javascript"
src="../states.js" />
<script type="application/javascript"
src="../selectable.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
function doTest()
{
var id = "tabs_single";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for tabs_single");
var select = getAccessible(id, [nsIAccessibleSelectable]);
testSelectableSelection(select, ["tab_single1"]);
select.unselectAll();
select.addItemToSelection(1); // tab_single2
testSelectableSelection(select, ["tab_single2"], "select tab_single2: ");
id = "tabs_multi";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for tabs_multi");
select = getAccessible(id, [nsIAccessibleSelectable]);
// Make sure both XUL selection and ARIA selection are included.
testSelectableSelection(select, ["tab_multi_xul1", "tab_multi_aria"]);
select.unselectAll();
select.addItemToSelection(2); // tab_multi_xul2
// We can only affect XUL selection, so ARIA selection won't change.
testSelectableSelection(select, ["tab_multi_aria", "tab_multi_xul2"],
"select tab_multi_xul2: ");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1480058"
title="XUL tabs don't support ARIA selection">
Mozilla Bug 1480058
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<tabbox>
<tabs id="tabs_single">
<tab id="tab_single1" label="tab1" selected="true"/>
<tab id="tab_single2" label="tab2"/>
</tabs>
</tabbox>
<tabbox>
<tabs id="tabs_multi" aria-multiselectable="true">
<tab id="tab_multi_xul1" label="tab1" selected="true"/>
<tab id="tab_multi_aria" label="tab2" aria-selected="true"/>
<tab id="tab_multi_xul2" label="tab3"/>
</tabs>
</tabbox>
</vbox>
</hbox>
</window>

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

@ -24,6 +24,14 @@
testStates("pressed_button", STATE_PRESSED, 0, STATE_CHECKABLE);
testStates("pressed_menu_button", STATE_PRESSED | STATE_HASPOPUP, 0, STATE_CHECKABLE);
testStates("tabs", STATE_MULTISELECTABLE);
// Make sure XUL selection works, since aria-selected defaults to false.
testStates("tab1", STATE_SELECTED);
// aria-selected="true".
testStates("tab2", STATE_SELECTED);
// Neither.
testStates("tab3", 0, 0, STATE_SELECTED);
SimpleTest.finish()
}
@ -53,6 +61,14 @@
<menuitem label="I am a menu item" />
</menupopup>
</button>
<tabbox>
<tabs id="tabs" aria-multiselectable="true">
<tab id="tab1" label="tab1" selected="true"/>
<tab id="tab2" label="tab2" aria-selected="true"/>
<tab id="tab3" label="tab3"/>
</tabs>
</tabbox>
</vbox>
</hbox>

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

@ -5,6 +5,7 @@
#include "XULTabAccessible.h"
#include "ARIAMap.h"
#include "nsAccUtils.h"
#include "Relation.h"
#include "Role.h"
@ -123,6 +124,17 @@ XULTabAccessible::RelationByType(RelationType aType) const
return rel;
}
void
XULTabAccessible::ApplyARIAState(uint64_t* aState) const
{
HyperTextAccessibleWrap::ApplyARIAState(aState);
// XUL tab has an implicit ARIA role of tab, so support aria-selected.
// Don't use aria::MapToState because that will set the SELECTABLE state
// even if the tab is disabled.
if (nsAccUtils::IsARIASelected(this)) {
*aState |= states::SELECTED;
}
}
////////////////////////////////////////////////////////////////////////////////
// XULTabsAccessible
@ -159,6 +171,66 @@ XULTabsAccessible::NativeName(nsString& aName) const
return eNameOK;
}
void
XULTabsAccessible::ApplyARIAState(uint64_t* aState) const
{
XULSelectControlAccessible::ApplyARIAState(aState);
// XUL tabs has an implicit ARIA role of tablist, so support
// aria-multiselectable.
MOZ_ASSERT(Elm());
aria::MapToState(aria::eARIAMultiSelectable, Elm(), aState);
}
// XUL tabs is a single selection control and doesn't allow ARIA selection.
// However, if aria-multiselectable is used, it becomes a multiselectable
// control, where both native and ARIA markup are used to set selection.
// Therefore, if aria-multiselectable is set, use the base implementation of
// the selection retrieval methods in order to support ARIA selection.
// We don't bother overriding the selection setting methods because
// current front-end code using XUL tabs doesn't support setting of
// aria-selected by the a11y engine and we still want to be able to set the
// primary selected item according to XUL.
void
XULTabsAccessible::SelectedItems(nsTArray<Accessible*>* aItems)
{
if (nsAccUtils::IsARIAMultiSelectable(this)) {
AccessibleWrap::SelectedItems(aItems);
} else {
XULSelectControlAccessible::SelectedItems(aItems);
}
}
Accessible*
XULTabsAccessible::GetSelectedItem(uint32_t aIndex)
{
if (nsAccUtils::IsARIAMultiSelectable(this)) {
return AccessibleWrap::GetSelectedItem(aIndex);
}
return XULSelectControlAccessible::GetSelectedItem(aIndex);
}
uint32_t
XULTabsAccessible::SelectedItemCount()
{
if (nsAccUtils::IsARIAMultiSelectable(this)) {
return AccessibleWrap::SelectedItemCount();
}
return XULSelectControlAccessible::SelectedItemCount();
}
bool
XULTabsAccessible::IsItemSelected(uint32_t aIndex)
{
if (nsAccUtils::IsARIAMultiSelectable(this)) {
return AccessibleWrap::IsItemSelected(aIndex);
}
return XULSelectControlAccessible::IsItemSelected(aIndex);
}
////////////////////////////////////////////////////////////////////////////////
// XULTabpanelsAccessible

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

@ -29,6 +29,7 @@ public:
virtual uint64_t NativeState() const override;
virtual uint64_t NativeInteractiveState() const override;
virtual Relation RelationByType(RelationType aType) const override;
virtual void ApplyARIAState(uint64_t* aState) const override;
// ActionAccessible
virtual uint8_t ActionCount() const override;
@ -48,10 +49,17 @@ public:
// Accessible
virtual void Value(nsString& aValue) const override;
virtual a11y::role NativeRole() const override;
virtual void ApplyARIAState(uint64_t* aState) const override;
// ActionAccessible
virtual uint8_t ActionCount() const override;
// SelectAccessible
virtual void SelectedItems(nsTArray<Accessible*>* aItems) override;
virtual uint32_t SelectedItemCount() override;
virtual Accessible* GetSelectedItem(uint32_t aIndex) override;
virtual bool IsItemSelected(uint32_t aIndex) override;
protected:
// Accessible
virtual ENameValueFlag NativeName(nsString& aName) const override;

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

@ -111,7 +111,6 @@ skip-if = (verify && (os == 'linux' || os == 'mac'))
[browser_ext_menus_events.js]
[browser_ext_menus_refresh.js]
[browser_ext_omnibox.js]
skip-if = (debug && (os == 'linux' || os == 'mac')) || (verify && (os == 'linux' || os == 'mac')) # Bug 1416103 (was bug 1417052)
[browser_ext_openPanel.js]
skip-if = (verify && !debug && (os == 'linux' || os == 'mac'))
[browser_ext_optionsPage_browser_style.js]

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

@ -67,27 +67,18 @@ class TabsListBase {
for (let tab of this.gBrowser.tabs) {
if (this.filterFn(tab)) {
let row = this._createRow(tab);
row.tab = tab;
row.addEventListener("command", this);
this.tabToElement.set(tab, row);
if (this.className) {
row.classList.add(this.className);
}
fragment.appendChild(row);
fragment.appendChild(this._createRow(tab));
}
}
if (this.insertBefore) {
this.insertBefore.parentNode.insertBefore(fragment, this.insertBefore);
} else {
this.containerNode.appendChild(fragment);
}
this._addElement(fragment);
this._setupListeners();
}
_addElement(elementOrFragment) {
this.containerNode.insertBefore(elementOrFragment, this.insertBefore);
}
/*
* Remove the menuitems from the DOM, cleanup internal state and listeners.
*/
@ -115,11 +106,32 @@ class TabsListBase {
let item = this.tabToElement.get(tab);
if (item) {
if (!this.filterFn(tab)) {
// If the tab is no longer in this set of tabs, hide the item.
// The tab no longer matches our criteria, remove it.
this._removeItem(item, tab);
} else {
this._setRowAttributes(item, tab);
}
} else if (this.filterFn(tab)) {
// The tab now matches our criteria, add a row for it.
this._addTab(tab);
}
}
_addTab(newTab) {
let newRow = this._createRow(newTab);
let nextTab = newTab.nextSibling;
while (nextTab && !this.filterFn(nextTab)) {
nextTab = nextTab.nextSibling;
}
if (nextTab) {
// If we found a tab after this one in the list, insert the new row before it.
let nextRow = this.tabToElement.get(nextTab);
nextRow.parentNode.insertBefore(newRow, nextRow);
} else {
// If there's no next tab then insert it as usual.
this._addElement(newRow);
}
}
@ -206,6 +218,12 @@ class TabsPanel extends TabsListBase {
let {doc} = this;
let row = doc.createElementNS(NSXUL, "toolbaritem");
row.setAttribute("class", "all-tabs-item");
if (this.className) {
row.classList.add(this.className);
}
row.tab = tab;
row.addEventListener("command", this);
this.tabToElement.set(tab, row);
let button = doc.createElementNS(NSXUL, "toolbarbutton");
button.setAttribute("class", "all-tabs-button subviewbutton subviewbutton-iconic");

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

@ -804,6 +804,10 @@
box-shadow: inset -4px 0 var(--blue-40);
}
.all-tabs-button {
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
}
.all-tabs-secondary-button > label {
display: none;
margin: 0 5.5px;

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

@ -2,20 +2,26 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@import "resource://devtools/client/themes/variables.css";
@import "chrome://global/skin/in-content/common.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/App.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/ConnectPage.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimePage.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/Sidebar.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/SidebarItem.css";
:root {
/* Import css variables from common.css */
--text-color: var(--in-content-page-color);
}
html, body {
margin: 0;
padding: 0;
color: var(--text-color);
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
}

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

@ -5,6 +5,7 @@
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css" type="text/css"/>
<link rel="stylesheet" href="chrome://devtools/content/aboutdebugging-new/aboutdebugging.css"/>
<script src="chrome://devtools/content/aboutdebugging-new/aboutdebugging.js"></script>
</head>

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

@ -3,10 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* The current layout of the about:debugging is
* The current layout of about:debugging is
*
* +-------------+-------------------------------+
* | Sidebar | RuntimePage |
* | Sidebar | Page (Runtime or Connect) |
* | (240px) | |
* | | |
* +-------------+-------------------------------+
@ -14,8 +14,13 @@
.app {
display: grid;
font-size: 15px;
grid-column-gap: 40px;
grid-template-columns: 240px auto;
height: 100vh;
overflow: hidden;
width: 100vw;
}
.page {
padding-block-start: 60px;
}

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

@ -11,6 +11,7 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { PAGES } = require("../constants");
const ConnectPage = createFactory(require("./ConnectPage"));
const RuntimePage = createFactory(require("./RuntimePage"));
const Sidebar = createFactory(require("./Sidebar"));
@ -29,6 +30,8 @@ class App extends PureComponent {
switch (this.props.selectedPage) {
case PAGES.THIS_FIREFOX:
return RuntimePage();
case PAGES.CONNECT:
return ConnectPage();
default:
// Invalid page, blank.
return null;

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

@ -0,0 +1,24 @@
/* 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/. */
.connect-page__steps {
list-style-type: decimal;
margin-inline-start: 40px;
line-height: 1.5em;
margin-block-end: 20px;
}
.connect-page__step {
padding-inline-start: 20px;
}
.connect-page__section__title {
display: flex;
}
.connect-page__section__icon {
width: 32px;
height: 32px;
margin-inline-end: 5px;
}

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

@ -0,0 +1,92 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const USB_ICON_SRC = "chrome://devtools/skin/images/aboutdebugging-connect-icon.svg";
const WIFI_ICON_SRC = "chrome://devtools/skin/images/aboutdebugging-connect-icon.svg";
class RuntimePage extends PureComponent {
renderSteps(steps) {
return dom.ul(
{
className: "connect-page__steps"
},
steps.map(step => dom.li(
{
className: "connect-page__step"
},
step)
)
);
}
renderWifi() {
return dom.section(
{},
dom.h2(
{
className: "connect-page__section__title"
},
dom.img(
{
className: "connect-page__section__icon",
src: WIFI_ICON_SRC
}
),
"Via WiFi (Recommended)"
),
this.renderSteps([
"Ensure that your browser and device are on the same network",
"Open Firefox for Android",
"Go to Options -> Settings -> Advanced",
"Enable Remote Debugging via WiFi in the Developer Tools section",
])
);
}
renderUsb() {
return dom.section(
{},
dom.h2(
{
className: "connect-page__section__title"
},
dom.img(
{
className: "connect-page__section__icon",
src: USB_ICON_SRC
}
),
"Via USB"
),
this.renderSteps([
"Enable Developer menu on your Android device",
"Enable USB Debugging on the Android Developer Menu",
"Connect the USB Device to your computer",
])
);
}
render() {
return dom.article(
{
className: "page connect-page",
},
dom.h1(
{
className: "connect-page__title"
},
"Connect a Device"
),
this.renderWifi(),
this.renderUsb(),
);
}
}
module.exports = RuntimePage;

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

@ -1,7 +0,0 @@
/* 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/. */
.runtime-page {
padding-block-start: 60px;
}

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

@ -15,7 +15,7 @@ class RuntimePage extends PureComponent {
render() {
return dom.article(
{
className: "runtime-page",
className: "page",
},
RuntimeInfo({
icon: "chrome://branding/content/icon64.png",

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

@ -3,20 +3,32 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.sidebar-item {
--sidebar-item-color: var(--grey-50);
--sidebar-item-selected-color: var(--blue-55);
/* Import css variables from common.css */
--sidebar-text-color: var(--in-content-category-text);
--sidebar-selected-color: var(--in-content-category-text-selected);
--sidebar-background-hover: var(--in-content-category-background-hover);
}
.sidebar-item {
color: var(--sidebar-item-color);
align-items: center;
border-radius: 2px;
color: var(--sidebar-text-color);
display: flex;
font-size: 20px;
font-size: 16px;
height: 48px;
margin-inline-start: 24px;
padding-inline-end: 10px;
padding-inline-start: 10px;
transition: background-color 150ms;
-moz-user-select: none;
}
.sidebar-item:hover {
background-color: var(--sidebar-background-hover);
}
.sidebar-item__icon {
fill: var(--sidebar-item-color);
fill: currentColor;
height: 24px;
margin-inline-end: 9px;
width: 24px;
@ -24,9 +36,5 @@
}
.sidebar-item--selected {
color: var(--sidebar-item-selected-color);
}
.sidebar-item__icon--selected {
fill: var(--sidebar-item-selected-color);
color: var(--sidebar-selected-color);
}

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

@ -5,9 +5,10 @@
DevToolsModules(
'App.css',
'App.js',
'ConnectPage.css',
'ConnectPage.js',
'RuntimeInfo.css',
'RuntimeInfo.js',
'RuntimePage.css',
'RuntimePage.js',
'Sidebar.css',
'Sidebar.js',

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

@ -1,6 +1,6 @@
<!doctype html><html><head><meta charset="UTF-8"></head><body>
<object>
<embed src="doc_inspector_menu.html" type="application/html"
<embed src="doc_inspector_menu.html" type="text/html"
width="422" height="258"></embed>
</object>
</body></html>

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

@ -170,7 +170,6 @@ skip-if = verify
[browser_num-l10n.js]
[browser_options-view-01.js]
[browser_outputparser.js]
skip-if = e10s # Test intermittently fails with e10s. Bug 1124162.
[browser_poller.js]
[browser_prefs-01.js]
[browser_prefs-02.js]

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

@ -283,7 +283,7 @@ function testParseFilter(doc, parser) {
}
function testParseAngle(doc, parser) {
let frag = parser.parseCssProperty("image-orientation", "90deg", {
let frag = parser.parseCssProperty("rotate", "90deg", {
angleSwatchClass: "test-angleswatch"
});

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

@ -3240,7 +3240,7 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugin
}
NS_IMETHODIMP
nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
nsDOMWindowUtils::SetVisualViewportSize(float aWidth, float aHeight)
{
if (!(aWidth >= 0.0 && aHeight >= 0.0)) {
return NS_ERROR_ILLEGAL_VALUE;
@ -3251,7 +3251,7 @@ nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aH
return NS_ERROR_FAILURE;
}
nsLayoutUtils::SetScrollPositionClampingScrollPortSize(presShell, CSSSize(aWidth, aHeight));
nsLayoutUtils::SetVisualViewportSize(presShell, CSSSize(aWidth, aHeight));
return NS_OK;
}

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

@ -3137,9 +3137,9 @@ nsGlobalWindowOuter::GetInnerSize(CSSIntSize& aSize)
* be the visual viewport, but we fall back to the CSS viewport
* if it is not set.
*/
if (presShell->IsScrollPositionClampingScrollPortSizeSet()) {
if (presShell->IsVisualViewportSizeSet()) {
aSize = CSSIntRect::FromAppUnitsRounded(
presShell->GetScrollPositionClampingScrollPortSize());
presShell->GetVisualViewportSize());
} else {
RefPtr<nsViewManager> viewManager = presShell->GetViewManager();
if (viewManager) {

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

@ -1810,12 +1810,15 @@ nsObjectLoadingContent::UpdateObjectParameters()
IsPluginType(newMime_Type)) {
newType = newMime_Type;
LOG(("OBJLC [%p]: Plugin type with no URI, skipping channel load", this));
} else if (newURI) {
} else if (newURI && (mOriginalContentType.IsEmpty() || newMime_Type != eType_Null)) {
// We could potentially load this if we opened a channel on mURI, indicate
// This by leaving type as loading
// this by leaving type as loading.
//
// If a MIME type was requested in the tag, but we have decided to set load
// type to null, ignore (otherwise we'll default to document type loading).
newType = eType_Loading;
} else {
// Unloadable - no URI, and no plugin type. Non-plugin types (images,
// Unloadable - no URI, and no plugin/MIME type. Non-plugin types (images,
// documents) always load with a channel.
newType = eType_Null;
}

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

@ -23,9 +23,9 @@ function run()
var newHeight = oldHeight / 2;
var utils = SpecialPowers.getDOMWindowUtils(window);
utils.setScrollPositionClampingScrollPortSize(newWidth, newHeight);
is(window.innerWidth, newWidth, "innerWidth not updated to scroll port width");
is(window.innerHeight, newHeight, "innerHeight not updated to scroll port height");
utils.setVisualViewportSize(newWidth, newHeight);
is(window.innerWidth, newWidth, "innerWidth not updated to viewport width");
is(window.innerHeight, newHeight, "innerHeight not updated to viewport height");
var innerWidthGetter = Object.getOwnPropertyDescriptor(window, "innerWidth").get;
var innerHeightGetter = Object.getOwnPropertyDescriptor(window, "innerHeight").get;

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

@ -2753,7 +2753,7 @@ EventStateManager::GetScrollAmount(nsPresContext* aPresContext,
aScrollableFrame->GetLineScrollAmount();
}
// If there is no scrollable frame and page scrolling, use view port size.
// If there is no scrollable frame and page scrolling, use viewport size.
if (isPage) {
return aPresContext->GetVisibleArea().Size();
}

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

@ -1591,12 +1591,12 @@ interface nsIDOMWindowUtils : nsISupports {
readonly attribute jsval plugins;
/**
* Set the scrollport size for the purposes of clamping scroll positions for
* Set the viewport size for the purposes of clamping scroll positions for
* the root scroll frame of this document to be (aWidth,aHeight) in CSS pixels.
*
* The caller of this method must have chrome privileges.
*/
void setScrollPositionClampingScrollPortSize(in float aWidth, in float aHeight);
void setVisualViewportSize(in float aWidth, in float aHeight);
/**
* These are used to control whether dialogs (alert, prompt, confirm) are

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

@ -140,7 +140,9 @@ IsMediaElementAllowedToPlay(const HTMLMediaElement& aElement)
return true;
}
if (aElement.OwnerDoc()->MediaDocumentKind() == nsIDocument::MediaDocumentKind::Video) {
nsIDocument* topDocument = ApproverDocOf(*aElement.OwnerDoc());
if (topDocument &&
topDocument->MediaDocumentKind() == nsIDocument::MediaDocumentKind::Video) {
AUTOPLAY_LOG("Allow video document %p to autoplay\n", &aElement);
return true;
}

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

@ -1419,8 +1419,12 @@ class RTCPeerConnection {
}
this._closed = true;
this.changeIceConnectionState("closed");
this._localIdp.close();
this._remoteIdp.close();
if (this._localIdp) {
this._localIdp.close();
}
if (this._remoteIdp) {
this._remoteIdp.close();
}
this._impl.close();
this._suppressEvents = true;
delete this._pc;

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

@ -280,9 +280,9 @@ struct ParamTraits<mozilla::dom::RTCIceComponentStats>
}
};
static void WriteRTCRTPStreamStats(
static void WriteRTCRtpStreamStats(
Message* aMsg,
const mozilla::dom::RTCRTPStreamStats& aParam)
const mozilla::dom::RTCRtpStreamStats& aParam)
{
WriteParam(aMsg, aParam.mBitrateMean);
WriteParam(aMsg, aParam.mBitrateStdDev);
@ -297,9 +297,9 @@ static void WriteRTCRTPStreamStats(
WriteParam(aMsg, aParam.mTransportId);
}
static bool ReadRTCRTPStreamStats(
static bool ReadRTCRtpStreamStats(
const Message* aMsg, PickleIterator* aIter,
mozilla::dom::RTCRTPStreamStats* aResult)
mozilla::dom::RTCRtpStreamStats* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mBitrateMean)) ||
!ReadParam(aMsg, aIter, &(aResult->mBitrateStdDev)) ||
@ -334,7 +334,7 @@ struct ParamTraits<mozilla::dom::RTCInboundRTPStreamStats>
WriteParam(aMsg, aParam.mRoundTripTime);
WriteParam(aMsg, aParam.mPacketsLost);
WriteParam(aMsg, aParam.mPacketsReceived);
WriteRTCRTPStreamStats(aMsg, aParam);
WriteRTCRtpStreamStats(aMsg, aParam);
WriteRTCStats(aMsg, aParam);
}
@ -349,7 +349,7 @@ struct ParamTraits<mozilla::dom::RTCInboundRTPStreamStats>
!ReadParam(aMsg, aIter, &(aResult->mRoundTripTime)) ||
!ReadParam(aMsg, aIter, &(aResult->mPacketsLost)) ||
!ReadParam(aMsg, aIter, &(aResult->mPacketsReceived)) ||
!ReadRTCRTPStreamStats(aMsg, aIter, aResult) ||
!ReadRTCRtpStreamStats(aMsg, aIter, aResult) ||
!ReadRTCStats(aMsg, aIter, aResult)) {
return false;
}
@ -373,7 +373,7 @@ struct ParamTraits<mozilla::dom::RTCOutboundRTPStreamStats>
WriteParam(aMsg, aParam.mFirCount);
WriteParam(aMsg, aParam.mNackCount);
WriteParam(aMsg, aParam.mPliCount);
WriteRTCRTPStreamStats(aMsg, aParam);
WriteRTCRtpStreamStats(aMsg, aParam);
WriteRTCStats(aMsg, aParam);
}
@ -387,7 +387,7 @@ struct ParamTraits<mozilla::dom::RTCOutboundRTPStreamStats>
!ReadParam(aMsg, aIter, &(aResult->mFirCount)) ||
!ReadParam(aMsg, aIter, &(aResult->mNackCount)) ||
!ReadParam(aMsg, aIter, &(aResult->mPliCount)) ||
!ReadRTCRTPStreamStats(aMsg, aIter, aResult) ||
!ReadRTCRtpStreamStats(aMsg, aIter, aResult) ||
!ReadRTCStats(aMsg, aIter, aResult)) {
return false;
}

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

@ -9,7 +9,6 @@ with Files("**"):
BUG_COMPONENT = ("Core", "DOM")
XPIDL_SOURCES += [
'nsCWebBrowserPersist.idl',
'nsIWebBrowserPersist.idl',
'nsIWebBrowserPersistDocument.idl',
]

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

@ -1,15 +0,0 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsIWebBrowserPersist.idl"
%{ C++
// {7E677795-C582-4cd1-9E8D-8271B3474D2A}
#define NS_WEBBROWSERPERSIST_CID \
{ 0x7e677795, 0xc582, 0x4cd1, { 0x9e, 0x8d, 0x82, 0x71, 0xb3, 0x47, 0x4d, 0x2a } }
#define NS_WEBBROWSERPERSIST_CONTRACTID \
"@mozilla.org/embedding/browser/nsWebBrowserPersist;1"
%}

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

@ -261,3 +261,16 @@ interface nsIWebBrowserPersist : nsICancelable
*/
void cancelSave();
};
/**
* We don't export nsWebBrowserPersist.h as a public header, so we need a place
* to put the CID/ContractID. All places uses the WebBrowserPersist include
* nsIWebBrowserPersist.h, so we define our contract IDs here for now.
*/
%{ C++
// {7E677795-C582-4cd1-9E8D-8271B3474D2A}
#define NS_WEBBROWSERPERSIST_CID \
{ 0x7e677795, 0xc582, 0x4cd1, { 0x9e, 0x8d, 0x82, 0x71, 0xb3, 0x47, 0x4d, 0x2a } }
#define NS_WEBBROWSERPERSIST_CONTRACTID \
"@mozilla.org/embedding/browser/nsWebBrowserPersist;1"
%}

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

@ -21,6 +21,7 @@
#include "nsIProgressEventSink.h"
#include "nsIFile.h"
#include "nsIWebProgressListener2.h"
#include "nsIWebBrowserPersist.h"
#include "nsIWebBrowserPersistDocument.h"
#include "mozilla/UniquePtr.h"
@ -28,8 +29,6 @@
#include "nsHashKeys.h"
#include "nsTArray.h"
#include "nsCWebBrowserPersist.h"
class nsIStorageStream;
class nsIWebBrowserPersistDocument;

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

@ -26,7 +26,7 @@ dictionary RTCStats {
DOMString id;
};
dictionary RTCRTPStreamStats : RTCStats {
dictionary RTCRtpStreamStats : RTCStats {
unsigned long ssrc;
DOMString mediaType;
DOMString remoteId;
@ -48,7 +48,7 @@ dictionary RTCRTPStreamStats : RTCStats {
unsigned long nackCount;
};
dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
dictionary RTCInboundRTPStreamStats : RTCRtpStreamStats {
unsigned long packetsReceived;
unsigned long long bytesReceived;
double jitter;
@ -62,7 +62,7 @@ dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
unsigned long framesDecoded;
};
dictionary RTCOutboundRTPStreamStats : RTCRTPStreamStats {
dictionary RTCOutboundRTPStreamStats : RTCRtpStreamStats {
unsigned long packetsSent;
unsigned long long bytesSent;
double targetBitrate; // config encoder bitrate target of this SSRC in bits/s

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

@ -16,7 +16,7 @@
*/
/* fluent-dom@aa95b1f (July 10, 2018) */
/* fluent-dom@cab517f (July 31, 2018) */
const { Localization } =
ChromeUtils.import("resource://gre/modules/Localization.jsm", {});
@ -60,10 +60,10 @@ const LOCALIZABLE_ATTRIBUTES = {
th: ["abbr"]
},
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul": {
description: ["value"],
global: [
"accesskey", "aria-label", "aria-valuetext", "aria-moz-hint", "label"
],
description: ["value"],
key: ["key", "keycode"],
label: ["value"],
textbox: ["placeholder"],
@ -523,7 +523,7 @@ class DOMLocalization extends Localization {
if (this.windowElement) {
if (this.windowElement !== newRoot.ownerGlobal) {
throw new Error(`Cannot connect a root:
DOMLocalization already has a root from a different window`);
DOMLocalization already has a root from a different window.`);
}
} else {
this.windowElement = newRoot.ownerGlobal;

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

@ -16,7 +16,7 @@
*/
/* fluent-dom@aa95b1f (July 10, 2018) */
/* fluent-dom@cab517f (July 31, 2018) */
/* eslint no-console: ["error", { allow: ["warn", "error"] }] */
/* global console */
@ -25,13 +25,25 @@ const { L10nRegistry } = ChromeUtils.import("resource://gre/modules/L10nRegistry
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
const { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
/*
* CachedAsyncIterable caches the elements yielded by an iterable.
*
* It can be used to iterate over an iterable many times without depleting the
* iterable.
*/
class CachedAsyncIterable {
class CachedIterable extends Array {
/**
* Create a `CachedIterable` instance from an iterable or, if another
* instance of `CachedIterable` is passed, return it without any
* modifications.
*
* @param {Iterable} iterable
* @returns {CachedIterable}
*/
static from(iterable) {
if (iterable instanceof this) {
return iterable;
}
return new this(iterable);
}
}
class CachedAsyncIterable extends CachedIterable {
/**
* Create an `CachedAsyncIterable` instance.
*
@ -39,6 +51,8 @@ class CachedAsyncIterable {
* @returns {CachedAsyncIterable}
*/
constructor(iterable) {
super();
if (Symbol.asyncIterator in Object(iterable)) {
this.iterator = iterable[Symbol.asyncIterator]();
} else if (Symbol.iterator in Object(iterable)) {
@ -46,20 +60,46 @@ class CachedAsyncIterable {
} else {
throw new TypeError("Argument must implement the iteration protocol.");
}
this.seen = [];
}
/**
* Synchronous iterator over the cached elements.
*
* Return a generator object implementing the iterator protocol over the
* cached elements of the original (async or sync) iterable.
*/
[Symbol.iterator]() {
const cached = this;
let cur = 0;
return {
next() {
if (cached.length === cur) {
return {value: undefined, done: true};
}
return cached[cur++];
}
};
}
/**
* Asynchronous iterator caching the yielded elements.
*
* Elements yielded by the original iterable will be cached and available
* synchronously. Returns an async generator object implementing the
* iterator protocol over the elements of the original (async or sync)
* iterable.
*/
[Symbol.asyncIterator]() {
const { seen, iterator } = this;
const cached = this;
let cur = 0;
return {
async next() {
if (seen.length <= cur) {
seen.push(await iterator.next());
if (cached.length <= cur) {
cached.push(await cached.iterator.next());
}
return seen[cur++];
return cached[cur++];
}
};
}
@ -71,13 +111,17 @@ class CachedAsyncIterable {
* @param {number} count - number of elements to consume
*/
async touchNext(count = 1) {
const { seen, iterator } = this;
let idx = 0;
while (idx++ < count) {
if (seen.length === 0 || seen[seen.length - 1].done === false) {
seen.push(await iterator.next());
const last = this[this.length - 1];
if (last && last.done) {
break;
}
this.push(await this.iterator.next());
}
// Return the last cached {value, done} object to allow the calling
// code to decide if it needs to call touchNext again.
return this[this.length - 1];
}
}
@ -112,8 +156,8 @@ class Localization {
constructor(resourceIds = [], generateMessages = defaultGenerateMessages) {
this.resourceIds = resourceIds;
this.generateMessages = generateMessages;
this.ctxs =
new CachedAsyncIterable(this.generateMessages(this.resourceIds));
this.ctxs = CachedAsyncIterable.from(
this.generateMessages(this.resourceIds));
}
addResourceIds(resourceIds) {
@ -276,8 +320,8 @@ class Localization {
* that language negotiation or available resources changed.
*/
onChange() {
this.ctxs =
new CachedAsyncIterable(this.generateMessages(this.resourceIds));
this.ctxs = CachedAsyncIterable.from(
this.generateMessages(this.resourceIds));
this.ctxs.touchNext(2);
}
}

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

@ -16,7 +16,7 @@
*/
/* fluent@aa95b1f (July 10, 2018) */
/* fluent@0.7.0 */
/* eslint no-magic-numbers: [0] */
@ -25,6 +25,9 @@ const MAX_PLACEABLES = 100;
const entryIdentifierRe = /-?[a-zA-Z][a-zA-Z0-9_-]*/y;
const identifierRe = /[a-zA-Z][a-zA-Z0-9_-]*/y;
const functionIdentifierRe = /^[A-Z][A-Z_?-]*$/;
const unicodeEscapeRe = /^[a-fA-F0-9]{4}$/;
const trailingWSRe = /[ \t\n\r]+$/;
/**
* The `Parser` class is responsible for parsing FTL resources.
@ -94,46 +97,15 @@ class RuntimeParser {
const ch = this._source[this._index];
// We don't care about comments or sections at runtime
if (ch === "/" ||
(ch === "#" &&
[" ", "#", "\n"].includes(this._source[this._index + 1]))) {
if (ch === "#" &&
[" ", "#", "\n"].includes(this._source[this._index + 1])) {
this.skipComment();
return;
}
if (ch === "[") {
this.skipSection();
return;
}
this.getMessage();
}
/**
* Skip the section entry from the current index.
*
* @private
*/
skipSection() {
this._index += 1;
if (this._source[this._index] !== "[") {
throw this.error('Expected "[[" to open a section');
}
this._index += 1;
this.skipInlineWS();
this.getVariantName();
this.skipInlineWS();
if (this._source[this._index] !== "]" ||
this._source[this._index + 1] !== "]") {
throw this.error('Expected "]]" to close a section');
}
this._index += 2;
}
/**
* Parse the source string from the current index as an FTL message
* and add it to the entries property on the Parser.
@ -147,6 +119,8 @@ class RuntimeParser {
if (this._source[this._index] === "=") {
this._index++;
} else {
throw this.error("Expected \"=\" after the identifier");
}
this.skipInlineWS();
@ -236,7 +210,7 @@ class RuntimeParser {
* Get identifier using the provided regex.
*
* By default this will get identifiers of public messages, attributes and
* external arguments (without the $).
* variables (without the $).
*
* @returns {String}
* @private
@ -311,21 +285,30 @@ class RuntimeParser {
* @private
*/
getString() {
const start = this._index + 1;
let value = "";
this._index++;
while (++this._index < this._length) {
while (this._index < this._length) {
const ch = this._source[this._index];
if (ch === '"') {
this._index++;
break;
}
if (ch === "\n") {
throw this.error("Unterminated string expression");
}
if (ch === "\\") {
value += this.getEscapedCharacter(["{", "\\", "\""]);
} else {
this._index++;
value += ch;
}
}
return this._source.substring(start, this._index++);
return value;
}
/**
@ -349,10 +332,17 @@ class RuntimeParser {
eol = this._length;
}
const firstLineContent = start !== eol ?
this._source.slice(start, eol) : null;
// If there's any text between the = and the EOL, store it for now. The next
// non-empty line will decide what to do with it.
const firstLineContent = start !== eol
// Trim the trailing whitespace in case this is a single-line pattern.
// Multiline patterns are parsed anew by getComplexPattern.
? this._source.slice(start, eol).replace(trailingWSRe, "")
: null;
if (firstLineContent && firstLineContent.includes("{")) {
if (firstLineContent
&& (firstLineContent.includes("{")
|| firstLineContent.includes("\\"))) {
return this.getComplexPattern();
}
@ -439,13 +429,19 @@ class RuntimeParser {
}
ch = this._source[this._index];
continue;
} else if (ch === "\\") {
const ch2 = this._source[this._index + 1];
if (ch2 === '"' || ch2 === "{" || ch2 === "\\") {
ch = ch2;
this._index++;
}
} else if (ch === "{") {
}
if (ch === undefined) {
break;
}
if (ch === "\\") {
buffer += this.getEscapedCharacter();
ch = this._source[this._index];
continue;
}
if (ch === "{") {
// Push the buffer to content array right before placeable
if (buffer.length) {
content.push(buffer);
@ -457,18 +453,13 @@ class RuntimeParser {
buffer = "";
content.push(this.getPlaceable());
this._index++;
ch = this._source[this._index];
ch = this._source[++this._index];
placeables++;
continue;
}
if (ch) {
buffer += ch;
}
this._index++;
ch = this._source[this._index];
buffer += ch;
ch = this._source[++this._index];
}
if (content.length === 0) {
@ -476,13 +467,42 @@ class RuntimeParser {
}
if (buffer.length) {
content.push(buffer);
// Trim trailing whitespace, too.
content.push(buffer.replace(trailingWSRe, ""));
}
return content;
}
/* eslint-enable complexity */
/**
* Parse an escape sequence and return the unescaped character.
*
* @returns {string}
* @private
*/
getEscapedCharacter(specials = ["{", "\\"]) {
this._index++;
const next = this._source[this._index];
if (specials.includes(next)) {
this._index++;
return next;
}
if (next === "u") {
const sequence = this._source.slice(this._index + 1, this._index + 5);
if (unicodeEscapeRe.test(sequence)) {
this._index += 5;
return String.fromCodePoint(parseInt(sequence, 16));
}
throw this.error(`Invalid Unicode escape sequence: \\u${sequence}`);
}
throw this.error(`Unknown escape sequence: \\${next}`);
}
/**
* Parses a single placeable in a Message pattern and returns its
* expression.
@ -519,7 +539,7 @@ class RuntimeParser {
const ch = this._source[this._index];
if (ch === "}") {
if (selector.type === "attr" && selector.id.name.startsWith("-")) {
if (selector.type === "getattr" && selector.id.name.startsWith("-")) {
throw this.error(
"Attributes of private messages cannot be interpolated."
);
@ -536,11 +556,11 @@ class RuntimeParser {
throw this.error("Message references cannot be used as selectors.");
}
if (selector.type === "var") {
if (selector.type === "getvar") {
throw this.error("Variants cannot be used as selectors.");
}
if (selector.type === "attr" && !selector.id.name.startsWith("-")) {
if (selector.type === "getattr" && !selector.id.name.startsWith("-")) {
throw this.error(
"Attributes of public messages cannot be used as selectors."
);
@ -578,6 +598,10 @@ class RuntimeParser {
* @private
*/
getSelectorExpression() {
if (this._source[this._index] === "{") {
return this.getPlaceable();
}
const literal = this.getLiteral();
if (literal.type !== "ref") {
@ -590,7 +614,7 @@ class RuntimeParser {
const name = this.getIdentifier();
this._index++;
return {
type: "attr",
type: "getattr",
id: literal,
name
};
@ -602,7 +626,7 @@ class RuntimeParser {
const key = this.getVariantKey();
this._index++;
return {
type: "var",
type: "getvar",
id: literal,
key
};
@ -640,7 +664,7 @@ class RuntimeParser {
const args = [];
while (this._index < this._length) {
this.skipInlineWS();
this.skipWS();
if (this._source[this._index] === ")") {
return args;
@ -657,7 +681,7 @@ class RuntimeParser {
if (this._source[this._index] === ":") {
this._index++;
this.skipInlineWS();
this.skipWS();
const val = this.getSelectorExpression();
@ -685,7 +709,7 @@ class RuntimeParser {
}
}
this.skipInlineWS();
this.skipWS();
if (this._source[this._index] === ")") {
break;
@ -885,7 +909,7 @@ class RuntimeParser {
if (cc0 === 36) { // $
this._index++;
return {
type: "ext",
type: "var",
name: this.getIdentifier()
};
}
@ -925,12 +949,11 @@ class RuntimeParser {
// to parse them properly and skip their content.
let eol = this._source.indexOf("\n", this._index);
while (eol !== -1 &&
((this._source[eol + 1] === "/" && this._source[eol + 2] === "/") ||
(this._source[eol + 1] === "#" &&
[" ", "#"].includes(this._source[eol + 2])))) {
this._index = eol + 3;
while (eol !== -1
&& this._source[eol + 1] === "#"
&& [" ", "#"].includes(this._source[eol + 2])) {
this._index = eol + 3;
eol = this._source.indexOf("\n", this._index);
if (eol === -1) {
@ -972,7 +995,7 @@ class RuntimeParser {
if ((cc >= 97 && cc <= 122) || // a-z
(cc >= 65 && cc <= 90) || // A-Z
cc === 47 || cc === 91) { // /[
cc === 45) { // -
this._index = start;
return;
}
@ -1169,11 +1192,11 @@ function values(opts) {
* The role of the Fluent resolver is to format a translation object to an
* instance of `FluentType` or an array of instances.
*
* Translations can contain references to other messages or external arguments,
* Translations can contain references to other messages or variables,
* conditional logic in form of select expressions, traits which describe their
* grammatical features, and can use Fluent builtins which make use of the
* `Intl` formatters to format numbers, dates, lists and more into the
* context's language. See the documentation of the Fluent syntax for more
* context's language. See the documentation of the Fluent syntax for more
* information.
*
* In case of errors the resolver will try to salvage as much of the
@ -1436,8 +1459,8 @@ function Type(env, expr) {
return new FluentSymbol(expr.name);
case "num":
return new FluentNumber(expr.val);
case "ext":
return ExternalArgument(env, expr);
case "var":
return VariableReference(env, expr);
case "fun":
return FunctionReference(env, expr);
case "call":
@ -1446,11 +1469,11 @@ function Type(env, expr) {
const message = MessageReference(env, expr);
return Type(env, message);
}
case "attr": {
case "getattr": {
const attr = AttributeExpression(env, expr);
return Type(env, attr);
}
case "var": {
case "getvar": {
const variant = VariantExpression(env, expr);
return Type(env, variant);
}
@ -1474,7 +1497,7 @@ function Type(env, expr) {
}
/**
* Resolve a reference to an external argument.
* Resolve a reference to a variable.
*
* @param {Object} env
* Resolver environment object.
@ -1485,11 +1508,11 @@ function Type(env, expr) {
* @returns {FluentType}
* @private
*/
function ExternalArgument(env, {name}) {
function VariableReference(env, {name}) {
const { args, errors } = env;
if (!args || !args.hasOwnProperty(name)) {
errors.push(new ReferenceError(`Unknown external: ${name}`));
errors.push(new ReferenceError(`Unknown variable: ${name}`));
return new FluentNone(name);
}
@ -1512,7 +1535,7 @@ function ExternalArgument(env, {name}) {
}
default:
errors.push(
new TypeError(`Unsupported external type: ${name}, ${typeof arg}`)
new TypeError(`Unsupported variable type: ${name}, ${typeof arg}`)
);
return new FluentNone(name);
}
@ -1691,13 +1714,13 @@ class FluentResource extends Map {
* responsible for parsing translation resources in the Fluent syntax and can
* format translation units (entities) to strings.
*
* Always use `MessageContext.format` to retrieve translation units from
* a context. Translations can contain references to other entities or
* external arguments, conditional logic in form of select expressions, traits
* which describe their grammatical features, and can use Fluent builtins which
* make use of the `Intl` formatters to format numbers, dates, lists and more
* into the context's language. See the documentation of the Fluent syntax for
* more information.
* Always use `MessageContext.format` to retrieve translation units from a
* context. Translations can contain references to other entities or variables,
* conditional logic in form of select expressions, traits which describe their
* grammatical features, and can use Fluent builtins which make use of the
* `Intl` formatters to format numbers, dates, lists and more into the
* context's language. See the documentation of the Fluent syntax for more
* information.
*/
class MessageContext {
@ -1849,8 +1872,8 @@ class MessageContext {
* Format a message to a string or null.
*
* Format a raw `message` from the context into a string (or a null if it has
* a null value). `args` will be used to resolve references to external
* arguments inside of the translation.
* a null value). `args` will be used to resolve references to variables
* passed as arguments to the translation.
*
* In case of errors `format` will try to salvage as much of the translation
* as possible and will still return a string. For performance reasons, the
@ -1868,7 +1891,7 @@ class MessageContext {
*
* // Returns 'Hello, name!' and `errors` is now:
*
* [<ReferenceError: Unknown external: name>]
* [<ReferenceError: Unknown variable: name>]
*
* @param {Object | string} message
* @param {Object | undefined} args

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -19,10 +19,10 @@
async function * generateMessages(locales, resourceIds) {
const mc = new MessageContext(locales);
mc.addMessages(`
file-menu
file-menu =
.label = File
.accesskey = F
new-tab
new-tab =
.label = New Tab
.accesskey = N
`);

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

@ -15,7 +15,7 @@
async function* mockGenerateMessages(locales, resourceIds) {
const mc = new MessageContext(locales);
mc.addMessages("title = Hello World");
mc.addMessages("link\n .title = Click me");
mc.addMessages("link =\n .title = Click me");
yield mc;
}

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

@ -626,7 +626,8 @@ TokenStreamChars<Utf8Unit, AnyCharsAccess>::internalEncodingError(uint8_t releva
TokenStreamAnyChars& anyChars = anyCharsAccess();
if (bool hasLineOfContext = anyChars.fillExcludingContext(&err, offset)) {
bool hasLineOfContext = anyChars.fillExcludingContext(&err, offset);
if (hasLineOfContext) {
if (!internalComputeLineOfContext(&err, offset))
break;

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

@ -301,8 +301,8 @@ MobileViewportManager::UpdateSPCSPS(const ScreenIntSize& aDisplaySize,
compositionSize.width -= scrollbars.LeftRight();
compositionSize.height -= scrollbars.TopBottom();
CSSSize compSize = compositionSize / aZoom;
MVM_LOG("%p: Setting SPCSPS %s\n", this, Stringify(compSize).c_str());
nsLayoutUtils::SetScrollPositionClampingScrollPortSize(mPresShell, compSize);
MVM_LOG("%p: Setting VVPS %s\n", this, Stringify(compSize).c_str());
nsLayoutUtils::SetVisualViewportSize(mPresShell, compSize);
}
void

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

@ -777,7 +777,7 @@ nsIPresShell::nsIPresShell()
, mIsFirstPaint(false)
, mObservesMutationsForPrint(false)
, mWasLastReflowInterrupted(false)
, mScrollPositionClampingScrollPortSizeSet(false)
, mVisualViewportSizeSet(false)
, mNeedLayoutFlush(true)
, mNeedStyleFlush(true)
, mObservingStyleFlushes(false)
@ -850,7 +850,7 @@ PresShell::PresShell()
mFrozen = false;
mRenderFlags = 0;
mScrollPositionClampingScrollPortSizeSet = false;
mVisualViewportSizeSet = false;
static bool addedSynthMouseMove = false;
if (!addedSynthMouseMove) {
@ -3445,7 +3445,7 @@ static void ScrollToShowRect(nsIScrollableFrame* aFrameAsScrollable,
{
nsPoint scrollPt = aFrameAsScrollable->GetScrollPosition();
nsRect visibleRect(scrollPt,
aFrameAsScrollable->GetScrollPositionClampingScrollPortSize());
aFrameAsScrollable->GetVisualViewportSize());
nsSize lineSize;
// Don't call GetLineScrollAmount unless we actually need it. Not only
@ -10590,14 +10590,14 @@ nsIPresShell::MarkFixedFramesForReflow(IntrinsicDirty aIntrinsicDirty)
}
void
nsIPresShell::SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight)
nsIPresShell::SetVisualViewportSize(nscoord aWidth, nscoord aHeight)
{
if (!mScrollPositionClampingScrollPortSizeSet ||
mScrollPositionClampingScrollPortSize.width != aWidth ||
mScrollPositionClampingScrollPortSize.height != aHeight) {
mScrollPositionClampingScrollPortSizeSet = true;
mScrollPositionClampingScrollPortSize.width = aWidth;
mScrollPositionClampingScrollPortSize.height = aHeight;
if (!mVisualViewportSizeSet ||
mVisualViewportSize.width != aWidth ||
mVisualViewportSize.height != aHeight) {
mVisualViewportSizeSet = true;
mVisualViewportSize.width = aWidth;
mVisualViewportSize.height = aHeight;
if (nsIScrollableFrame* rootScrollFrame = GetRootScrollFrameAsScrollable()) {
rootScrollFrame->MarkScrollbarsDirtyForReflow();

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

@ -1660,13 +1660,13 @@ public:
// clears that capture.
static void ClearMouseCapture(nsIFrame* aFrame);
void SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight);
bool IsScrollPositionClampingScrollPortSizeSet() {
return mScrollPositionClampingScrollPortSizeSet;
void SetVisualViewportSize(nscoord aWidth, nscoord aHeight);
bool IsVisualViewportSizeSet() {
return mVisualViewportSizeSet;
}
nsSize GetScrollPositionClampingScrollPortSize() {
NS_ASSERTION(mScrollPositionClampingScrollPortSizeSet, "asking for scroll port when its not set?");
return mScrollPositionClampingScrollPortSize;
nsSize GetVisualViewportSize() {
NS_ASSERTION(mVisualViewportSizeSet, "asking for visual viewport size when its not set?");
return mVisualViewportSize;
}
void SetVisualViewportOffset(const nsPoint& aScrollOffset) {
@ -1753,7 +1753,7 @@ protected:
// Count of the number of times this presshell has been painted to a window.
uint64_t mPaintCount;
nsSize mScrollPositionClampingScrollPortSize;
nsSize mVisualViewportSize;
nsPoint mVisualViewportOffset;
@ -1813,7 +1813,7 @@ protected:
// Whether the most recent interruptible reflow was actually interrupted:
bool mWasLastReflowInterrupted : 1;
bool mScrollPositionClampingScrollPortSizeSet : 1;
bool mVisualViewportSizeSet : 1;
// True if a layout flush might not be a no-op
bool mNeedLayoutFlush : 1;

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

@ -9040,11 +9040,11 @@ MaybeReflowForInflationScreenSizeChange(nsPresContext *aPresContext)
}
/* static */ void
nsLayoutUtils::SetScrollPositionClampingScrollPortSize(nsIPresShell* aPresShell, CSSSize aSize)
nsLayoutUtils::SetVisualViewportSize(nsIPresShell* aPresShell, CSSSize aSize)
{
MOZ_ASSERT(aSize.width >= 0.0 && aSize.height >= 0.0);
aPresShell->SetScrollPositionClampingScrollPortSize(
aPresShell->SetVisualViewportSize(
nsPresContext::CSSPixelsToAppUnits(aSize.width),
nsPresContext::CSSPixelsToAppUnits(aSize.height));

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

@ -2852,11 +2852,11 @@ public:
static bool HasDocumentLevelListenersForApzAwareEvents(nsIPresShell* aShell);
/**
* Set the scroll port size for the purpose of clamping the scroll position
* Set the viewport size for the purpose of clamping the scroll position
* for the root scroll frame of this document
* (see nsIDOMWindowUtils.setScrollPositionClampingScrollPortSize).
* (see nsIDOMWindowUtils.setVisualViewportSize).
*/
static void SetScrollPositionClampingScrollPortSize(nsIPresShell* aPresShell,
static void SetVisualViewportSize(nsIPresShell* aPresShell,
CSSSize aSize);
/**

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

@ -281,12 +281,12 @@ ViewportFrame::AdjustReflowInputAsContainingBlock(ReflowInput* aReflowInput) con
"We don't handle correct positioning of fixed frames with "
"scrollbars in odd positions");
// If a scroll position clamping scroll-port size has been set, layout
// If a scroll position clamping viewport size has been set, layout
// fixed position elements to this size instead of the computed size.
nsRect rect(0, 0, aReflowInput->ComputedWidth(), aReflowInput->ComputedHeight());
nsIPresShell* ps = PresShell();
if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
rect.SizeTo(ps->GetScrollPositionClampingScrollPortSize());
if (ps->IsVisualViewportSizeSet()) {
rect.SizeTo(ps->GetVisualViewportSize());
}
return rect;

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

@ -68,7 +68,7 @@ public:
/**
* Adjust aReflowInput to account for scrollbars and pres shell
* GetScrollPositionClampingScrollPortSizeSet and
* GetVisualViewportSizeSet and
* GetContentDocumentFixedPositionMargins adjustments.
* @return the rect to use as containing block rect
*/

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

@ -384,14 +384,14 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowInput* aState,
nsSize scrollPortSize = nsSize(std::max(0, aState->mInsideBorderSize.width - vScrollbarDesiredWidth),
std::max(0, aState->mInsideBorderSize.height - hScrollbarDesiredHeight));
nsSize visualScrollPortSize = scrollPortSize;
nsSize visualViewportSize = scrollPortSize;
nsIPresShell* presShell = PresShell();
if (mHelper.mIsRoot && presShell->IsScrollPositionClampingScrollPortSizeSet()) {
if (mHelper.mIsRoot && presShell->IsVisualViewportSizeSet()) {
nsSize compositionSize = nsLayoutUtils::CalculateCompositionSizeForFrame(this, false);
float resolution = presShell->GetResolution();
compositionSize.width /= resolution;
compositionSize.height /= resolution;
visualScrollPortSize = nsSize(std::max(0, compositionSize.width - vScrollbarDesiredWidth),
visualViewportSize = nsSize(std::max(0, compositionSize.width - vScrollbarDesiredWidth),
std::max(0, compositionSize.height - hScrollbarDesiredHeight));
}
@ -405,7 +405,7 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowInput* aState,
if (aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
bool wantHScrollbar =
aState->mStyles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL ||
scrolledRect.XMost() >= visualScrollPortSize.width + oneDevPixel ||
scrolledRect.XMost() >= visualViewportSize.width + oneDevPixel ||
scrolledRect.x <= -oneDevPixel;
if (scrollPortSize.width < hScrollbarMinSize.width)
wantHScrollbar = false;
@ -417,7 +417,7 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowInput* aState,
if (aState->mStyles.mVertical != NS_STYLE_OVERFLOW_HIDDEN) {
bool wantVScrollbar =
aState->mStyles.mVertical == NS_STYLE_OVERFLOW_SCROLL ||
scrolledRect.YMost() >= visualScrollPortSize.height + oneDevPixel ||
scrolledRect.YMost() >= visualViewportSize.height + oneDevPixel ||
scrolledRect.y <= -oneDevPixel;
if (scrollPortSize.height < vScrollbarMinSize.height)
wantVScrollbar = false;
@ -2860,10 +2860,10 @@ ScrollFrameHelper::ScrollToImpl(nsPoint aPt, const nsRect& aRange, nsAtom* aOrig
nsPoint dist(std::abs(pt.x - mLastUpdateFramesPos.x),
std::abs(pt.y - mLastUpdateFramesPos.y));
nsSize scrollPortSize = GetScrollPositionClampingScrollPortSize();
nscoord horzAllowance = std::max(scrollPortSize.width / std::max(sHorzScrollFraction, 1),
nsSize visualViewportSize = GetVisualViewportSize();
nscoord horzAllowance = std::max(visualViewportSize.width / std::max(sHorzScrollFraction, 1),
nsPresContext::AppUnitsPerCSSPixel());
nscoord vertAllowance = std::max(scrollPortSize.height / std::max(sVertScrollFraction, 1),
nscoord vertAllowance = std::max(visualViewportSize.height / std::max(sVertScrollFraction, 1),
nsPresContext::AppUnitsPerCSSPixel());
if (dist.x >= horzAllowance || dist.y >= vertAllowance) {
needFrameVisibilityUpdate = true;
@ -3491,7 +3491,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) {
aBuilder->AddToWillChangeBudget(mOuter, GetScrollPositionClampingScrollPortSize());
aBuilder->AddToWillChangeBudget(mOuter, GetVisualViewportSize());
}
mScrollParentID = aBuilder->GetCurrentScrollParentId();
@ -4056,16 +4056,16 @@ ScrollFrameHelper::GetScrollRangeForClamping() const
return nsRect(nscoord_MIN/2, nscoord_MIN/2,
nscoord_MAX - nscoord_MIN/2, nscoord_MAX - nscoord_MIN/2);
}
nsSize scrollPortSize = GetScrollPositionClampingScrollPortSize();
return GetScrollRange(scrollPortSize.width, scrollPortSize.height);
nsSize visualViewportSize = GetVisualViewportSize();
return GetScrollRange(visualViewportSize.width, visualViewportSize.height);
}
nsSize
ScrollFrameHelper::GetScrollPositionClampingScrollPortSize() const
ScrollFrameHelper::GetVisualViewportSize() const
{
nsIPresShell* presShell = mOuter->PresShell();
if (mIsRoot && presShell->IsScrollPositionClampingScrollPortSizeSet()) {
return presShell->GetScrollPositionClampingScrollPortSize();
if (mIsRoot && presShell->IsVisualViewportSizeSet()) {
return presShell->GetVisualViewportSize();
}
return mScrollPort.Size();
}
@ -5296,7 +5296,7 @@ ScrollFrameHelper::IsScrollingActive(nsDisplayListBuilder* aBuilder) const
{
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL) &&
aBuilder->IsInWillChangeBudget(mOuter, GetScrollPositionClampingScrollPortSize())) {
aBuilder->IsInWillChangeBudget(mOuter, GetVisualViewportSize())) {
return true;
}
@ -5604,7 +5604,7 @@ ScrollFrameHelper::ReflowFinished()
}
nsRect scrolledContentRect = GetScrolledRect();
nsSize scrollClampingScrollPort = GetScrollPositionClampingScrollPortSize();
nsSize scrollClampingScrollPort = GetVisualViewportSize();
nscoord minX = scrolledContentRect.x;
nscoord maxX = scrolledContentRect.XMost() - scrollClampingScrollPort.width;
nscoord minY = scrolledContentRect.y;
@ -5824,12 +5824,12 @@ ScrollFrameHelper::LayoutScrollbars(nsBoxLayoutState& aState,
bool scrollbarOnLeft = !IsScrollbarOnRight();
bool overlayScrollBarsWithZoom =
mIsRoot && LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) &&
presShell->IsScrollPositionClampingScrollPortSizeSet();
presShell->IsVisualViewportSizeSet();
nsSize scrollPortClampingSize = mScrollPort.Size();
double res = 1.0;
if (overlayScrollBarsWithZoom) {
scrollPortClampingSize = presShell->GetScrollPositionClampingScrollPortSize();
scrollPortClampingSize = presShell->GetVisualViewportSize();
res = presShell->GetCumulativeResolution();
}
@ -6109,11 +6109,11 @@ ScrollFrameHelper::GetScrolledRect() const
// For that, we first convert the scroll port and the scrolled rect to rects
// relative to the reference frame, since that's the space where painting does
// snapping.
nsSize scrollPortSize = GetScrollPositionClampingScrollPortSize();
nsSize visualViewportSize = GetVisualViewportSize();
const nsIFrame* referenceFrame =
mReferenceFrameDuringPainting ? mReferenceFrameDuringPainting : nsLayoutUtils::GetReferenceFrame(mOuter);
nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(referenceFrame);
nsRect scrollPort(mScrollPort.TopLeft() + toReferenceFrame, scrollPortSize);
nsRect scrollPort(mScrollPort.TopLeft() + toReferenceFrame, visualViewportSize);
nsRect scrolledRect = result + scrollPort.TopLeft();
if (scrollPort.Overflows() || scrolledRect.Overflows()) {

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

@ -214,9 +214,9 @@ public:
return pt;
}
nsRect GetScrollRange() const;
// Get the scroll range assuming the scrollport has size (aWidth, aHeight).
// Get the scroll range assuming the viewport has size (aWidth, aHeight).
nsRect GetScrollRange(nscoord aWidth, nscoord aHeight) const;
nsSize GetScrollPositionClampingScrollPortSize() const;
nsSize GetVisualViewportSize() const;
void ScrollSnap(nsIScrollableFrame::ScrollMode aMode = nsIScrollableFrame::SMOOTH_MSD);
void ScrollSnap(const nsPoint &aDestination,
nsIScrollableFrame::ScrollMode aMode = nsIScrollableFrame::SMOOTH_MSD);
@ -852,8 +852,8 @@ public:
virtual nsRect GetScrollRange() const override {
return mHelper.GetScrollRange();
}
virtual nsSize GetScrollPositionClampingScrollPortSize() const override {
return mHelper.GetScrollPositionClampingScrollPortSize();
virtual nsSize GetVisualViewportSize() const override {
return mHelper.GetVisualViewportSize();
}
virtual nsSize GetLineScrollAmount() const override {
return mHelper.GetLineScrollAmount();
@ -1304,8 +1304,8 @@ public:
virtual nsRect GetScrollRange() const override {
return mHelper.GetScrollRange();
}
virtual nsSize GetScrollPositionClampingScrollPortSize() const override {
return mHelper.GetScrollPositionClampingScrollPortSize();
virtual nsSize GetVisualViewportSize() const override {
return mHelper.GetVisualViewportSize();
}
virtual nsSize GetLineScrollAmount() const override {
return mHelper.GetLineScrollAmount();

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

@ -148,10 +148,10 @@ public:
*/
virtual nsRect GetScrollRange() const = 0;
/**
* Get the size of the scroll port to use when clamping the scroll
* Get the size of the view port to use when clamping the scroll
* position.
*/
virtual nsSize GetScrollPositionClampingScrollPortSize() const = 0;
virtual nsSize GetVisualViewportSize() const = 0;
/**
* Return how much we would try to scroll by in each direction if
* asked to scroll by one "line" vertically and horizontally.

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

@ -7017,8 +7017,8 @@ nsDisplayFixedPosition::BuildLayer(nsDisplayListBuilder* aBuilder,
if (viewportFrame) {
// Fixed position frames are reflowed into the scroll-port size if one has
// been set.
if (presContext->PresShell()->IsScrollPositionClampingScrollPortSizeSet()) {
anchorRect.SizeTo(presContext->PresShell()->GetScrollPositionClampingScrollPortSize());
if (presContext->PresShell()->IsVisualViewportSizeSet()) {
anchorRect.SizeTo(presContext->PresShell()->GetVisualViewportSize());
} else {
anchorRect.SizeTo(viewportFrame->GetSize());
}
@ -7193,9 +7193,9 @@ nsDisplayStickyPosition::BuildLayer(nsDisplayListBuilder* aBuilder,
// reflowed into the scroll-port size if one has been set.
nsSize scrollFrameSize = scrollFrame->GetSize();
if (scrollFrame == presContext->PresShell()->GetRootScrollFrame() &&
presContext->PresShell()->IsScrollPositionClampingScrollPortSizeSet()) {
presContext->PresShell()->IsVisualViewportSizeSet()) {
scrollFrameSize = presContext->PresShell()->
GetScrollPositionClampingScrollPortSize();
GetVisualViewportSize();
}
nsLayoutUtils::SetFixedPositionLayerData(layer, scrollFrame,

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

@ -1465,12 +1465,11 @@ public:
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
aBuilder->IsPaintingToWindow()) {
// position: fixed items are reflowed into and only drawn inside the
// viewport, or the scroll position clamping scrollport size, if one is
// set.
// viewport, or the visual viewport size, if one is set.
nsIPresShell* ps = aFrame->PresShell();
if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
if (ps->IsVisualViewportSizeSet()) {
dirtyRectRelativeToDirtyFrame =
nsRect(nsPoint(0, 0), ps->GetScrollPositionClampingScrollPortSize());
nsRect(nsPoint(0, 0), ps->GetVisualViewportSize());
visible = dirtyRectRelativeToDirtyFrame;
#ifdef MOZ_WIDGET_ANDROID
} else {

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

@ -292,8 +292,8 @@ function setupViewport(contentRootElement) {
var sw = attrOrDefault(contentRootElement, "reftest-scrollport-w", 0);
var sh = attrOrDefault(contentRootElement, "reftest-scrollport-h", 0);
if (sw !== 0 || sh !== 0) {
LogInfo("Setting scrollport to <w=" + sw + ", h=" + sh + ">");
windowUtils().setScrollPositionClampingScrollPortSize(sw, sh);
LogInfo("Setting viewport to <w=" + sw + ", h=" + sh + ">");
windowUtils().setVisualViewportSize(sw, sh);
}
// XXX support resolution when needed

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

@ -208,6 +208,10 @@ public:
{
return false;
}
bool UnsetRemoteSSRC(uint32_t ssrc) override
{
return true;
}
bool GetRemoteSSRC(unsigned int* ssrc) override;
bool SetLocalCNAME(const char* cname) override;
bool SetLocalMID(const std::string& mid) override;

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

@ -26,6 +26,7 @@
#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
#include <vector>
#include <set>
namespace webrtc {
class VideoFrame;
@ -40,64 +41,6 @@ enum class MediaSessionConduitLocalDirection : int {
using RtpExtList = std::vector<webrtc::RtpExtension>;
// Wrap the webrtc.org Call class adding mozilla add/ref support.
class WebRtcCallWrapper : public RefCounted<WebRtcCallWrapper>
{
public:
typedef webrtc::Call::Config Config;
static RefPtr<WebRtcCallWrapper> Create()
{
return new WebRtcCallWrapper();
}
static RefPtr<WebRtcCallWrapper> Create(UniquePtr<webrtc::Call>&& aCall)
{
return new WebRtcCallWrapper(std::move(aCall));
}
webrtc::Call* Call() const
{
return mCall.get();
}
virtual ~WebRtcCallWrapper()
{
if (mCall->voice_engine()) {
webrtc::VoiceEngine* voice_engine = mCall->voice_engine();
mCall.reset(nullptr); // Force it to release the voice engine reference
// Delete() must be after all refs are released
webrtc::VoiceEngine::Delete(voice_engine);
} else {
// Must ensure it's destroyed *before* the EventLog!
mCall.reset(nullptr);
}
}
MOZ_DECLARE_REFCOUNTED_TYPENAME(WebRtcCallWrapper)
private:
WebRtcCallWrapper()
{
webrtc::Call::Config config(&mEventLog);
mCall.reset(webrtc::Call::Create(config));
}
explicit WebRtcCallWrapper(UniquePtr<webrtc::Call>&& aCall)
{
MOZ_ASSERT(aCall);
mCall = std::move(aCall);
}
// Don't allow copying/assigning.
WebRtcCallWrapper(const WebRtcCallWrapper&) = delete;
void operator=(const WebRtcCallWrapper&) = delete;
UniquePtr<webrtc::Call> mCall;
webrtc::RtcEventLogNullImpl mEventLog;
};
/**
* Abstract Interface for transporting RTP packets - audio/vidoeo
* The consumers of this interface are responsible for passing in
@ -268,6 +211,7 @@ public:
virtual bool GetRemoteSSRC(unsigned int* ssrc) = 0;
virtual bool SetRemoteSSRC(unsigned int ssrc) = 0;
virtual bool UnsetRemoteSSRC(uint32_t ssrc) = 0;
virtual bool SetLocalCNAME(const char* cname) = 0;
virtual bool SetLocalMID(const std::string& mid) = 0;
@ -319,6 +263,87 @@ public:
};
// Wrap the webrtc.org Call class adding mozilla add/ref support.
class WebRtcCallWrapper : public RefCounted<WebRtcCallWrapper>
{
public:
typedef webrtc::Call::Config Config;
static RefPtr<WebRtcCallWrapper> Create()
{
return new WebRtcCallWrapper();
}
static RefPtr<WebRtcCallWrapper> Create(UniquePtr<webrtc::Call>&& aCall)
{
return new WebRtcCallWrapper(std::move(aCall));
}
// Don't allow copying/assigning.
WebRtcCallWrapper(const WebRtcCallWrapper&) = delete;
void operator=(const WebRtcCallWrapper&) = delete;
webrtc::Call* Call() const
{
return mCall.get();
}
virtual ~WebRtcCallWrapper()
{
if (mCall->voice_engine()) {
webrtc::VoiceEngine* voice_engine = mCall->voice_engine();
mCall.reset(nullptr); // Force it to release the voice engine reference
// Delete() must be after all refs are released
webrtc::VoiceEngine::Delete(voice_engine);
} else {
// Must ensure it's destroyed *before* the EventLog!
mCall.reset(nullptr);
}
}
bool UnsetRemoteSSRC(uint32_t ssrc)
{
for (auto conduit : mConduits) {
if (!conduit->UnsetRemoteSSRC(ssrc)) {
return false;
}
}
return true;
}
void RegisterConduit(MediaSessionConduit* conduit)
{
mConduits.insert(conduit);
}
void UnregisterConduit(MediaSessionConduit* conduit)
{
mConduits.erase(conduit);
}
MOZ_DECLARE_REFCOUNTED_TYPENAME(WebRtcCallWrapper)
private:
WebRtcCallWrapper()
{
webrtc::Call::Config config(&mEventLog);
mCall.reset(webrtc::Call::Create(config));
}
explicit WebRtcCallWrapper(UniquePtr<webrtc::Call>&& aCall)
{
MOZ_ASSERT(aCall);
mCall = std::move(aCall);
}
UniquePtr<webrtc::Call> mCall;
webrtc::RtcEventLogNullImpl mEventLog;
// Allows conduits to know about one another, to avoid remote SSRC
// collisions.
std::set<MediaSessionConduit*> mConduits;
};
// Abstract base classes for external encoder/decoder.
class CodecPluginID
{
@ -389,6 +414,7 @@ public:
virtual void DisableSsrcChanges() = 0;
bool SetRemoteSSRC(unsigned int ssrc) override = 0;
bool UnsetRemoteSSRC(uint32_t ssrc) override = 0;
/**
* Function to deliver a capture video frame for encoding and transport.

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

@ -277,6 +277,7 @@ WebrtcVideoConduit::WebrtcVideoConduit(RefPtr<WebRtcCallWrapper> aCall,
, mRecvCodecPlugin(nullptr)
, mVideoStatsTimer(NS_NewTimer())
{
mCall->RegisterConduit(this);
mRecvStreamConfig.renderer = this;
// Video Stats Callback
@ -307,6 +308,7 @@ WebrtcVideoConduit::~WebrtcVideoConduit()
{
CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
mCall->UnregisterConduit(this);
if (mVideoStatsTimer) {
CSFLogDebug(LOGTAG, "canceling StreamStats for VideoConduit: %p", this);
MutexAutoLock lock(mCodecMutex);
@ -884,6 +886,22 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
return condError;
}
static uint32_t
GenerateRandomSSRC()
{
uint32_t ssrc;
do {
SECStatus rv = PK11_GenerateRandom(reinterpret_cast<unsigned char*>(&ssrc), sizeof(ssrc));
if (rv != SECSuccess) {
CSFLogError(LOGTAG, "%s: PK11_GenerateRandom failed with error %d",
__FUNCTION__, rv);
return 0;
}
} while (ssrc == 0); // webrtc.org code has fits if you select an SSRC of 0
return ssrc;
}
bool
WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
{
@ -902,6 +920,11 @@ WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
}
CSFLogDebug(LOGTAG, "%s: SSRC %u (0x%x)", __FUNCTION__, ssrc, ssrc);
if (!mCall->UnsetRemoteSSRC(ssrc)) {
CSFLogError(LOGTAG, "%s: Failed to unset SSRC %u (0x%x) on other conduits,"
" bailing", __FUNCTION__, ssrc, ssrc);
return false;
}
mRecvStreamConfig.rtp.remote_ssrc = ssrc;
mWaitingForInitialSsrc = false;
@ -926,6 +949,33 @@ WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
return (StartReceiving() == kMediaConduitNoError);
}
bool
WebrtcVideoConduit::UnsetRemoteSSRC(uint32_t ssrc)
{
unsigned int our_ssrc;
if (!GetRemoteSSRC(&our_ssrc)) {
// This only fails when we aren't sending, which isn't really an error here
return true;
}
if (our_ssrc != ssrc) {
return true;
}
while (our_ssrc == ssrc) {
our_ssrc = GenerateRandomSSRC();
if (our_ssrc == 0) {
return false;
}
}
// There is a (tiny) chance that this new random ssrc will collide with some
// other conduit's remote ssrc, in which case that conduit will choose a new
// one.
SetRemoteSSRC(our_ssrc);
return true;
}
bool
WebrtcVideoConduit::GetRemoteSSRC(unsigned int* ssrc)
{
@ -1428,13 +1478,12 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs(
// Handle un-signalled SSRCs by creating a random one and then when it actually gets set,
// we'll destroy and recreate. Simpler than trying to unwind all the logic that assumes
// the receive stream is created and started when we ConfigureRecvMediaCodecs()
unsigned int ssrc;
do {
SECStatus rv = PK11_GenerateRandom(reinterpret_cast<unsigned char*>(&ssrc), sizeof(ssrc));
if (rv != SECSuccess) {
return kMediaConduitUnknownError;
}
} while (ssrc == 0); // webrtc.org code has fits if you select an SSRC of 0
uint32_t ssrc = GenerateRandomSSRC();
if (ssrc == 0) {
// webrtc.org code has fits if you select an SSRC of 0, so that's how
// we signal an error.
return kMediaConduitUnknownError;
}
mRecvStreamConfig.rtp.remote_ssrc = ssrc;
mRecvSSRC = ssrc;
@ -1451,13 +1500,12 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs(
auto ssrc = mSendStreamConfig.rtp.ssrcs.front();
Unused << NS_WARN_IF(ssrc == mRecvStreamConfig.rtp.remote_ssrc);
while (ssrc == mRecvStreamConfig.rtp.remote_ssrc || ssrc == 0) {
SECStatus rv = PK11_GenerateRandom(reinterpret_cast<unsigned char*>(&ssrc), sizeof(ssrc));
if (rv != SECSuccess) {
while (ssrc == mRecvStreamConfig.rtp.remote_ssrc) {
ssrc = GenerateRandomSSRC();
if (ssrc == 0) {
return kMediaConduitUnknownError;
}
}
// webrtc.org code has fits if you select an SSRC of 0
mRecvStreamConfig.rtp.local_ssrc = ssrc;
CSFLogDebug(LOGTAG, "%s (%p): Local SSRC 0x%08x (of %u), remote SSRC 0x%08x",

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

@ -275,6 +275,7 @@ public:
bool SetLocalSSRCs(const std::vector<unsigned int> & ssrcs) override;
bool GetRemoteSSRC(unsigned int* ssrc) override;
bool SetRemoteSSRC(unsigned int ssrc) override;
bool UnsetRemoteSSRC(uint32_t ssrc) override;
bool SetLocalCNAME(const char* cname) override;
bool SetLocalMID(const std::string& mid) override;

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

@ -880,10 +880,6 @@ pref("media.openUnsupportedTypeWithExternalApp", true);
pref("dom.keyboardevent.dispatch_during_composition", true);
#if CPU_ARCH == aarch64
pref("javascript.options.native_regexp", false);
#endif
// Ask for permission when enumerating WebRTC devices.
pref("media.navigator.permission.device", true);

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

@ -581,6 +581,7 @@ def config_status_deps(build_env, build_project):
extra_deps = [os.path.join(topobjdir[:-7], '.mozconfig.json')]
return list(__sandbox__._all_paths) + extra_deps + [
os.path.join(topsrcdir, 'CLOBBER'),
os.path.join(topsrcdir, 'configure'),
os.path.join(topsrcdir, 'js', 'src', 'configure'),
os.path.join(topsrcdir, 'configure.in'),

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

@ -711,11 +711,9 @@ class TupBackend(CommonBackend):
'PYTHON': self.environment.substs['PYTHON'],
'PYTHONDONTWRITEBYTECODE': '1',
}
cargo_incremental = self.environment.substs.get('CARGO_INCREMENTAL')
if cargo_incremental is not None:
# TODO (bug 1468527): CARGO_INCREMENTAL produces outputs that Tup
# doesn't know about, disable it unconditionally for now.
pass # env['CARGO_INCREMENTAL'] = cargo_incremental
# TODO (bug 1468527): CARGO_INCREMENTAL produces outputs that Tup
# doesn't know about, disable it unconditionally for now.
env['CARGO_INCREMENTAL'] = '0'
rust_simd = self.environment.substs.get('MOZ_RUST_SIMD')
if rust_simd is not None:

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

@ -0,0 +1,2 @@
[object-in-svg-foreignobject.sub.html]
disabled: https://github.com/web-platform-tests/wpt/issues/12282

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

@ -20,7 +20,7 @@
It uses demo web applications to simulate user actions such as adding to-do items.
</p>
<p id="screen-size-warning"><strong>
Your browser window is too small. For most accurate results, please make the view port size at least 850px by 650px.<br>
Your browser window is too small. For most accurate results, please make the viewport size at least 850px by 650px.<br>
It's currently <span id="screen-size"></span>.
</strong></p>
<div class="buttons">

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

@ -29,7 +29,7 @@
StyleBench is a browser benchmark that measures the performance of the style resolution mechanism.
</p>
<p id="screen-size-warning"><strong>
Your browser window is too small. For most accurate results, please make the view port size at least 850px by 650px.<br>
Your browser window is too small. For most accurate results, please make the viewport size at least 850px by 650px.<br>
It's currently <span id="screen-size"></span>.
</strong>
<div class="buttons">

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

@ -10,7 +10,6 @@ with Files('**'):
DIRS += ['build']
XPIDL_SOURCES += [
'nsCWebBrowser.idl',
'nsIEmbeddingSiteWindow.idl',
'nsIWebBrowser.idl',
'nsIWebBrowserChrome.idl',

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

@ -1,34 +0,0 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsIWebBrowser.idl"
#include "nsIBaseWindow.idl"
#include "nsIScrollable.idl"
#include "nsITextScroll.idl"
/*
nsCWebBrowser implements:
-------------------------
nsIWebBrowser
nsIDocShellTreeItem
nsIWebNavigation
nsIWebProgress
nsIBaseWindow
nsIScrollable
nsITextScroll
nsIInterfaceRequestor
Outwardly communicates with:
----------------------------
nsIWebBrowserChrome
nsIBaseWindow
nsIInterfaceRequestor
*/
%{ C++
#include "nsEmbedCID.h"
%}

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

@ -43,15 +43,4 @@
#define NS_PROMPTSERVICE_CONTRACTID \
"@mozilla.org/embedcomp/prompt-service;1"
/**
* This contract ID should be implemented by password managers to be able to
* override the standard implementation of nsIAuthPrompt2. It will be used as
* a service.
*
* This contract implements the following interfaces:
* nsIPromptFactory
*/
#define NS_PWMGR_AUTHPROMPTFACTORY \
"@mozilla.org/passwordmanager/authpromptfactory;1"
#endif // NSEMBEDCID_H

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

@ -31,7 +31,6 @@
#include "nsISHistoryListener.h"
#include "nsIURI.h"
#include "nsIWebBrowserPersist.h"
#include "nsCWebBrowserPersist.h"
#include "nsIServiceManager.h"
#include "nsFocusManager.h"
#include "Layers.h"

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

@ -16,7 +16,6 @@
#include "nsCycleCollectionParticipant.h"
// Interfaces needed
#include "nsCWebBrowser.h"
#include "nsIBaseWindow.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"

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

@ -989,9 +989,10 @@ function EngineURL(aType, aMethod, aTemplate, aResultDomain) {
FAIL("new EngineURL: template uses invalid scheme!", Cr.NS_ERROR_FAILURE);
}
this.templateHost = templateURI.host;
// If no resultDomain was specified in the engine definition file, use the
// host from the template.
this.resultDomain = aResultDomain || templateURI.host;
this.resultDomain = aResultDomain || this.templateHost;
}
EngineURL.prototype = {
@ -4154,6 +4155,33 @@ SearchService.prototype = {
}
}
if (!sendSubmissionURL) {
// ... or engines that are the same domain as a default engine.
let engineHost = engine._getURLOfType(URLTYPE_SEARCH_HTML).templateHost;
for (let name in this._engines) {
let innerEngine = this._engines[name];
if (!innerEngine._isDefault) {
continue;
}
let innerEngineURL = innerEngine._getURLOfType(URLTYPE_SEARCH_HTML);
if (innerEngineURL.templateHost == engineHost) {
sendSubmissionURL = true;
break;
}
}
if (!sendSubmissionURL) {
// ... or well known search domains.
//
// Starts with: www.google., search.aol., yandex.
// or
// Ends with: search.yahoo.com, .ask.com, .bing.com, .startpage.com, baidu.com, duckduckgo.com
const urlTest = /^(?:www\.google\.|search\.aol\.|yandex\.)|(?:search\.yahoo|\.ask|\.bing|\.startpage|\.baidu|\.duckduckgo)\.com$/;
sendSubmissionURL = urlTest.test(engineHost);
}
}
if (sendSubmissionURL) {
let uri = engine._getURLOfType("text/html")
.getSubmission("", engine, "searchbar").uri;

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

@ -0,0 +1,58 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Tests covering sending submission URLs for major engines
*/
const SUBMISSION_YES = new Map([
["Google1 Test", "https://www.google.com/search?q={searchTerms}"],
["Google2 Test", "https://www.google.co.uk/search?q={searchTerms}"],
["Yahoo1 Test", "https://search.yahoo.com/search?p={searchTerms}"],
["Yahoo2 Test", "https://uk.search.yahoo.com/search?p={searchTerms}"],
["AOL1 Test", "https://search.aol.com/aol/search?q={searchTerms}"],
["AOL2 Test", "https://search.aol.co.uk/aol/search?q={searchTerms}"],
["Yandex1 Test", "https://yandex.ru/search/?text={searchTerms}"],
["Yandex2 Test", "https://yandex.com/search/?text{searchTerms}"],
["Ask1 Test", "https://www.ask.com/web?q={searchTerms}"],
["Ask2 Test", "https://fr.ask.com/web?q={searchTerms}"],
["Bing Test", "https://www.bing.com/search?q={searchTerms}"],
["Startpage Test", "https://www.startpage.com/do/search?query={searchTerms}"],
["DuckDuckGo Test", "https://duckduckgo.com/?q={searchTerms}"],
["Baidu Test", "https://www.baidu.com/s?wd={searchTerms}"],
]);
const SUBMISSION_NO = new Map([
["Other1 Test", "https://example.com?q={searchTerms}"],
["Other2 Test", "https://googlebutnotgoogle.com?q={searchTerms}"],
]);
function addAndMakeDefault(name, searchURL) {
Services.search.addEngineWithDetails(name, null, null, null, "GET", searchURL);
let engine = Services.search.getEngineByName(name);
Services.search.currentEngine = engine;
return engine;
}
add_task(async function test() {
Assert.ok(!Services.search.isInitialized);
await asyncInit();
let engineInfo;
let engine;
for (let [name, searchURL] of SUBMISSION_YES) {
engine = addAndMakeDefault(name, searchURL);
engineInfo = Services.search.getDefaultEngineInfo();
Assert.equal(engineInfo.submissionURL, searchURL.replace("{searchTerms}", ""));
Services.search.removeEngine(engine);
}
for (let [name, searchURL] of SUBMISSION_NO) {
engine = addAndMakeDefault(name, searchURL);
engineInfo = Services.search.getDefaultEngineInfo();
Assert.equal(engineInfo.submissionURL, null);
Services.search.removeEngine(engine);
}
});

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

@ -101,3 +101,4 @@ skip-if = (verify && !debug && (os == 'linux'))
[test_engineUpdate.js]
[test_paramSubstitution.js]
[test_migrateWebExtensionEngine.js]
[test_sendSubmissionURL.js]

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

@ -42,7 +42,7 @@ Structure:
name: <string>, // engine name, e.g. "Yahoo"; or "NONE" if no default
loadPath: <string>, // where the engine line is located; missing if no default
origin: <string>, // 'default', 'verified', 'unverified', or 'invalid'; based on the presence and validity of the engine's loadPath verification hash.
submissionURL: <string> // missing if no default or for user-installed engines
submissionURL: <string> // set for default engines or well known search domains
},
searchCohort: <string>, // optional, contains an identifier for any active search A/B experiments
e10sEnabled: <bool>, // whether e10s is on, i.e. browser tabs open by default in a different process

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

@ -12,12 +12,33 @@ function setup_test_preference() {
function checkIsVideoDocumentAutoplay(browser) {
return ContentTask.spawn(browser, null, async () => {
let video = content.document.getElementsByTagName("video")[0];
let played = video && await video.play().then(() => true, () => false);
const video = content.document.getElementsByTagName("video")[0];
const played = video && await video.play().then(() => true, () => false);
ok(played, "Should be able to play in video document.");
});
}
async function checkIsIframeVideoDocumentAutoplay(browser) {
info("- create iframe video document -");
await ContentTask.spawn(browser, PAGE, async (pageURL) => {
const iframe = content.document.createElement("iframe");
iframe.src = pageURL;
content.document.body.appendChild(iframe);
const iframeLoaded = new Promise((resolve, reject) => {
iframe.addEventListener("load", e => resolve(), {once: true});
});
await iframeLoaded;
});
info("- check whether iframe video document starts playing -");
await ContentTask.spawn(browser, null, async () => {
const iframe = content.document.querySelector("iframe");
const video = iframe.contentDocument.querySelector("video");
ok(video.paused, "Subdoc video should not have played");
is(video.played.length, 0, "Should have empty played ranges");
});
}
add_task(async () => {
await BrowserTestUtils.withNewTab({
gBrowser,
@ -31,3 +52,16 @@ add_task(async () => {
});
});
add_task(async () => {
await BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank",
}, async (browser) => {
info("- setup test preference -");
await setup_test_preference();
info(`- check whether video document in iframe is autoplay -`);
await checkIsIframeVideoDocumentAutoplay(browser);
});
});

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

@ -29,7 +29,6 @@
#include "nsIScreenManager.h"
#include "nsISupportsPrimitives.h"
#include "nsIURL.h"
#include "nsCWebBrowserPersist.h"
#include "nsToolkit.h"
#include "nsCRT.h"
#include "nsDirectoryServiceDefs.h"