Merge m-c to autoland a=merge CLOSED TREE

MozReview-Commit-ID: Ko3lhAvzMJN
This commit is contained in:
Wes Kocher 2017-08-03 18:22:09 -07:00
Родитель bb9cb9182f 2196b718d3
Коммит db7d003ae0
1129 изменённых файлов: 33628 добавлений и 8347 удалений

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

@ -95,7 +95,7 @@
#endif
<html:link rel="shortcut icon"
href="chrome://browser/skin/preferences/in-content-new/favicon.ico"/>
href="chrome://browser/skin/settings.svg"/>
<script type="application/javascript"
src="chrome://browser/content/utilityOverlay.js"/>

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

@ -69,7 +69,7 @@
#endif
<html:link rel="shortcut icon"
href="chrome://browser/skin/preferences/in-content/favicon.ico"/>
href="chrome://browser/skin/settings.svg"/>
<script type="application/javascript"
src="chrome://browser/content/utilityOverlay.js"/>

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

@ -7,9 +7,7 @@ MOZ_AUTOMATION_L10N_CHECK=0
ac_add_options --enable-debug
ac_add_options --enable-dmd
# Disable stylo until bug 1356926 is fixed and we have >= llvm39 on centos.
ac_add_options --disable-stylo
unset LLVM_CONFIG
. $topsrcdir/build/mozconfig.stylo
# Use Clang as specified in manifest
export CC="$topsrcdir/clang/bin/clang"

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

@ -6,9 +6,7 @@ MOZ_AUTOMATION_L10N_CHECK=0
ac_add_options --enable-dmd
# Disable stylo until bug 1356926 is fixed and we have >= llvm39 on centos.
ac_add_options --disable-stylo
unset LLVM_CONFIG
. $topsrcdir/build/mozconfig.stylo
# Use Clang as specified in manifest
CC="$topsrcdir/clang/bin/clang"

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

@ -1,18 +0,0 @@
[
{
"version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
"size": 161014632,
"digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
},
{
"size": 12072532,
"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
}
]

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

@ -1,18 +0,0 @@
[
{
"size": 12072532,
"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
},
{
"version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
"size": 161014632,
"digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
}
]

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

@ -1,26 +0,0 @@
[
{
"version": "clang 3.8.0, libgcc 4.8.5",
"size": 140319580,
"digest": "34e219d7e8eaffa81710631c34d21355563d06335b3c00851e94c1f42f9098788fded8463dd0f67dd699f77b47a0245dd7aff754943a7a03fb5fd145a808254f",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true
},
{
"size": 12072532,
"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
},
{
"version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
"size": 161014632,
"digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
}
]

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

@ -1,18 +0,0 @@
[
{
"version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
"size": 161014632,
"digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
},
{
"size": 12072532,
"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
}
]

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

@ -1,18 +0,0 @@
[
{
"version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
"size": 161014632,
"digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
},
{
"size": 12072532,
"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
}
]

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

@ -34,6 +34,14 @@
background: none;
}
/* Keyboard focus styling */
#onboarding-overlay-button:-moz-focusring {
outline: solid 2px rgba(0, 0, 0, 0.1);
-moz-outline-radius: 5px;
outline-offset: 5px;
transition: outline-offset 150ms;
}
#onboarding-overlay-button-icon {
width: 36px;
vertical-align: top;
@ -308,7 +316,8 @@
}
/* Remove default dotted outline around buttons' text */
.onboarding-tour-action-button::-moz-focus-inner {
.onboarding-tour-action-button::-moz-focus-inner,
#onboarding-overlay-button::-moz-focus-inner {
border: 0;
}

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

@ -394,13 +394,14 @@ class Onboarding {
this._tourItems = [];
this._tourPages = [];
let { body } = this._window.document;
this._overlayIcon = this._renderOverlayButton();
this._overlayIcon.addEventListener("click", this);
this._window.document.body.appendChild(this._overlayIcon);
body.insertBefore(this._overlayIcon, body.firstChild);
this._overlay = this._renderOverlay();
this._overlay.addEventListener("click", this);
this._window.document.body.appendChild(this._overlay);
body.appendChild(this._overlay);
this._loadJS(TOUR_AGENT_JS_URI);
@ -827,8 +828,11 @@ class Onboarding {
let tooltip = this._bundle.formatStringFromName(tooltipStringId, [BRAND_SHORT_NAME], 1);
button.setAttribute("aria-label", tooltip);
button.id = "onboarding-overlay-button";
button.setAttribute("aria-haspopup", true);
button.setAttribute("aria-controls", "onboarding-overlay-dialog");
let img = this._window.document.createElement("img");
img.id = "onboarding-overlay-button-icon";
img.setAttribute("role", "presentation");
img.src = "resource://onboarding/img/overlay-icon.svg";
button.appendChild(img);
return button;

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

@ -2,6 +2,7 @@
support-files =
head.js
[browser_onboarding_accessibility.js]
[browser_onboarding_notification.js]
[browser_onboarding_notification_2.js]
[browser_onboarding_notification_3.js]

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

@ -0,0 +1,31 @@
/* 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";
add_task(async function test_onboarding_overlay_button() {
resetOnboardingDefaultState();
info("Wait for onboarding overlay loaded");
let tab = await openTab(ABOUT_HOME_URL);
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
info("Test accessibility and semantics of the overlay button");
await ContentTask.spawn(tab.linkedBrowser, {}, function() {
let doc = content.document;
let button = doc.body.firstChild;
is(button.id, "onboarding-overlay-button",
"First child is an overlay button");
ok(button.getAttribute("aria-label"),
"Onboarding button has an accessible label");
is(button.getAttribute("aria-haspopup"), "true",
"Onboarding button should indicate that it triggers a popup");
is(button.getAttribute("aria-controls"), "onboarding-overlay-dialog",
"Onboarding button semantically controls an overlay dialog");
is(button.firstChild.getAttribute("role"), "presentation",
"Onboarding button icon should have presentation only semantics");
});
await BrowserTestUtils.removeTab(tab);
});

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

@ -31,13 +31,11 @@ browser/chrome/browser/content/browser/preferences/in-content-new/security.js
browser/chrome/browser/content/browser/preferences/in-content-new/sync.js
browser/chrome/browser/skin/classic/browser/preferences/in-content/search.css
browser/chrome/browser/skin/classic/browser/preferences/in-content/containers.css
browser/chrome/browser/skin/classic/browser/preferences/in-content/favicon.ico
browser/chrome/browser/skin/classic/browser/preferences/in-content/icons.svg
browser/chrome/browser/skin/classic/browser/preferences/in-content/preferences.css
browser/chrome/browser/skin/classic/browser/preferences/in-content/dialog.css
browser/chrome/browser/skin/classic/browser/preferences/in-content-new/search.css
browser/chrome/browser/skin/classic/browser/preferences/in-content-new/containers.css
browser/chrome/browser/skin/classic/browser/preferences/in-content-new/favicon.ico
browser/chrome/browser/skin/classic/browser/preferences/in-content-new/icons.svg
browser/chrome/browser/skin/classic/browser/preferences/in-content-new/preferences.css
browser/chrome/browser/skin/classic/browser/preferences/in-content-new/dialog.css

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

До

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

Двоичные данные
browser/themes/shared/incontentprefs/favicon.ico

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

До

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

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

@ -95,13 +95,11 @@
skin/classic/browser/panel-icon-magnifier.svg (../shared/panel-icon-magnifier.svg)
#endif
skin/classic/browser/panel-icon-retry.svg (../shared/panel-icon-retry.svg)
skin/classic/browser/preferences/in-content-new/favicon.ico (../shared/incontentprefs/favicon.ico)
skin/classic/browser/preferences/in-content-new/icons.svg (../shared/incontentprefs/icons.svg)
skin/classic/browser/preferences/in-content-new/search-arrow-indicator.svg (../shared/incontentprefs/search-arrow-indicator.svg)
skin/classic/browser/preferences/in-content-new/search.css (../shared/incontentprefs/search.css)
skin/classic/browser/preferences/in-content-new/siteDataSettings.css (../shared/incontentprefs/siteDataSettings.css)
* skin/classic/browser/preferences/in-content-new/containers.css (../shared/incontentprefs/containers.css)
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs-old/favicon.ico)
skin/classic/browser/preferences/in-content/icons.svg (../shared/incontentprefs-old/icons.svg)
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs-old/search.css)
* skin/classic/browser/preferences/in-content/containers.css (../shared/incontentprefs-old/containers.css)

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

@ -77,6 +77,11 @@
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
}
.tab-icon-image[src^="chrome://"] {
-moz-context-properties: fill;
fill: currentColor;
}
.tab-icon-image[sharing]:not([selected]),
.tab-sharing-icon-overlay {
animation: 3s linear tab-sharing-icon-pulse infinite;

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

@ -9,7 +9,7 @@ this.EXPORTED_SYMBOLS = ["Tabs"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const CUST_TAB = "chrome://browser/skin/customizableui/customizeFavicon.ico";
const PREFS_TAB = "chrome://browser/skin/preferences/in-content-new/favicon.ico";
const PREFS_TAB = "chrome://browser/skin/settings.svg";
const DEFAULT_FAVICON_TAB = `data:text/html,<meta charset="utf-8">
<title>No favicon</title>`;

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

@ -28,6 +28,7 @@ This file adds the necessary compatibility tricks to avoid symbols with
version GLIBCXX_3.4.16 and bigger, keeping binary compatibility with
libstdc++ 4.6.1.
WARNING: all symbols from this file must be defined weak.
*/
#define GLIBCXX_VERSION(a, b, c) (((a) << 16) | ((b) << 8) | (c))
@ -39,7 +40,7 @@ libstdc++ 4.6.1.
#include <tr1/unordered_map>
namespace std
{
size_t
size_t __attribute__((weak))
__detail::_Prime_rehash_policy::_M_next_bkt(size_t __n) const
{
tr1::__detail::_Prime_rehash_policy policy(_M_max_load_factor);
@ -48,7 +49,7 @@ namespace std
return ret;
}
pair<bool, size_t>
pair<bool, size_t> __attribute__((weak))
__detail::_Prime_rehash_policy::_M_need_rehash(size_t __n_bkt,
size_t __n_elt,
size_t __n_ins) const
@ -67,7 +68,7 @@ namespace std {
/* We shouldn't be throwing exceptions at all, but it sadly turns out
we call STL (inline) functions that do. */
void __throw_out_of_range_fmt(char const* fmt, ...)
void __attribute__((weak)) __throw_out_of_range_fmt(char const* fmt, ...)
{
va_list ap;
char buf[1024]; // That should be big enough.
@ -87,7 +88,7 @@ namespace std {
/* Technically, this symbol is not in GLIBCXX_3.4.20, but in CXXABI_1.3.8,
but that's equivalent, version-wise. Those calls are added by the compiler
itself on `new Class[n]` calls. */
extern "C" void
extern "C" void __attribute__((weak))
__cxa_throw_bad_array_new_length()
{
MOZ_CRASH();
@ -100,7 +101,7 @@ __cxa_throw_bad_array_new_length()
* char const* argument. Older versions only have a constructor with
* std::string. */
namespace std {
runtime_error::runtime_error(char const* s)
__attribute__((weak)) runtime_error::runtime_error(char const* s)
: runtime_error(std::string(s))
{
}

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

@ -445,7 +445,7 @@ skip-if = e10s && debug
[browser_dbg_watch-expressions-02.js]
skip-if = e10s && debug
[browser_dbg_worker-console-01.js]
skip-if = e10s && debug
skip-if = true # bug 1368569
[browser_dbg_worker-console-02.js]
skip-if = e10s && debug
[browser_dbg_worker-console-03.js]

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

@ -44,4 +44,4 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
subsuite = clipboard
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
[browser_computed_style-editor-link.js]
skip-if = os == 'mac' # bug 1307846
skip-if = true # bug 1307846

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

@ -270,7 +270,7 @@ skip-if = stylo # Bug 1384802 - Empty rules aren't returned
[browser_rules_strict-search-filter_02.js]
[browser_rules_strict-search-filter_03.js]
[browser_rules_style-editor-link.js]
skip-if = !debug # Bug 1309759
skip-if = true # Bug 1309759
[browser_rules_url-click-opens-new-tab.js]
[browser_rules_urls-clickable.js]
[browser_rules_user-agent-styles.js]

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

@ -8631,6 +8631,12 @@ private:
} // namespace
bool
nsDocShell::SandboxFlagsImplyCookies(const uint32_t &aSandboxFlags)
{
return (aSandboxFlags & (SANDBOXED_ORIGIN | SANDBOXED_SCRIPTS)) == 0;
}
nsresult
nsDocShell::RestoreFromHistory()
{
@ -9291,6 +9297,9 @@ nsDocShell::CreateContentViewer(const nsACString& aContentType,
// Mark the channel as being a document URI...
aOpenedChannel->GetLoadFlags(&loadFlags);
loadFlags |= nsIChannel::LOAD_DOCUMENT_URI;
if (SandboxFlagsImplyCookies(mSandboxFlags)) {
loadFlags |= nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE;
}
aOpenedChannel->SetLoadFlags(loadFlags);
@ -11507,6 +11516,9 @@ nsDocShell::DoChannelLoad(nsIChannel* aChannel,
loadFlags |= nsIChannel::LOAD_DOCUMENT_URI |
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS;
if (SandboxFlagsImplyCookies(mSandboxFlags)) {
loadFlags |= nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE;
}
// Load attributes depend on load type...
switch (mLoadType) {
case LOAD_HISTORY: {

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

@ -257,6 +257,8 @@ public:
friend class OnLinkClickEvent;
static bool SandboxFlagsImplyCookies(const uint32_t &aSandboxFlags);
// We need dummy OnLocationChange in some cases to update the UI without
// updating security info.
void FireDummyOnLocationChange()

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

@ -132,48 +132,6 @@ ToChar(SelectionType aSelectionType)
}
}
static bool
IsValidSelectionType(RawSelectionType aRawSelectionType)
{
switch (static_cast<SelectionType>(aRawSelectionType)) {
case SelectionType::eNone:
case SelectionType::eNormal:
case SelectionType::eSpellCheck:
case SelectionType::eIMERawClause:
case SelectionType::eIMESelectedRawClause:
case SelectionType::eIMEConvertedClause:
case SelectionType::eIMESelectedClause:
case SelectionType::eAccessibility:
case SelectionType::eFind:
case SelectionType::eURLSecondary:
case SelectionType::eURLStrikeout:
return true;
default:
return false;
}
}
SelectionType
ToSelectionType(RawSelectionType aRawSelectionType)
{
if (!IsValidSelectionType(aRawSelectionType)) {
return SelectionType::eInvalid;
}
return static_cast<SelectionType>(aRawSelectionType);
}
RawSelectionType
ToRawSelectionType(SelectionType aSelectionType)
{
return static_cast<RawSelectionType>(aSelectionType);
}
bool operator &(SelectionType aSelectionType,
RawSelectionType aRawSelectionTypes)
{
return (ToRawSelectionType(aSelectionType) & aRawSelectionTypes) != 0;
}
} // namespace mozilla
//#define DEBUG_SELECTION // uncomment for printf describing every collapse and extend.

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

@ -73,8 +73,6 @@ public:
NS_DECL_NSISELECTION
NS_DECL_NSISELECTIONPRIVATE
virtual Selection* AsSelection() override { return this; }
nsresult EndBatchChangesInternal(int16_t aReason = nsISelectionListener::NO_REASON);
nsIDocument* GetParentObject() const;
@ -520,6 +518,60 @@ public:
};
} // namespace dom
inline bool
IsValidSelectionType(RawSelectionType aRawSelectionType)
{
switch (static_cast<SelectionType>(aRawSelectionType)) {
case SelectionType::eNone:
case SelectionType::eNormal:
case SelectionType::eSpellCheck:
case SelectionType::eIMERawClause:
case SelectionType::eIMESelectedRawClause:
case SelectionType::eIMEConvertedClause:
case SelectionType::eIMESelectedClause:
case SelectionType::eAccessibility:
case SelectionType::eFind:
case SelectionType::eURLSecondary:
case SelectionType::eURLStrikeout:
return true;
default:
return false;
}
}
inline SelectionType
ToSelectionType(RawSelectionType aRawSelectionType)
{
if (!IsValidSelectionType(aRawSelectionType)) {
return SelectionType::eInvalid;
}
return static_cast<SelectionType>(aRawSelectionType);
}
inline RawSelectionType
ToRawSelectionType(SelectionType aSelectionType)
{
return static_cast<RawSelectionType>(aSelectionType);
}
inline RawSelectionType ToRawSelectionType(TextRangeType aTextRangeType)
{
return ToRawSelectionType(ToSelectionType(aTextRangeType));
}
inline bool operator &(SelectionType aSelectionType,
RawSelectionType aRawSelectionTypes)
{
return (ToRawSelectionType(aSelectionType) & aRawSelectionTypes) != 0;
}
} // namespace mozilla
inline mozilla::dom::Selection*
nsISelection::AsSelection()
{
return static_cast<mozilla::dom::Selection*>(this);
}
#endif // mozilla_Selection_h__

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

@ -2476,6 +2476,17 @@ WarnIfSandboxIneffective(nsIDocShell* aDocShell,
}
}
bool
nsDocument::IsSynthesized() {
nsCOMPtr<nsIHttpChannelInternal> internalChan = do_QueryInterface(mChannel);
bool synthesized = false;
if (internalChan) {
DebugOnly<nsresult> rv = internalChan->GetResponseSynthesized(&synthesized);
MOZ_ASSERT(NS_SUCCEEDED(rv), "GetResponseSynthesized shouldn't fail.");
}
return synthesized;
}
nsresult
nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
nsILoadGroup* aLoadGroup,
@ -2546,6 +2557,19 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
}
}
if (mChannel) {
nsLoadFlags loadFlags;
mChannel->GetLoadFlags(&loadFlags);
bool isDocument = false;
mChannel->GetIsDocument(&isDocument);
if (loadFlags & nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE &&
isDocument &&
IsSynthesized() &&
XRE_IsContentProcess()) {
ContentChild::UpdateCookieStatus(mChannel);
}
}
// If this document is being loaded by a docshell, copy its sandbox flags
// to the document, and store the fullscreen enabled flag. These are
// immutable after being set here.
@ -8280,7 +8304,11 @@ nsDocument::AddToRadioGroup(const nsAString& aName,
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
NS_ASSERTION(element, "radio controls have to be content elements");
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
HTMLInputElement* input = HTMLInputElement::FromContent(element);
NS_ASSERTION(input, "radio controls have to be input elements!");
if (input->IsRequired()) {
radioGroup->mRequiredRadioCount++;
}
}
@ -8294,7 +8322,11 @@ nsDocument::RemoveFromRadioGroup(const nsAString& aName,
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
NS_ASSERTION(element, "radio controls have to be content elements");
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
HTMLInputElement* input = HTMLInputElement::FromContent(element);
NS_ASSERTION(input, "radio controls have to be input elements!");
if (input->IsRequired()) {
NS_ASSERTION(radioGroup->mRequiredRadioCount != 0,
"mRequiredRadioCount about to wrap below 0!");
radioGroup->mRequiredRadioCount--;

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

@ -667,6 +667,7 @@ public:
virtual void ScheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG) override;
virtual void UnscheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG) override;
virtual void ResolveScheduledSVGPresAttrs() override;
bool IsSynthesized();
private:
void AddOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet);

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

@ -161,10 +161,11 @@ interface nsISelection : nsISupports
%{C++
/**
* AsSelection() returns a pointer to Selection class if the instance is
* derived from it. Otherwise, nullptr but it should never happen
* since Selection is the only class implementing nsISelection.
* AsSelection() returns a pointer to Selection class.
*
* In order to avoid circular dependency issues, this method is defined
* in mozilla/dom/Selection.h. Consumers need to #include that header.
*/
virtual mozilla::dom::Selection* AsSelection() = 0;
inline mozilla::dom::Selection* AsSelection();
%}
};

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

@ -8,6 +8,11 @@
%{C++
typedef short SelectionRegion;
namespace mozilla {
namespace dom {
class Selection;
} // namespace dom
} // namespace mozilla
%}
interface nsIContent;
@ -15,6 +20,8 @@ interface nsIDOMNode;
interface nsISelection;
interface nsISelectionDisplay;
[ptr] native SelectionPtr(mozilla::dom::Selection);
[scriptable, uuid(3801c9d4-8e69-4bfc-9edb-b58278621f8f)]
interface nsISelectionController : nsISelectionDisplay
{
@ -64,6 +71,11 @@ interface nsISelectionController : nsISelectionDisplay
*/
nsISelection getSelection(in short type);
/**
* Return the selection object corresponding to a selection type.
*/
[noscript,nostdcall,notxpcom] SelectionPtr getDOMSelection(in short aType);
const short SCROLL_SYNCHRONOUS = 1<<1;
const short SCROLL_FIRST_ANCESTOR_ONLY = 1<<2;
const short SCROLL_CENTER_VERTICALLY = 1<<4;
@ -312,11 +324,12 @@ enum : size_t
kPresentSelectionTypeCount = kSelectionTypeCount - 1
};
// Please include mozilla/dom/Selection.h for the following APIs.
const char* ToChar(SelectionType aSelectionType);
SelectionType ToSelectionType(RawSelectionType aRawSelectionType);
RawSelectionType ToRawSelectionType(SelectionType aSelectionType);
bool operator &(SelectionType aSelectionType,
RawSelectionType aRawSelectionTypes);
inline SelectionType ToSelectionType(RawSelectionType aRawSelectionType);
inline RawSelectionType ToRawSelectionType(SelectionType aSelectionType);
inline bool operator &(SelectionType aSelectionType,
RawSelectionType aRawSelectionTypes);
} // namespace mozilla
%}

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

@ -0,0 +1,3 @@
document.write("<p></p>");
parent.done();
document.close();

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

@ -457,6 +457,7 @@ skip-if = toolkit == 'android' #TIMED_OUT
[test_bug514487.html]
[test_bug515401.html]
[test_bug518104.html]
support-files = file_bug518104.js
[test_bug527896.html]
[test_bug540854.html]
[test_bug541937.html]

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

@ -26,9 +26,7 @@ function done() {
</script>
<div id="content" style="display: none">
<iframe id='iframe' src="data:text/html,
<div></div><div></div>
<script defer src='data:application/javascript,document.write(%2522<p></p>%2522);parent.done();document.close();'></script>">
<iframe id='iframe' srcdoc="<div></div><div></div><script defer src='file_bug518104.js'></script>">
</iframe>
</div>
<pre id="test">

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

@ -0,0 +1 @@
OLD

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

@ -0,0 +1 @@
NEW

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

@ -25,6 +25,9 @@ skip-if = debug == false
[test_bug1041646.html]
[test_bug1123875.html]
[test_barewordGetsWindow.html]
support-files =
file_barewordGetsWindow_frame1.html
file_barewordGetsWindow_frame2.html
[test_callback_across_document_open.html]
[test_callback_default_thisval.html]
[test_cloneAndImportNode.html]

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

@ -27,20 +27,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=936056
var qualifiedFunc = frames[0].eval("(function (count) { var doc; for (var i = 0; i < count; ++i) doc = window.document; return doc.documentElement; })");
document.querySelector("iframe").onload = function () {
// interp
is(barewordFunc(1).textContent, "OLD", "Bareword should see own inner 1");
is(qualifiedFunc(1).textContent, "NEW",
is(barewordFunc(1).innerText, "OLD", "Bareword should see own inner 1");
is(qualifiedFunc(1).innerText, "NEW",
"Qualified should see current inner 1");
// baseline
is(barewordFunc(100).textContent, "OLD", "Bareword should see own inner 2");
is(qualifiedFunc(100).textContent, "NEW",
is(barewordFunc(100).innerText, "OLD", "Bareword should see own inner 2");
is(qualifiedFunc(100).innerText, "NEW",
"Qualified should see current inner 2");
// ion
is(barewordFunc(10000).textContent, "OLD", "Bareword should see own inner 3");
is(qualifiedFunc(10000).textContent, "NEW",
is(barewordFunc(10000).innerText, "OLD", "Bareword should see own inner 3");
is(qualifiedFunc(10000).innerText, "NEW",
"Qualified should see current inner 2");
SimpleTest.finish();
}
frames[0].location = "data:text/plain,NEW";
frames[0].location = "file_barewordGetsWindow_frame2.html";
}
@ -52,7 +52,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=936056
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=936056">Mozilla Bug 936056</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe src="data:text/plain,OLD"></iframe>
<iframe src="file_barewordGetsWindow_frame1.html"></iframe>
</div>
<pre id="test">
</pre>

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

@ -47,5 +47,6 @@ function runTest() {
// Disable third-party cookies for this test.
addEventListener('testready', function() {
SpecialPowers.pushPrefEnv({'set': [['network.cookie.cookieBehavior', 1]]}, runTest);
SpecialPowers.pushPrefEnv({'set': [['network.cookie.cookieBehavior', 1],
['network.cookie.ipc.sync', true]]}, runTest);
});

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

@ -490,7 +490,7 @@ void
EventStateManager::TryToFlushPendingNotificationsToIME()
{
if (mIMEContentObserver) {
mIMEContentObserver->TryToFlushPendingNotifications();
mIMEContentObserver->TryToFlushPendingNotifications(true);
}
}

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

@ -330,6 +330,8 @@ private:
#define DISABLED_STATES (NS_EVENT_STATE_DISABLED | NS_EVENT_STATE_ENABLED)
#define REQUIRED_STATES (NS_EVENT_STATE_REQUIRED | NS_EVENT_STATE_OPTIONAL)
// Event states that can be added and removed through
// Element::{Add,Remove}ManuallyManagedStates.
//
@ -350,6 +352,7 @@ private:
MANUALLY_MANAGED_STATES | \
DIR_ATTR_STATES | \
DISABLED_STATES | \
REQUIRED_STATES | \
NS_EVENT_STATE_ACTIVE | \
NS_EVENT_STATE_DRAGOVER | \
NS_EVENT_STATE_FOCUS | \

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

@ -1739,10 +1739,10 @@ IMEContentObserver::FlushMergeableNotifications()
}
void
IMEContentObserver::TryToFlushPendingNotifications()
IMEContentObserver::TryToFlushPendingNotifications(bool aAllowAsync)
{
if (!mQueuedSender || mSendingNotification != NOTIFY_IME_OF_NOTHING ||
XRE_IsContentProcess()) {
(XRE_IsContentProcess() && aAllowAsync)) {
return;
}

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

@ -155,9 +155,9 @@ public:
* TryToFlushPendingNotifications() should be called when pending events
* should be flushed. This tries to run the queued IMENotificationSender.
* Doesn't do anything in child processes where flushing happens
* asynchronously.
* asynchronously unless aAllowAsync is false.
*/
void TryToFlushPendingNotifications();
void TryToFlushPendingNotifications(bool aAllowAsync);
/**
* MaybeNotifyCompositionEventHandled() posts composition event handled

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

@ -652,7 +652,7 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
(" OnChangeFocusInternal(), an "
"IMEContentObserver instance is created for plugin and trying to "
"flush its pending notifications..."));
sActiveIMEContentObserver->TryToFlushPendingNotifications();
sActiveIMEContentObserver->TryToFlushPendingNotifications(false);
}
}
@ -827,7 +827,7 @@ IMEStateManager::OnFocusInEditor(nsPresContext* aPresContext,
MOZ_LOG(sISMLog, LogLevel::Debug,
(" OnFocusInEditor(), new IMEContentObserver is "
"created, trying to flush pending notifications..."));
sActiveIMEContentObserver->TryToFlushPendingNotifications();
sActiveIMEContentObserver->TryToFlushPendingNotifications(false);
}
}

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

@ -2314,7 +2314,10 @@ HTMLFormElement::AddToRadioGroup(const nsAString& aName,
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
NS_ASSERTION(element, "radio controls have to be content elements!");
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
HTMLInputElement* input = HTMLInputElement::FromContent(element);
NS_ASSERTION(input, "radio controls have to be input elements!");
if (input->IsRequired()) {
auto entry = mRequiredRadioButtonCounts.LookupForAdd(aName);
if (!entry) {
entry.OrInsert([]() { return 1; });
@ -2329,9 +2332,12 @@ HTMLFormElement::RemoveFromRadioGroup(const nsAString& aName,
nsIFormControl* aRadio)
{
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
NS_ASSERTION(element, "radio controls have to be content elements!");
NS_ASSERTION(element, "radio controls have to be content elements");
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
HTMLInputElement* input = HTMLInputElement::FromContent(element);
NS_ASSERTION(input, "radio controls have to be input elements!");
if (input->IsRequired()) {
auto entry = mRequiredRadioButtonCounts.Lookup(aName);
if (!entry) {
MOZ_ASSERT_UNREACHABLE("At least one radio button has to be required!");

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

@ -1453,6 +1453,13 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
UpdateDisabledState(aNotify);
}
if (aName == nsGkAtoms::required && DoesRequiredApply()) {
// This *has* to be called *before* UpdateValueMissingValidityState
// because UpdateValueMissingValidityState depends on our required
// state.
UpdateRequiredState(!!aValue, aNotify);
}
UpdateValueMissingValidityState();
// This *has* to be called *after* validity has changed.
@ -5005,6 +5012,17 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType, bool aNotify)
mFocusedValue.Truncate();
}
// Update or clear our required states since we may have changed from a
// required input type to a non-required input type or viceversa.
if (DoesRequiredApply()) {
bool isRequired = HasAttr(kNameSpaceID_None, nsGkAtoms::required);
UpdateRequiredState(isRequired, aNotify);
} else if (aNotify) {
RemoveStates(REQUIRED_STATES);
} else {
RemoveStatesSilently(REQUIRED_STATES);
}
UpdateHasRange();
// Do not notify, it will be done after if needed.
@ -6554,12 +6572,6 @@ HTMLInputElement::IntrinsicState() const
state |= nsImageLoadingContent::ImageState();
}
if (DoesRequiredApply() && HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
state |= NS_EVENT_STATE_REQUIRED;
} else {
state |= NS_EVENT_STATE_OPTIONAL;
}
if (IsCandidateForConstraintValidation()) {
if (IsValid()) {
state |= NS_EVENT_STATE_VALID;
@ -7232,6 +7244,9 @@ HTMLInputElement::UpdateTooShortValidityState()
void
HTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
{
MOZ_ASSERT(mType == NS_FORM_INPUT_RADIO,
"This should be called only for radio input types");
bool notify = mDoneCreating;
nsCOMPtr<nsIDOMHTMLInputElement> selection = GetSelectedRadioButton();
@ -7240,7 +7255,7 @@ HTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
// If there is no selection, that might mean the radio is not in a group.
// In that case, we can look for the checked state of the radio.
bool selected = selection || (!aIgnoreSelf && mChecked);
bool required = !aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required);
bool required = !aIgnoreSelf && IsRequired();
bool valueMissing = false;
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
@ -7257,7 +7272,7 @@ HTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
// If the current radio is required and not ignored, we can assume the entire
// group is required.
if (!required) {
required = (aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required))
required = (aIgnoreSelf && IsRequired())
? container->GetRequiredRadioCount(name) - 1
: container->GetRequiredRadioCount(name);
}

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

@ -941,6 +941,22 @@ public:
static void Shutdown();
/**
* Returns if the required attribute applies for the current type.
*/
bool DoesRequiredApply() const;
/**
* Returns the current required state of the element. This function differs
* from Required() in that this function only returns true for input types
* that @required attribute applies and the attribute is set; in contrast,
* Required() returns true whenever @required attribute is set.
*/
bool IsRequired() const
{
return State().HasState(NS_EVENT_STATE_REQUIRED);
}
protected:
virtual ~HTMLInputElement();
@ -1137,11 +1153,6 @@ protected:
*/
bool DoesReadOnlyApply() const;
/**
* Returns if the required attribute applies for the current type.
*/
bool DoesRequiredApply() const;
/**
* Returns if the min and max attributes apply for the current type.
*/

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

@ -1088,7 +1088,7 @@ HTMLSelectElement::IsOptionDisabled(int32_t aIndex, bool* aIsDisabled)
}
bool
HTMLSelectElement::IsOptionDisabled(HTMLOptionElement* aOption)
HTMLSelectElement::IsOptionDisabled(HTMLOptionElement* aOption) const
{
MOZ_ASSERT(aOption);
if (aOption->Disabled()) {
@ -1333,6 +1333,11 @@ HTMLSelectElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
UpdateValueMissingValidityState();
UpdateBarredFromConstraintValidation();
} else if (aName == nsGkAtoms::required) {
// This *has* to be called *before* UpdateValueMissingValidityState
// because UpdateValueMissingValidityState depends on our required
// state.
UpdateRequiredState(!!aValue, aNotify);
UpdateValueMissingValidityState();
} else if (aName == nsGkAtoms::autocomplete) {
// Clear the cached @autocomplete attribute and autocompleteInfo state.
@ -1530,12 +1535,6 @@ HTMLSelectElement::IntrinsicState() const
}
}
if (HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
state |= NS_EVENT_STATE_REQUIRED;
} else {
state |= NS_EVENT_STATE_OPTIONAL;
}
return state;
}
@ -1781,7 +1780,7 @@ HTMLSelectElement::RebuildOptionsArray(bool aNotify)
}
bool
HTMLSelectElement::IsValueMissing()
HTMLSelectElement::IsValueMissing() const
{
if (!Required()) {
return false;

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

@ -211,7 +211,7 @@ public:
}
bool Required() const
{
return GetBoolAttr(nsGkAtoms::required);
return State().HasState(NS_EVENT_STATE_REQUIRED);
}
void SetRequired(bool aVal, ErrorResult& aRv)
{
@ -341,7 +341,7 @@ public:
*/
NS_IMETHOD IsOptionDisabled(int32_t aIndex,
bool* aIsDisabled);
bool IsOptionDisabled(HTMLOptionElement* aOption);
bool IsOptionDisabled(HTMLOptionElement* aOption) const;
/**
* Sets multiple options (or just sets startIndex if select is single)
@ -521,7 +521,7 @@ protected:
// nsIConstraintValidation
void UpdateBarredFromConstraintValidation();
bool IsValueMissing();
bool IsValueMissing() const;
/**
* Get the index of the first option at, under or following the content in

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

@ -958,12 +958,6 @@ HTMLTextAreaElement::IntrinsicState() const
{
EventStates state = nsGenericHTMLFormElementWithState::IntrinsicState();
if (HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
state |= NS_EVENT_STATE_REQUIRED;
} else {
state |= NS_EVENT_STATE_OPTIONAL;
}
if (IsCandidateForConstraintValidation()) {
if (IsValid()) {
state |= NS_EVENT_STATE_VALID;
@ -1114,6 +1108,13 @@ HTMLTextAreaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
UpdateDisabledState(aNotify);
}
if (aName == nsGkAtoms::required) {
// This *has* to be called *before* UpdateValueMissingValidityState
// because UpdateValueMissingValidityState depends on our required
// state.
UpdateRequiredState(!!aValue, aNotify);
}
UpdateValueMissingValidityState();
// This *has* to be called *after* validity has changed.
@ -1218,7 +1219,7 @@ HTMLTextAreaElement::IsTooShort()
bool
HTMLTextAreaElement::IsValueMissing() const
{
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::required) || !IsMutable()) {
if (!Required() || !IsMutable()) {
return false;
}

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

@ -252,9 +252,9 @@ public:
{
SetHTMLBoolAttr(nsGkAtoms::readonly, aReadOnly, aError);
}
bool Required()
bool Required() const
{
return GetBoolAttr(nsGkAtoms::required);
return State().HasState(NS_EVENT_STATE_REQUIRED);
}
void SetRangeText(const nsAString& aReplacement, ErrorResult& aRv);
@ -410,6 +410,7 @@ protected:
void GetSelectionRange(uint32_t* aSelectionStart,
uint32_t* aSelectionEnd,
ErrorResult& aRv);
private:
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
GenericSpecifiedValues* aGenericData);

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

@ -13,7 +13,7 @@
bool
CheckboxInputType::IsValueMissing() const
{
if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
if (!mInputElement->IsRequired()) {
return false;
}

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

@ -41,7 +41,7 @@ DateTimeInputTypeBase::IsMutable() const
bool
DateTimeInputTypeBase::IsValueMissing() const
{
if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
if (!mInputElement->IsRequired()) {
return false;
}

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

@ -11,7 +11,7 @@
bool
FileInputType::IsValueMissing() const
{
if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
if (!mInputElement->IsRequired()) {
return false;
}

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

@ -133,7 +133,7 @@ NumericInputTypeBase::ConvertNumberToString(mozilla::Decimal aValue,
bool
NumberInputType::IsValueMissing() const
{
if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
if (!mInputElement->IsRequired()) {
return false;
}

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

@ -58,7 +58,7 @@ SingleLineTextInputTypeBase::IsTooShort() const
bool
SingleLineTextInputTypeBase::IsValueMissing() const
{
if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
if (!mInputElement->IsRequired()) {
return false;
}

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

@ -109,6 +109,7 @@
#include "mozilla/StyleSetHandleInlines.h"
#include "ReferrerPolicy.h"
#include "mozilla/dom/HTMLLabelElement.h"
#include "mozilla/dom/HTMLInputElement.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -2425,6 +2426,40 @@ void nsGenericHTMLFormElement::UpdateDisabledState(bool aNotify)
}
}
void
nsGenericHTMLFormElement::UpdateRequiredState(bool aIsRequired, bool aNotify)
{
#ifdef DEBUG
int32_t type = ControlType();
#endif
MOZ_ASSERT((type & NS_FORM_INPUT_ELEMENT) ||
type == NS_FORM_SELECT ||
type == NS_FORM_TEXTAREA,
"This should be called only on types that @required applies");
#ifdef DEBUG
HTMLInputElement* input = HTMLInputElement::FromContent(this);
if (input) {
MOZ_ASSERT(input->DoesRequiredApply(),
"This should be called only on input types that @required applies");
}
#endif
EventStates requiredStates;
if (aIsRequired) {
requiredStates |= NS_EVENT_STATE_REQUIRED;
} else {
requiredStates |= NS_EVENT_STATE_OPTIONAL;
}
EventStates oldRequiredStates = State() & REQUIRED_STATES;
EventStates changedStates = requiredStates ^ oldRequiredStates;
if (!changedStates.IsEmpty()) {
ToggleStates(changedStates, aNotify);
}
}
void
nsGenericHTMLFormElement::FieldSetDisabledChanged(bool aNotify)
{

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

@ -1101,6 +1101,11 @@ public:
*/
void UpdateDisabledState(bool aNotify);
/**
* Update our required/optional flags to match the given aIsRequired boolean.
*/
void UpdateRequiredState(bool aIsRequired, bool aNotify);
void FieldSetFirstLegendChanged(bool aNotify) {
UpdateFieldSet(aNotify);
}

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

@ -2438,6 +2438,9 @@ nsHTMLDocument::CreateAndAddWyciwygChannel(void)
nsLoadFlags loadFlags = 0;
channel->GetLoadFlags(&loadFlags);
loadFlags |= nsIChannel::LOAD_DOCUMENT_URI;
if (nsDocShell::SandboxFlagsImplyCookies(mSandboxFlags)) {
loadFlags |= nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE;
}
channel->SetLoadFlags(loadFlags);
channel->SetOriginalURI(wcwgURI);

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

@ -296,6 +296,7 @@ public:
NS_IMETHOD GetSelectionFlags(int16_t *aOutEnable) override;
NS_IMETHOD GetSelection(RawSelectionType aRawSelectionType,
nsISelection** aSelection) override;
Selection* GetDOMSelection(RawSelectionType aRawSelectionType) override;
NS_IMETHOD ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
int16_t aRegion, int16_t aFlags) override;
NS_IMETHOD RepaintSelection(RawSelectionType aRawSelectionType) override;
@ -432,6 +433,12 @@ nsTextInputSelectionImpl::GetSelection(RawSelectionType aRawSelectionType,
return NS_OK;
}
Selection*
nsTextInputSelectionImpl::GetDOMSelection(RawSelectionType aRawSelectionType)
{
return GetSelection(ToSelectionType(aRawSelectionType));
}
NS_IMETHODIMP
nsTextInputSelectionImpl::ScrollSelectionIntoView(
RawSelectionType aRawSelectionType,

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

@ -61,6 +61,7 @@
#include "mozilla/layout/RenderFrameChild.h"
#include "mozilla/loader/ScriptCacheActors.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/net/CookieServiceChild.h"
#include "mozilla/net/CaptivePortalService.h"
#include "mozilla/plugins/PluginInstanceParent.h"
#include "mozilla/plugins/PluginModuleParent.h"
@ -1947,6 +1948,16 @@ ContentChild::RecvPTestShellConstructor(PTestShellChild* actor)
return IPC_OK();
}
void
ContentChild::UpdateCookieStatus(nsIChannel *aChannel)
{
RefPtr<CookieServiceChild> csChild =
CookieServiceChild::GetSingleton();
NS_ASSERTION(csChild, "Couldn't get CookieServiceChild");
csChild->TrackCookieLoad(aChannel);
}
PScriptCacheChild*
ContentChild::AllocPScriptCacheChild(const FileDescOrError& cacheFile, const bool& wantCacheData)
{

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

@ -7,6 +7,7 @@
#ifndef mozilla_dom_ContentChild_h
#define mozilla_dom_ContentChild_h
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/nsIContentChild.h"
@ -144,6 +145,8 @@ public:
static void AppendProcessId(nsACString& aName);
static void UpdateCookieStatus(nsIChannel *aChannel);
mozilla::ipc::IPCResult
RecvInitContentBridgeChild(Endpoint<PContentBridgeChild>&& aEndpoint) override;
@ -757,7 +760,7 @@ private:
nsClassHashtable<nsUint64HashKey, AnonymousTemporaryFileCallback> mPendingAnonymousTemporaryFiles;
bool mShuttingDown;
mozilla::Atomic<bool> mShuttingDown;
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
};

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

@ -27,6 +27,7 @@
#if defined(XP_WIN) && defined(ACCESSIBILITY)
#include "mozilla/a11y/AccessibleWrap.h"
#endif
#include "mozilla/BasePrincipal.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/DataStorage.h"
@ -80,6 +81,8 @@
#include "mozilla/media/MediaParent.h"
#include "mozilla/Move.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/net/CookieServiceParent.h"
#include "mozilla/net/PCookieServiceParent.h"
#include "mozilla/plugins/PluginBridge.h"
#include "mozilla/Preferences.h"
#include "mozilla/ProcessHangMonitor.h"
@ -108,6 +111,7 @@
#include "nsHashPropertyBag.h"
#include "nsIAlertsService.h"
#include "nsIClipboard.h"
#include "nsICookie.h"
#include "nsContentPermissionHelper.h"
#include "nsIContentProcess.h"
#include "nsICycleCollectorListener.h"
@ -588,6 +592,8 @@ static const char* sObserverTopics[] = {
"cacheservice:empty-cache",
"intl:app-locales-changed",
"intl:requested-locales-changed",
"cookie-changed",
"private-cookie-changed",
};
// PreallocateProcess is called by the PreallocatedProcessManager.
@ -2789,6 +2795,41 @@ ContentParent::Observe(nsISupports* aSubject,
LocaleService::GetInstance()->GetRequestedLocales(requestedLocales);
Unused << SendUpdateRequestedLocales(requestedLocales);
}
else if (!strcmp(aTopic, "cookie-changed") ||
!strcmp(aTopic, "private-cookie-changed")) {
if (!aData) {
return NS_ERROR_UNEXPECTED;
}
PNeckoParent *neckoParent = LoneManagedOrNullAsserts(ManagedPNeckoParent());
if (!neckoParent) {
return NS_OK;
}
PCookieServiceParent *csParent = LoneManagedOrNullAsserts(neckoParent->ManagedPCookieServiceParent());
if (!csParent) {
return NS_OK;
}
auto *cs = static_cast<CookieServiceParent*>(csParent);
if (!nsCRT::strcmp(aData, u"batch-deleted")) {
nsCOMPtr<nsIArray> cookieList = do_QueryInterface(aSubject);
NS_ASSERTION(cookieList, "couldn't get cookie list");
cs->RemoveBatchDeletedCookies(cookieList);
return NS_OK;
}
if (!nsCRT::strcmp(aData, u"cleared")) {
cs->RemoveAll();
return NS_OK;
}
nsCOMPtr<nsICookie> xpcCookie = do_QueryInterface(aSubject);
NS_ASSERTION(xpcCookie, "couldn't get cookie");
if (!nsCRT::strcmp(aData, u"deleted")) {
cs->RemoveCookie(xpcCookie);
} else if ((!nsCRT::strcmp(aData, u"added")) ||
(!nsCRT::strcmp(aData, u"changed"))) {
cs->AddCookie(xpcCookie);
}
}
return NS_OK;
}
@ -5045,6 +5086,17 @@ ContentParent::ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch
ProcessHangMonitor::ForcePaint(mHangMonitorActor, aTabParent, aLayerObserverEpoch);
}
void
ContentParent::UpdateCookieStatus(nsIChannel *aChannel)
{
PNeckoParent *neckoParent = LoneManagedOrNullAsserts(ManagedPNeckoParent());
PCookieServiceParent *csParent = LoneManagedOrNullAsserts(neckoParent->ManagedPCookieServiceParent());
if (csParent) {
auto *cs = static_cast<CookieServiceParent*>(csParent);
cs->TrackCookieLoad(aChannel);
}
}
nsresult
ContentParent::AboutToLoadHttpFtpWyciwygDocumentForChild(nsIChannel* aChannel)
{
@ -5069,6 +5121,14 @@ ContentParent::AboutToLoadHttpFtpWyciwygDocumentForChild(nsIChannel* aChannel)
rv = TransmitPermissionsForPrincipal(principal);
NS_ENSURE_SUCCESS(rv, rv);
nsLoadFlags newLoadFlags;
aChannel->GetLoadFlags(&newLoadFlags);
bool isDocument = false;
aChannel->GetIsDocument(&isDocument);
if (newLoadFlags & nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE && isDocument) {
UpdateCookieStatus(aChannel);
}
return NS_OK;
}

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

@ -346,6 +346,8 @@ public:
bool RequestRunToCompletion();
void UpdateCookieStatus(nsIChannel *aChannel);
bool IsAvailable() const
{
return mIsAvailable;

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

@ -90,7 +90,7 @@ public:
if (!existingBackgroundChild) {
LOG(("No existingBackgroundChild"));
existingBackgroundChild =
ipc::BackgroundChild::SynchronouslyCreateForCurrentThread();
ipc::BackgroundChild::GetOrCreateForCurrentThread();
LOG(("BackgroundChild: %p", existingBackgroundChild));
if (!existingBackgroundChild) {
return NS_ERROR_FAILURE;
@ -130,7 +130,7 @@ GetCamerasChild() {
// At this point we are in the MediaManager thread, and the thread we are
// dispatching to is the specific Cameras IPC thread that was just made
// above, so now we will fire off a runnable to run
// BackgroundChild::SynchronouslyCreateForCurrentThread there, while we
// BackgroundChild::GetOrCreateForCurrentThread there, while we
// block in this thread.
// We block until the following happens in the Cameras IPC thread:
// 1) Creation of PBackground finishes

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

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1386183 - Meta CSP on data: URI iframe should be merged with toplevel CSP</title>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content= "img-src https:"/>
</head>
<body>
<iframe id="dataFrame" onload="doCSPMergeCheck()"
src="data:text/html,<html><head><meta http-equiv='Content-Security-Policy' content='script-src https:'/></head><body>merge csp</body></html>">
</iframe>
<script type="application/javascript">
function doCSPMergeCheck() {
// get the csp in JSON notation from the principal
var frame = document.getElementById("dataFrame");
var principal = SpecialPowers.wrap(frame).contentDocument.nodePrincipal;
var cspOBJ = JSON.parse(principal.cspJSON);
// make sure we got >>two<< policies
var policies = cspOBJ["csp-policies"];
window.parent.postMessage({result: policies.length}, "*");
}
</script>
</body>
</html>

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

@ -216,6 +216,7 @@ support-files =
file_ignore_xfo.html^headers^
file_ro_ignore_xfo.html
file_ro_ignore_xfo.html^headers^
file_data_csp_merge.html
[test_base-uri.html]
[test_blob_data_schemes.html]
@ -307,3 +308,4 @@ tags = mcb
[test_websocket_self.html]
skip-if = toolkit == 'android'
[test_ignore_xfo.html]
[test_data_csp_merge.html]

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

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1386183 - Meta CSP on data: URI iframe should be merged with toplevel CSP</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe style="width:100%;" id="testframe"></iframe>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
/* Description of the test:
* We load an iframe using a meta CSP which includes another iframe
* using a data: URI which also defines a meta CSP. We make sure the
* CSP from the including document gets merged with the data: URI
* CSP and applies to the data: URI iframe.
*/
window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
window.removeEventListener("message", receiveMessage);
// toplevel CSP + data: URI iframe meta CSP => 2 CSP policies
is(event.data.result, 2,
"CSP on data: URI iframe gets merged with CSP from including context");
SimpleTest.finish();
}
document.getElementById("testframe").src = "file_data_csp_merge.html";
</script>
</body>
</html>

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

@ -16,6 +16,7 @@ support-files =
file_bug1224790-1_nonmodal.xul
file_bug1224790-2_modal.xul
file_bug1224790-2_nonmodal.xul
file_popup_blocker_chrome.html
file_subscript_bindings.js
focus_frameset.html
focus_window2.xul

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

@ -0,0 +1,6 @@
<html>
<body onload="window.opener.next()">
foobar
</script>
</body>
</html>

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

@ -20,35 +20,47 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=662519
/** Test for Bug 662519 **/
let w = null;
let steps = [
function() {
w = window.open("file_popup_blocker_chrome.html", "", "width=200,height=200");
ok(w, "The window object shouldn't be null");
// next() is called within file_popup_blocker_chrome.html
},
function() {
w.close();
ok(true, "The popup appeared");
next();
},
function() {
w = window.open("file_popup_blocker_chrome.html", "_blank", "width=200,height=200");
ok(w, "The window object shouldn't be null");
// next() is called within file_popup_blocker_chrome.html
},
function() {
w.close();
ok(true, "The popup appeared");
next();
},
];
function next() {
if (!steps.length) {
SimpleTest.finish();
return;
}
let step = steps.shift();
step();
}
SimpleTest.waitForExplicitFinish();
// We have to enable dom.disable_open_during_load which is disabled
// by the test harness.
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var gLastDomLoadValue = prefs.getBoolPref("dom.disable_open_during_load");
prefs.setBoolPref("dom.disable_open_during_load", true);
let w = window.open("data:text/html,foobar", "", "width=200,height=200");
ok(w, "The window object shouldn't be null");
SimpleTest.waitForFocus(function() {
w.close();
ok(true, "The popup appeared");
SimpleTest.waitForFocus(function() {
let w = window.open("data:text/html,foobar", "", "width=200,height=200");
ok(w, "The window object shouldn't be null");
SimpleTest.waitForFocus(function() {
w.close();
ok(true, "The popup appeared");
prefs.setBoolPref("dom.disable_open_during_load", gLastDomLoadValue);
SimpleTest.finish();
}, w, false);
});
}, w, false);
SpecialPowers.pushPrefEnv({'set': [["dom.disable_open_during_load", true]] }, function() {
next();
});
]]>
</script>
</window>

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

@ -2849,10 +2849,10 @@ WorkerThreadPrimaryRunnable::Run()
profiler_register_thread(threadName.get(), &stackBaseGuess);
// Note: SynchronouslyCreateForCurrentThread() must be called prior to
// Note: GetOrCreateForCurrentThread() must be called prior to
// mWorkerPrivate->SetThread() in order to avoid accidentally consuming
// worker messages here.
if (NS_WARN_IF(!BackgroundChild::SynchronouslyCreateForCurrentThread())) {
if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread())) {
// XXX need to fire an error at parent.
// Failed in creating BackgroundChild: probably in shutdown. Continue to run
// without BackgroundChild created.

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

@ -327,7 +327,7 @@ WorkerThread::Observer::OnProcessNextEvent(nsIThreadInternal* /* aThread */,
// If the PBackground child is not created yet, then we must permit
// blocking event processing to support
// BackgroundChild::SynchronouslyCreateForCurrentThread(). If this occurs
// BackgroundChild::GetOrCreateCreateForCurrentThread(). If this occurs
// then we are spinning on the event queue at the start of
// PrimaryWorkerRunnable::Run() and don't want to process the event in
// mWorkerPrivate yet.

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

@ -23,7 +23,6 @@
#include "InsertTextTransaction.h" // for InsertTextTransaction
#include "JoinNodeTransaction.h" // for JoinNodeTransaction
#include "PlaceholderTransaction.h" // for PlaceholderTransaction
#include "SetTextTransaction.h" // for SetTextTransaction
#include "SplitNodeTransaction.h" // for SplitNodeTransaction
#include "StyleSheetTransactions.h" // for AddStyleSheetTransaction, etc.
#include "TextEditUtils.h" // for TextEditUtils
@ -166,6 +165,8 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(EditorBase)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(EditorBase)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRootElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectionController)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mInlineSpellChecker)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTxnMgr)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIMETextNode)
@ -187,6 +188,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(EditorBase)
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRootElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectionController)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInlineSpellChecker)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTxnMgr)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIMETextNode)
@ -225,7 +228,7 @@ EditorBase::Init(nsIDOMDocument* aDOMDocument,
}
// First only set flags, but other stuff shouldn't be initialized now.
// Don't move this call after initializing mDocumentWeak.
// Don't move this call after initializing mDocument.
// SetFlags() can check whether it's called during initialization or not by
// them. Note that SetFlags() will be called by PostCreate().
#ifdef DEBUG
@ -234,14 +237,13 @@ EditorBase::Init(nsIDOMDocument* aDOMDocument,
SetFlags(aFlags);
NS_ASSERTION(NS_SUCCEEDED(rv), "SetFlags() failed");
nsCOMPtr<nsIDocument> document = do_QueryInterface(aDOMDocument);
mDocumentWeak = document.get();
mDocument = do_QueryInterface(aDOMDocument);
// HTML editors currently don't have their own selection controller,
// so they'll pass null as aSelCon, and we'll get the selection controller
// off of the presshell.
nsCOMPtr<nsISelectionController> selectionController;
if (aSelectionController) {
mSelectionControllerWeak = aSelectionController;
mSelectionController = aSelectionController;
selectionController = aSelectionController;
} else {
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
@ -565,14 +567,14 @@ EditorBase::GetIsDocumentEditable(bool* aIsDocumentEditable)
already_AddRefed<nsIDocument>
EditorBase::GetDocument()
{
nsCOMPtr<nsIDocument> document = mDocumentWeak.get();
nsCOMPtr<nsIDocument> document = mDocument;
return document.forget();
}
already_AddRefed<nsIDOMDocument>
EditorBase::GetDOMDocument()
{
nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(mDocumentWeak);
nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(mDocument);
return domDocument.forget();
}
@ -634,19 +636,6 @@ EditorBase::GetSelectionController(nsISelectionController** aSel)
return NS_OK;
}
already_AddRefed<nsISelectionController>
EditorBase::GetSelectionController()
{
nsCOMPtr<nsISelectionController> selectionController;
if (mSelectionControllerWeak) {
selectionController = mSelectionControllerWeak.get();
} else {
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
selectionController = do_QueryInterface(presShell);
}
return selectionController.forget();
}
NS_IMETHODIMP
EditorBase::DeleteSelection(EDirection aAction,
EStripWrappers aStripWrappers)
@ -667,25 +656,13 @@ EditorBase::GetSelection(SelectionType aSelectionType,
{
NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
*aSelection = nullptr;
nsCOMPtr<nsISelectionController> selcon = GetSelectionController();
nsISelectionController* selcon = GetSelectionController();
if (!selcon) {
return NS_ERROR_NOT_INITIALIZED;
}
return selcon->GetSelection(ToRawSelectionType(aSelectionType), aSelection);
}
Selection*
EditorBase::GetSelection(SelectionType aSelectionType)
{
nsCOMPtr<nsISelection> sel;
nsresult rv = GetSelection(aSelectionType, getter_AddRefs(sel));
if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!sel)) {
return nullptr;
}
return sel->AsSelection();
}
NS_IMETHODIMP
EditorBase::DoTransaction(nsITransaction* aTxn)
{
@ -2378,8 +2355,7 @@ EditorBase::CloneAttributes(Element* aDest,
nsresult
EditorBase::ScrollSelectionIntoView(bool aScrollToAnchor)
{
nsCOMPtr<nsISelectionController> selectionController =
GetSelectionController();
nsISelectionController* selectionController = GetSelectionController();
if (!selectionController) {
return NS_OK;
}
@ -2722,9 +2698,7 @@ nsresult
EditorBase::SetTextImpl(Selection& aSelection, const nsAString& aString,
Text& aCharData)
{
SetTextTransaction transaction(aCharData, aString, *this, &mRangeUpdater);
uint32_t length = aCharData.Length();
const uint32_t length = aCharData.Length();
AutoRules beginRulesSniffing(this, EditAction::setText,
nsIEditor::eNext);
@ -2749,7 +2723,20 @@ EditorBase::SetTextImpl(Selection& aSelection, const nsAString& aString,
// We don't support undo here, so we don't really need all of the transaction
// machinery, therefore we can run our transaction directly, breaking all of
// the rules!
nsresult rv = transaction.DoTransaction();
nsresult rv = aCharData.SetData(aString);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Only set selection to insertion point if editor gives permission
if (GetShouldTxnSetSelection()) {
RefPtr<Selection> selection = GetSelection();
DebugOnly<nsresult> rv = selection->Collapse(&aCharData, length);
NS_ASSERTION(NS_SUCCEEDED(rv),
"Selection could not be collapsed after insert");
}
mRangeUpdater.SelAdjDeleteText(&aCharData, 0, length);
mRangeUpdater.SelAdjInsertText(aCharData, 0, aString);
// Let listeners know what happened
{
@ -5307,8 +5294,7 @@ EditorBase::GetIMESelectionStartOffsetIn(nsINode* aTextNode)
{
MOZ_ASSERT(aTextNode, "aTextNode must not be nullptr");
nsCOMPtr<nsISelectionController> selectionController =
GetSelectionController();
nsISelectionController* selectionController = GetSelectionController();
if (NS_WARN_IF(!selectionController)) {
return -1;
}

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

@ -9,9 +9,11 @@
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
#include "mozilla/Maybe.h" // for Maybe
#include "mozilla/OwningNonNull.h" // for OwningNonNull
#include "mozilla/PresShell.h" // for PresShell
#include "mozilla/SelectionState.h" // for RangeUpdater, etc.
#include "mozilla/StyleSheet.h" // for StyleSheet
#include "mozilla/WeakPtr.h" // for WeakPtr
#include "mozilla/dom/Selection.h"
#include "mozilla/dom/Text.h"
#include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr
#include "nsCycleCollectionParticipant.h"
@ -119,7 +121,6 @@ class InsertTextTransaction;
class JoinNodeTransaction;
class PlaceholderTransaction;
class RemoveStyleSheetTransaction;
class SetTextTransaction;
class SplitNodeTransaction;
class TextComposition;
class TextEditor;
@ -129,7 +130,6 @@ namespace dom {
class DataTransfer;
class Element;
class EventTarget;
class Selection;
class Text;
} // namespace dom
@ -252,7 +252,7 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(EditorBase, nsIEditor)
bool IsInitialized() const { return !!mDocumentWeak; }
bool IsInitialized() const { return !!mDocument; }
already_AddRefed<nsIDOMDocument> GetDOMDocument();
already_AddRefed<nsIDocument> GetDocument();
already_AddRefed<nsIPresShell> GetPresShell();
@ -567,7 +567,21 @@ protected:
*/
bool EnsureComposition(WidgetCompositionEvent* aCompositionEvent);
already_AddRefed<nsISelectionController> GetSelectionController();
nsISelectionController* GetSelectionController() const
{
if (mSelectionController) {
return mSelectionController;
}
if (!mDocument) {
return nullptr;
}
nsIPresShell* presShell = mDocument->GetShell();
if (!presShell) {
return nullptr;
}
nsISelectionController* sc = static_cast<PresShell*>(presShell);
return sc;
}
nsresult GetSelection(SelectionType aSelectionType,
nsISelection** aSelection);
@ -820,7 +834,15 @@ public:
static void DumpNode(nsIDOMNode* aNode, int32_t indent = 0);
#endif
Selection* GetSelection(SelectionType aSelectionType =
SelectionType::eNormal);
SelectionType::eNormal)
{
nsISelectionController* sc = GetSelectionController();
if (!sc) {
return nullptr;
}
Selection* selection = sc->GetDOMSelection(ToRawSelectionType(aSelectionType));
return selection;
}
/**
* Helpers to add a node to the selection.
@ -980,7 +1002,7 @@ public:
bool HasIndependentSelection() const
{
return !!mSelectionControllerWeak;
return !!mSelectionController;
}
bool IsModifiable() const
@ -1105,12 +1127,8 @@ public:
void HideCaret(bool aHide);
private:
// Weak reference to the nsISelectionController.
// Use GetSelectionController() to retrieve actual pointer.
CachedWeakPtr<nsISelectionController> mSelectionControllerWeak;
// Weak reference to the nsIDocument.
// Use GetDocument() to retrieve actual pointer.
CachedWeakPtr<nsIDocument> mDocumentWeak;
nsCOMPtr<nsISelectionController> mSelectionController;
nsCOMPtr<nsIDocument> mDocument;
protected:
enum Tristate

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

@ -4272,8 +4272,7 @@ HTMLEditor::IsVisTextNode(nsIContent* aNode,
uint32_t length = aNode->TextLength();
if (aSafeToAskFrames) {
nsCOMPtr<nsISelectionController> selectionController =
GetSelectionController();
nsISelectionController* selectionController = GetSelectionController();
if (NS_WARN_IF(!selectionController)) {
return NS_ERROR_FAILURE;
}

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

@ -1,67 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* 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 "SetTextTransaction.h"
#include "mozilla/DebugOnly.h" // DebugOnly
#include "mozilla/EditorBase.h" // mEditorBase
#include "mozilla/SelectionState.h" // RangeUpdater
#include "mozilla/dom/Selection.h" // Selection local var
#include "mozilla/dom/Text.h" // mTextNode
#include "nsAString.h" // nsAString parameter
#include "nsDebug.h" // for NS_ASSERTION, etc.
#include "nsError.h" // for NS_OK, etc.
namespace mozilla {
using namespace dom;
SetTextTransaction::SetTextTransaction(Text& aTextNode,
const nsAString& aStringToSet,
EditorBase& aEditorBase,
RangeUpdater* aRangeUpdater)
: mTextNode(&aTextNode)
, mStringToSet(aStringToSet)
, mEditorBase(&aEditorBase)
, mRangeUpdater(aRangeUpdater)
{
}
nsresult
SetTextTransaction::DoTransaction()
{
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
return NS_ERROR_NOT_AVAILABLE;
}
nsresult rv = mTextNode->GetData(mPreviousData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = mTextNode->SetData(mStringToSet);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Only set selection to insertion point if editor gives permission
if (mEditorBase->GetShouldTxnSetSelection()) {
RefPtr<Selection> selection = mEditorBase->GetSelection();
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_NULL_POINTER;
}
DebugOnly<nsresult> rv =
selection->Collapse(mTextNode, mStringToSet.Length());
NS_ASSERTION(NS_SUCCEEDED(rv),
"Selection could not be collapsed after insert");
}
mRangeUpdater->SelAdjDeleteText(mTextNode, 0, mPreviousData.Length());
mRangeUpdater->SelAdjInsertText(*mTextNode, 0, mStringToSet);
return NS_OK;
}
} // namespace mozilla

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

@ -1,61 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* 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_SetTextTransaction_h
#define mozilla_SetTextTransaction_h
#include "mozilla/Attributes.h" // for MOZ_STACK_CLASS
#include "nsString.h" // nsString members
#include "nscore.h" // NS_IMETHOD, nsAString
namespace mozilla {
class EditorBase;
class RangeUpdater;
namespace dom {
class Text;
} // namespace dom
/**
* A fake transaction that inserts text into a content node.
*
* This class mimics a transaction class but it is not intended to be used as one.
*/
class MOZ_STACK_CLASS SetTextTransaction final
{
public:
/**
* @param aTextNode The text content node.
* @param aString The new text to insert.
* @param aEditorBase Used to get and set the selection.
* @param aRangeUpdater The range updater
*/
SetTextTransaction(dom::Text& aTextNode,
const nsAString& aString, EditorBase& aEditorBase,
RangeUpdater* aRangeUpdater);
nsresult DoTransaction();
private:
// The Text node to operate upon.
RefPtr<dom::Text> mTextNode;
// The text to insert into mTextNode at mOffset.
nsString mStringToSet;
// The previous text for undo
nsString mPreviousData;
// The editor, which we'll need to get the selection.
EditorBase* MOZ_NON_OWNING_REF mEditorBase;
RangeUpdater* mRangeUpdater;
};
} // namespace mozilla
#endif // #ifndef mozilla_SetTextTransaction_h

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

@ -840,7 +840,7 @@ TextEditRules::WillSetText(Selection& aSelection,
if (!IsPlaintextEditor() || textEditor->IsIMEComposing() ||
aMaxLength != -1) {
// SetTextTransaction only supports plain text editor without IME.
// SetTextImpl only supports plain text editor without IME.
return NS_OK;
}

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

@ -64,7 +64,6 @@ UNIFIED_SOURCES += [
'JoinNodeTransaction.cpp',
'PlaceholderTransaction.cpp',
'SelectionState.cpp',
'SetTextTransaction.cpp',
'SplitNodeTransaction.cpp',
'StyleSheetTransactions.cpp',
'TextEditor.cpp',

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

@ -90,7 +90,7 @@ skip-if = os == 'android'
[test_bug578771.html]
skip-if = android_version == '18' # bug 1147989
[test_bug586662.html]
skip-if = toolkit == 'android'
skip-if = true # bug 1376382
[test_bug587461.html]
[test_bug590554.html]
[test_bug592592.html]

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

@ -113,12 +113,33 @@ PaintThread::IsOnPaintThread()
void
PaintThread::PaintContentsAsync(CompositorBridgeChild* aBridge,
gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget)
CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback)
{
MOZ_ASSERT(IsOnPaintThread());
MOZ_ASSERT(aCapture);
MOZ_ASSERT(aState);
DrawTarget* target = aState->mTarget;
Matrix oldTransform = target->GetTransform();
target->SetTransform(aState->mTargetTransform);
if (!aCallback(aState)) {
return;
}
// Draw all the things into the actual dest target.
aTarget->DrawCapturedDT(aCapture, Matrix());
target->DrawCapturedDT(aCapture, Matrix());
target->SetTransform(oldTransform);
// Textureclient forces a flush once we "end paint", so
// users of this texture expect all the drawing to be complete.
// Force a flush now.
// TODO: This might be a performance bottleneck because
// main thread painting only does one flush at the end of all paints
// whereas we force a flush after each draw target paint.
target->Flush();
if (aBridge) {
aBridge->NotifyFinishedAsyncPaint();
@ -127,9 +148,12 @@ PaintThread::PaintContentsAsync(CompositorBridgeChild* aBridge,
void
PaintThread::PaintContents(DrawTargetCapture* aCapture,
DrawTarget* aTarget)
CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aCapture);
MOZ_ASSERT(aState);
// If painting asynchronously, we need to acquire the compositor bridge which
// owns the underlying MessageChannel. Otherwise we leave it null and use
@ -140,13 +164,15 @@ PaintThread::PaintContents(DrawTargetCapture* aCapture,
cbc->NotifyBeginAsyncPaint();
}
RefPtr<DrawTargetCapture> capture(aCapture);
RefPtr<DrawTarget> target(aTarget);
RefPtr<CapturedPaintState> state(aState);
RefPtr<PaintThread> self = this;
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents",
[self, cbc, capture, target]() -> void
[self, cbc, capture, state, aCallback]() -> void
{
self->PaintContentsAsync(cbc, capture, target);
self->PaintContentsAsync(cbc, capture,
state,
aCallback);
});
if (cbc) {

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

@ -8,6 +8,7 @@
#define MOZILLA_LAYERS_PAINTTHREAD_H
#include "base/platform_thread.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsThreadUtils.h"
@ -20,6 +21,38 @@ class DrawTargetCapture;
namespace layers {
// Holds the key parts from a RotatedBuffer::PaintState
// required to draw the captured paint state
class CapturedPaintState {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CapturedPaintState)
public:
CapturedPaintState(nsIntRegion& aRegionToDraw,
gfx::DrawTarget* aTarget,
gfx::DrawTarget* aTargetOnWhite,
gfx::Matrix aTargetTransform,
SurfaceMode aSurfaceMode,
gfxContentType aContentType)
: mRegionToDraw(aRegionToDraw)
, mTarget(aTarget)
, mTargetOnWhite(aTargetOnWhite)
, mTargetTransform(aTargetTransform)
, mSurfaceMode(aSurfaceMode)
, mContentType(aContentType)
{}
nsIntRegion mRegionToDraw;
RefPtr<gfx::DrawTarget> mTarget;
RefPtr<gfx::DrawTarget> mTargetOnWhite;
gfx::Matrix mTargetTransform;
SurfaceMode mSurfaceMode;
gfxContentType mContentType;
protected:
virtual ~CapturedPaintState() {}
};
typedef bool (*PrepDrawTargetForPaintingCallback)(CapturedPaintState* aPaintState);
class CompositorBridgeChild;
class PaintThread final
@ -31,7 +64,8 @@ public:
static void Shutdown();
static PaintThread* Get();
void PaintContents(gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget);
CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback);
// Sync Runnables need threads to be ref counted,
// But this thread lives through the whole process.
@ -49,7 +83,8 @@ private:
void InitOnPaintThread();
void PaintContentsAsync(CompositorBridgeChild* aBridge,
gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget);
CapturedPaintState* aState,
PrepDrawTargetForPaintingCallback aCallback);
static StaticAutoPtr<PaintThread> sSingleton;
static StaticRefPtr<nsIThread> sThread;

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

@ -27,6 +27,7 @@
#include "mozilla/gfx/Point.h" // for IntSize
#include "gfx2DGlue.h"
#include "nsLayoutUtils.h" // for invalidation debugging
#include "PaintThread.h"
namespace mozilla {
@ -730,6 +731,77 @@ RotatedContentBuffer::BeginPaint(PaintedLayer* aLayer,
return result;
}
DrawTarget*
RotatedContentBuffer::BorrowDrawTargetForRecording(PaintState& aPaintState,
DrawIterator* aIter /* = nullptr */)
{
if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) {
return nullptr;
}
DrawTarget* result = BorrowDrawTargetForQuadrantUpdate(aPaintState.mRegionToDraw.GetBounds(),
BUFFER_BOTH, aIter);
if (!result) {
return nullptr;
}
ExpandDrawRegion(aPaintState, aIter, result->GetBackendType());
return result;
}
/*static */ bool
RotatedContentBuffer::PrepareDrawTargetForPainting(CapturedPaintState* aState)
{
RefPtr<DrawTarget> target = aState->mTarget;
RefPtr<DrawTarget> whiteTarget = aState->mTargetOnWhite;
if (aState->mSurfaceMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
if (!target || !target->IsValid() ||
!aState->mTargetOnWhite || !aState->mTargetOnWhite->IsValid()) {
// This can happen in release builds if allocating one of the two buffers
// failed. This in turn can happen if unreasonably large textures are
// requested.
return false;
}
for (auto iter = aState->mRegionToDraw.RectIter(); !iter.Done(); iter.Next()) {
const IntRect& rect = iter.Get();
target->FillRect(Rect(rect.x, rect.y, rect.width, rect.height),
ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
whiteTarget->FillRect(Rect(rect.x, rect.y, rect.width, rect.height),
ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
}
} else if (aState->mContentType == gfxContentType::COLOR_ALPHA &&
target->IsValid()) {
// HaveBuffer() => we have an existing buffer that we must clear
for (auto iter = aState->mRegionToDraw.RectIter(); !iter.Done(); iter.Next()) {
const IntRect& rect = iter.Get();
target->ClearRect(Rect(rect.x, rect.y, rect.width, rect.height));
}
}
return true;
}
void
RotatedContentBuffer::ExpandDrawRegion(PaintState& aPaintState,
DrawIterator* aIter,
BackendType aBackendType)
{
nsIntRegion* drawPtr = &aPaintState.mRegionToDraw;
if (aIter) {
// The iterators draw region currently only contains the bounds of the region,
// this makes it the precise region.
aIter->mDrawRegion.And(aIter->mDrawRegion, aPaintState.mRegionToDraw);
drawPtr = &aIter->mDrawRegion;
}
if (aBackendType == BackendType::DIRECT2D ||
aBackendType == BackendType::DIRECT2D1_1) {
// Simplify the draw region to avoid hitting expensive drawing paths
// for complex regions.
drawPtr->SimplifyOutwardByArea(100 * 100);
}
}
DrawTarget*
RotatedContentBuffer::BorrowDrawTargetForPainting(PaintState& aPaintState,
DrawIterator* aIter /* = nullptr */)
@ -744,41 +816,22 @@ RotatedContentBuffer::BorrowDrawTargetForPainting(PaintState& aPaintState,
return nullptr;
}
nsIntRegion* drawPtr = &aPaintState.mRegionToDraw;
if (aIter) {
// The iterators draw region currently only contains the bounds of the region,
// this makes it the precise region.
aIter->mDrawRegion.And(aIter->mDrawRegion, aPaintState.mRegionToDraw);
drawPtr = &aIter->mDrawRegion;
}
if (result->GetBackendType() == BackendType::DIRECT2D ||
result->GetBackendType() == BackendType::DIRECT2D1_1) {
// Simplify the draw region to avoid hitting expensive drawing paths
// for complex regions.
drawPtr->SimplifyOutwardByArea(100 * 100);
}
ExpandDrawRegion(aPaintState, aIter, result->GetBackendType());
if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
if (!mDTBuffer || !mDTBuffer->IsValid() ||
!mDTBufferOnWhite || !mDTBufferOnWhite->IsValid()) {
// This can happen in release builds if allocating one of the two buffers
// failed. This in turn can happen if unreasonably large textures are
// requested.
return nullptr;
}
for (auto iter = drawPtr->RectIter(); !iter.Done(); iter.Next()) {
const IntRect& rect = iter.Get();
mDTBuffer->FillRect(Rect(rect.x, rect.y, rect.width, rect.height),
ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
mDTBufferOnWhite->FillRect(Rect(rect.x, rect.y, rect.width, rect.height),
ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
}
} else if (aPaintState.mContentType == gfxContentType::COLOR_ALPHA && HaveBuffer()) {
// HaveBuffer() => we have an existing buffer that we must clear
for (auto iter = drawPtr->RectIter(); !iter.Done(); iter.Next()) {
const IntRect& rect = iter.Get();
result->ClearRect(Rect(rect.x, rect.y, rect.width, rect.height));
}
nsIntRegion regionToDraw = aIter ? aIter->mDrawRegion
: aPaintState.mRegionToDraw;
// Can't stack allocate refcounted objects.
RefPtr<CapturedPaintState> capturedPaintState =
MakeAndAddRef<CapturedPaintState>(regionToDraw,
mDTBuffer,
mDTBufferOnWhite,
Matrix(),
aPaintState.mMode,
aPaintState.mContentType);
if (!RotatedContentBuffer::PrepareDrawTargetForPainting(capturedPaintState)) {
return nullptr;
}
return result;

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

@ -22,6 +22,10 @@
namespace mozilla {
namespace layers {
class CapturedPaintState;
typedef bool (*PrepDrawTargetForPaintingCallback)(CapturedPaintState*);
class TextureClient;
class PaintedLayer;
@ -293,6 +297,14 @@ public:
gfx::DrawTarget* BorrowDrawTargetForPainting(PaintState& aPaintState,
DrawIterator* aIter = nullptr);
gfx::DrawTarget* BorrowDrawTargetForRecording(PaintState& aPaintState,
DrawIterator* aIter = nullptr);
void ExpandDrawRegion(PaintState& aPaintState,
DrawIterator* aIter,
gfx::BackendType aBackendType);
static bool PrepareDrawTargetForPainting(CapturedPaintState*);
enum {
BUFFER_COMPONENT_ALPHA = 0x02 // Dual buffers should be created for drawing with
// component alpha.

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

@ -25,6 +25,7 @@
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "PaintThread.h"
#include "ReadbackProcessor.h"
#include "RotatedBuffer.h"
namespace mozilla {
namespace layers {
@ -188,6 +189,29 @@ ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUp
}
}
/***
* If we can, let's paint this ClientPaintedLayer's contents off the main thread.
* The essential idea is that we ask the ContentClient for a DrawTarget and record
* the moz2d commands. On the Paint Thread, we replay those commands to the
* destination draw target. There are a couple of lifetime issues here though:
*
* 1) TextureClient owns the underlying buffer and DrawTarget. Because of this
* we have to keep the TextureClient and DrawTarget alive but trick the
* TextureClient into thinking it's already returned the DrawTarget
* since we iterate through different Rects to get DrawTargets*. If
* the TextureClient goes away, the DrawTarget and thus buffer can too.
* 2) When ContentClient::EndPaint happens, it flushes the DrawTarget. We have
* to Reflush on the Paint Thread
* 3) DrawTarget API is NOT thread safe. We get around this by recording
* on the main thread and painting on the paint thread. Logically,
* ClientLayerManager will force a flushed paint and block the main thread
* if we have another transaction. Thus we have a gap between when the main
* thread records, the paint thread paints, and we block the main thread
* from trying to paint again. The underlying API however is NOT thread safe.
* 4) We have both "sync" and "async" OMTP. Sync OMTP means we paint on the main thread
* but block the main thread while the paint thread paints. Async OMTP doesn't block
* the main thread. Sync OMTP is only meant to be used as a debugging tool.
*/
bool
ClientPaintedLayer::PaintOffMainThread()
{
@ -202,7 +226,8 @@ ClientPaintedLayer::PaintOffMainThread()
bool didUpdate = false;
RotatedContentBuffer::DrawIterator iter;
while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) {
// Debug Protip: Change to BorrowDrawTargetForPainting if using sync OMTP.
while (DrawTarget* target = mContentClient->BorrowDrawTargetForRecording(state, &iter)) {
if (!target || !target->IsValid()) {
if (target) {
mContentClient->ReturnDrawTargetToBuffer(target);
@ -210,14 +235,15 @@ ClientPaintedLayer::PaintOffMainThread()
continue;
}
// We don't clear the rect here like WRPaintedBlobLayers do
// because ContentClient already clears the surface for us during BeginPaint.
RefPtr<DrawTargetCapture> captureDT =
Factory::CreateCaptureDrawTarget(target->GetBackendType(),
target->GetSize(),
target->GetFormat());
captureDT->SetTransform(target->GetTransform());
Matrix capturedTransform = target->GetTransform();
captureDT->SetTransform(capturedTransform);
// TODO: Capture AA Flags and reset them in PaintThread
SetAntialiasingFlags(this, captureDT);
SetAntialiasingFlags(this, target);
@ -234,12 +260,23 @@ ClientPaintedLayer::PaintOffMainThread()
ctx = nullptr;
PaintThread::Get()->PaintContents(captureDT, target);
// TODO: Fixup component alpha
DrawTarget* targetOnWhite = nullptr;
RefPtr<CapturedPaintState> capturedState
= MakeAndAddRef<CapturedPaintState>(state.mRegionToDraw,
target, targetOnWhite,
capturedTransform,
state.mMode,
state.mContentType);
PaintThread::Get()->PaintContents(captureDT,
capturedState,
RotatedContentBuffer::PrepareDrawTargetForPainting);
mContentClient->ReturnDrawTargetToBuffer(target);
didUpdate = true;
}
mContentClient->EndPaint(nullptr);
if (didUpdate) {

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

@ -96,7 +96,8 @@ public:
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(RotatedContentBuffer::PaintState& aPaintState,
RotatedContentBuffer::DrawIterator* aIter = nullptr) = 0;
virtual void ReturnDrawTargetToBuffer(gfx::DrawTarget*& aReturned) = 0;
virtual gfx::DrawTarget* BorrowDrawTargetForRecording(RotatedContentBuffer::PaintState& aPaintState,
RotatedContentBuffer::DrawIterator* aIter = nullptr) = 0;
// Called as part of the layers transation reply. Conveys data about our
// buffer(s) from the compositor. If appropriate we should swap references
// to our buffers.
@ -151,6 +152,11 @@ public:
{
return RotatedContentBuffer::BorrowDrawTargetForPainting(aPaintState, aIter);
}
virtual gfx::DrawTarget* BorrowDrawTargetForRecording(PaintState& aPaintState,
RotatedContentBuffer::DrawIterator* aIter = nullptr) override
{
return RotatedContentBuffer::BorrowDrawTargetForRecording(aPaintState, aIter);
}
virtual void ReturnDrawTargetToBuffer(gfx::DrawTarget*& aReturned) override
{
BorrowDrawTarget::ReturnDrawTarget(aReturned);
@ -234,6 +240,11 @@ public:
{
return RotatedContentBuffer::BorrowDrawTargetForPainting(aPaintState, aIter);
}
virtual gfx::DrawTarget* BorrowDrawTargetForRecording(PaintState& aPaintState,
RotatedContentBuffer::DrawIterator* aIter = nullptr) override
{
return RotatedContentBuffer::BorrowDrawTargetForRecording(aPaintState, aIter);
}
virtual void ReturnDrawTargetToBuffer(gfx::DrawTarget*& aReturned) override
{
BorrowDrawTarget::ReturnDrawTarget(aReturned);

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

@ -218,6 +218,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
// This was observed during Tab move between different windows.
NS_WARNING("Created child without a matching parent?");
parent = WebRenderBridgeParent::CreateDestroyed();
parent->AddRef(); // IPDL reference
*aIdNamespace = parent->GetIdNamespace();
*aTextureFactoryIdentifier = TextureFactoryIdentifier(LayersBackend::LAYERS_NONE);
return parent;
@ -228,8 +229,8 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
RefPtr<AsyncImagePipelineManager> holder = root->AsyncImageManager();
RefPtr<CompositorAnimationStorage> animStorage = cbp->GetAnimationStorage();
parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder), Move(animStorage));
parent->AddRef(); // IPDL reference
sIndirectLayerTrees[layersId].mCrossProcessParent = this;
sIndirectLayerTrees[layersId].mWrBridge = parent;
*aTextureFactoryIdentifier = parent->GetTextureFactoryIdentifier();

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

@ -7,6 +7,7 @@
#include "mozilla/layers/WebRenderLayer.h"
#include "UnitTransforms.h"
#include "nsDisplayList.h"
namespace mozilla {
namespace layers {
@ -17,33 +18,6 @@ StackingContextHelper::StackingContextHelper()
// mOrigin remains at 0,0
}
StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
LayerRect aBoundForSC,
LayerPoint aOrigin,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
const nsTArray<wr::WrFilterOp>& aFilters,
const gfx::CompositionOp& aMixBlendMode)
: mBuilder(&aBuilder)
{
wr::LayoutRect scBounds = aParentSC.ToRelativeLayoutRect(aBoundForSC);
if (aTransformPtr) {
mTransform = *aTransformPtr;
}
mBuilder->PushStackingContext(scBounds,
aAnimationsId,
aOpacityPtr,
aTransformPtr,
wr::TransformStyle::Flat,
wr::ToMixBlendMode(aMixBlendMode),
aFilters);
mOrigin = aOrigin;
}
StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
@ -88,6 +62,47 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
mOrigin = aLayer->Bounds().TopLeft();
}
StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
nsDisplayListBuilder* aDisplayListBuilder,
nsDisplayItem* aItem,
nsDisplayList* aDisplayList,
gfx::Matrix4x4Typed<LayerPixel, LayerPixel>* aBoundTransform,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
const nsTArray<wr::WrFilterOp>& aFilters,
const gfx::CompositionOp& aMixBlendMode)
: mBuilder(&aBuilder)
{
nsRect itemBounds = aDisplayList->GetClippedBoundsWithRespectToASR(aDisplayListBuilder, aItem->GetActiveScrolledRoot());
nsRect childrenVisible = aItem->GetVisibleRectForChildren();
nsRect visibleRect = itemBounds.Intersect(childrenVisible);
float appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
LayerRect bounds = ViewAs<LayerPixel>(LayoutDeviceRect::FromAppUnits(visibleRect, appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
if (aBoundTransform && !aBoundTransform->IsIdentity()) {
bounds.MoveTo(aBoundTransform->TransformPoint(bounds.TopLeft()));
}
wr::LayoutRect scBounds = aParentSC.ToRelativeLayoutRect(bounds);
if (aTransformPtr) {
mTransform = *aTransformPtr;
}
mBuilder->PushStackingContext(scBounds,
aAnimationsId,
aOpacityPtr,
aTransformPtr,
wr::TransformStyle::Flat,
wr::ToMixBlendMode(aMixBlendMode),
aFilters);
mOrigin = bounds.TopLeft();
}
StackingContextHelper::~StackingContextHelper()
{
if (mBuilder) {

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

@ -12,6 +12,10 @@
#include "mozilla/webrender/WebRenderTypes.h"
#include "Units.h"
class nsDisplayListBuilder;
class nsDisplayItem;
class nsDisplayList;
namespace mozilla {
namespace layers {
@ -45,8 +49,10 @@ public:
// The constructor for layers-free mode.
StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
LayerRect aBoundForSC,
LayerPoint aOrigin,
nsDisplayListBuilder* aDisplayListBuilder,
nsDisplayItem* aItem,
nsDisplayList* aDisplayList,
gfx::Matrix4x4Typed<LayerPixel, LayerPixel>* aBoundTransform,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,

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

@ -1266,6 +1266,7 @@ gfxDWriteFontList::GetStandardFamilyName(const nsAString& aFontName,
bool
gfxDWriteFontList::FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle,
gfxFloat aDevToCssSize)
{
@ -1282,7 +1283,10 @@ gfxDWriteFontList::FindAndAddFamilies(const nsAString& aFamily,
return false;
}
return gfxPlatformFontList::FindAndAddFamilies(aFamily, aOutput, aStyle,
return gfxPlatformFontList::FindAndAddFamilies(aFamily,
aOutput,
aDeferOtherFamilyNamesLoading,
aStyle,
aDevToCssSize);
}

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

@ -379,6 +379,7 @@ public:
bool FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle = nullptr,
gfxFloat aDevToCssSize = 1.0) override;

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

@ -1483,6 +1483,7 @@ gfxFcPlatformFontList::MakePlatformFont(const nsAString& aFontName,
bool
gfxFcPlatformFontList::FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle,
gfxFloat aDevToCssSize)
{
@ -1565,7 +1566,9 @@ gfxFcPlatformFontList::FindAndAddFamilies(const nsAString& aFamily,
FcStrCmp(substName, sentinelFirstFamily) == 0) {
break;
}
gfxPlatformFontList::FindAndAddFamilies(subst, &cachedFamilies);
gfxPlatformFontList::FindAndAddFamilies(subst,
&cachedFamilies,
aDeferOtherFamilyNamesLoading);
}
// Cache the resulting list, so we don't have to do this again.
@ -1847,7 +1850,8 @@ gfxFcPlatformFontList::FindGenericFamilies(const nsAString& aGeneric,
NS_ConvertUTF8toUTF16 mappedGenericName(ToCharPtr(mappedGeneric));
AutoTArray<gfxFontFamily*,1> genericFamilies;
if (gfxPlatformFontList::FindAndAddFamilies(mappedGenericName,
&genericFamilies)) {
&genericFamilies,
true)) {
MOZ_ASSERT(genericFamilies.Length() == 1,
"expected a single family");
if (!prefFonts->Contains(genericFamilies[0])) {

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

@ -251,6 +251,7 @@ public:
bool FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle = nullptr,
gfxFloat aDevToCssSize = 1.0) override;

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

@ -912,6 +912,7 @@ gfxGDIFontList::MakePlatformFont(const nsAString& aFontName,
bool
gfxGDIFontList::FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle,
gfxFloat aDevToCssSize)
{
@ -928,7 +929,10 @@ gfxGDIFontList::FindAndAddFamilies(const nsAString& aFamily,
return false;
}
return gfxPlatformFontList::FindAndAddFamilies(aFamily, aOutput, aStyle,
return gfxPlatformFontList::FindAndAddFamilies(aFamily,
aOutput,
aDeferOtherFamilyNamesLoading,
aStyle,
aDevToCssSize);
}

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

@ -309,6 +309,7 @@ public:
bool FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle = nullptr,
gfxFloat aDevToCssSize = 1.0) override;

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

@ -106,6 +106,7 @@ public:
bool FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle = nullptr,
gfxFloat aDevToCssSize = 1.0) override;

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

@ -1253,6 +1253,7 @@ static const char kSystemFont_system[] = "-apple-system";
bool
gfxMacPlatformFontList::FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle,
gfxFloat aDevToCssSize)
{
@ -1267,7 +1268,10 @@ gfxMacPlatformFontList::FindAndAddFamilies(const nsAString& aFamily,
return true;
}
return gfxPlatformFontList::FindAndAddFamilies(aFamily, aOutput, aStyle,
return gfxPlatformFontList::FindAndAddFamilies(aFamily,
aOutput,
aDeferOtherFamilyNamesLoading,
aStyle,
aDevToCssSize);
}

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

@ -266,9 +266,11 @@ gfxPlatformFontList::InitFontList()
gfxPlatform::PurgeSkiaFontCache();
CancelInitOtherFamilyNamesTask();
mFontFamilies.Clear();
mOtherFamilyNames.Clear();
mOtherFamilyNamesInitialized = false;
if (mExtraNames) {
mExtraNames->mFullnames.Clear();
mExtraNames->mPostscriptNames.Clear();
@ -304,37 +306,20 @@ gfxPlatformFontList::GenerateFontListKey(const nsAString& aKeyName, nsAString& a
#define OTHERNAMES_TIMEOUT 200
void
gfxPlatformFontList::InitOtherFamilyNames()
gfxPlatformFontList::InitOtherFamilyNames(bool aDeferOtherFamilyNamesLoading)
{
if (mOtherFamilyNamesInitialized) {
return;
}
TimeStamp start = TimeStamp::Now();
bool timedOut = false;
for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
RefPtr<gfxFontFamily>& family = iter.Data();
family->ReadOtherFamilyNames(this);
TimeDuration elapsed = TimeStamp::Now() - start;
if (elapsed.ToMilliseconds() > OTHERNAMES_TIMEOUT) {
timedOut = true;
break;
if (aDeferOtherFamilyNamesLoading) {
if (!mPendingOtherFamilyNameTask) {
RefPtr<mozilla::CancelableRunnable> task = new InitOtherFamilyNamesRunnable();
mPendingOtherFamilyNameTask = task;
NS_IdleDispatchToCurrentThread(task.forget());
}
}
if (!timedOut) {
mOtherFamilyNamesInitialized = true;
}
TimeStamp end = TimeStamp::Now();
Telemetry::AccumulateTimeDelta(Telemetry::FONTLIST_INITOTHERFAMILYNAMES,
start, end);
if (LOG_FONTINIT_ENABLED()) {
TimeDuration elapsed = end - start;
LOG_FONTINIT(("(fontinit) InitOtherFamilyNames took %8.2f ms %s",
elapsed.ToMilliseconds(),
(timedOut ? "timeout" : "")));
} else {
InitOtherFamilyNamesInternal(false);
}
}
@ -367,8 +352,8 @@ gfxPlatformFontList::SearchFamiliesForFaceName(const nsAString& aFaceName)
TimeDuration elapsed = TimeStamp::Now() - start;
if (elapsed.ToMilliseconds() > NAMELIST_TIMEOUT) {
timedOut = true;
break;
timedOut = true;
break;
}
}
@ -697,9 +682,10 @@ gfxPlatformFontList::CheckFamily(gfxFontFamily *aFamily)
return aFamily;
}
bool
bool
gfxPlatformFontList::FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle,
gfxFloat aDevToCssSize)
{
@ -722,7 +708,7 @@ gfxPlatformFontList::FindAndAddFamilies(const nsAString& aFamily,
// although ASCII localized family names are possible they don't occur
// in practice so avoid pulling in names at startup
if (!familyEntry && !mOtherFamilyNamesInitialized && !IsASCII(aFamily)) {
InitOtherFamilyNames();
InitOtherFamilyNames(aDeferOtherFamilyNamesLoading);
familyEntry = mOtherFamilyNames.GetWeak(key);
if (!familyEntry && !mOtherFamilyNamesInitialized) {
// localized family names load timed out, add name to list of
@ -896,7 +882,7 @@ gfxPlatformFontList::ResolveGenericFontNames(
style.language = langGroup;
style.systemFont = false;
AutoTArray<gfxFontFamily*,10> families;
FindAndAddFamilies(genericFamily, &families, &style);
FindAndAddFamilies(genericFamily, &families, true, &style);
for (gfxFontFamily* f : families) {
if (!aGenericFamilies->Contains(f)) {
aGenericFamilies->AppendElement(f);
@ -1495,13 +1481,14 @@ gfxPlatformFontList::LoadFontInfo()
if (done) {
mOtherFamilyNamesInitialized = true;
CancelInitOtherFamilyNamesTask();
mFaceNameListsInitialized = true;
}
return done;
}
void
void
gfxPlatformFontList::CleanupLoader()
{
mFontFamiliesToLoad.Clear();
@ -1522,7 +1509,7 @@ gfxPlatformFontList::CleanupLoader()
if (mOtherNamesMissed) {
for (auto it = mOtherNamesMissed->Iter(); !it.Done(); it.Next()) {
if (FindFamily(it.Get()->GetKey())) {
if (FindFamily(it.Get()->GetKey(), false)) {
forceReflow = true;
ForceGlobalReflow();
break;
@ -1691,5 +1678,72 @@ gfxPlatformFontList::IsFontFamilyWhitelistActive()
return mFontFamilyWhitelistActive;
}
void
gfxPlatformFontList::InitOtherFamilyNamesInternal(bool aDeferOtherFamilyNamesLoading)
{
if (mOtherFamilyNamesInitialized) {
return;
}
if (aDeferOtherFamilyNamesLoading) {
TimeStamp start = TimeStamp::Now();
bool timedOut = false;
for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
RefPtr<gfxFontFamily>& family = iter.Data();
family->ReadOtherFamilyNames(this);
TimeDuration elapsed = TimeStamp::Now() - start;
if (elapsed.ToMilliseconds() > OTHERNAMES_TIMEOUT) {
timedOut = true;
break;
}
}
if (!timedOut) {
mOtherFamilyNamesInitialized = true;
CancelInitOtherFamilyNamesTask();
}
TimeStamp end = TimeStamp::Now();
Telemetry::AccumulateTimeDelta(Telemetry::FONTLIST_INITOTHERFAMILYNAMES,
start, end);
if (LOG_FONTINIT_ENABLED()) {
TimeDuration elapsed = end - start;
LOG_FONTINIT(("(fontinit) InitOtherFamilyNames took %8.2f ms %s",
elapsed.ToMilliseconds(),
(timedOut ? "timeout" : "")));
}
} else {
TimeStamp start = TimeStamp::Now();
for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
RefPtr<gfxFontFamily>& family = iter.Data();
family->ReadOtherFamilyNames(this);
}
mOtherFamilyNamesInitialized = true;
CancelInitOtherFamilyNamesTask();
TimeStamp end = TimeStamp::Now();
Telemetry::AccumulateTimeDelta(Telemetry::FONTLIST_INITOTHERFAMILYNAMES_NO_DEFERRING,
start, end);
if (LOG_FONTINIT_ENABLED()) {
TimeDuration elapsed = end - start;
LOG_FONTINIT(("(fontinit) InitOtherFamilyNames without deferring took %8.2f ms",
elapsed.ToMilliseconds()));
}
}
}
void
gfxPlatformFontList::CancelInitOtherFamilyNamesTask()
{
if (mPendingOtherFamilyNameTask) {
mPendingOtherFamilyNameTask->Cancel();
mPendingOtherFamilyNameTask = nullptr;
}
}
#undef LOG
#undef LOG_ENABLED

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

@ -90,6 +90,8 @@ class gfxUserFontSet;
class gfxPlatformFontList : public gfxFontInfoLoader
{
friend class InitOtherFamilyNamesRunnable;
public:
typedef mozilla::unicode::Script Script;
@ -137,6 +139,7 @@ public:
virtual bool
FindAndAddFamilies(const nsAString& aFamily,
nsTArray<gfxFontFamily*>* aOutput,
bool aDeferOtherFamilyNamesLoading,
gfxFontStyle* aStyle = nullptr,
gfxFloat aDevToCssSize = 1.0);
@ -262,6 +265,42 @@ public:
}
protected:
class InitOtherFamilyNamesRunnable : public mozilla::CancelableRunnable
{
public:
InitOtherFamilyNamesRunnable()
: CancelableRunnable("gfxPlatformFontList::InitOtherFamilyNamesRunnable")
, mIsCanceled(false)
{
}
NS_IMETHOD Run() override
{
if (mIsCanceled) {
return NS_OK;
}
gfxPlatformFontList* fontList = gfxPlatformFontList::PlatformFontList();
if (!fontList) {
return NS_OK;
}
fontList->InitOtherFamilyNamesInternal(true);
return NS_OK;
}
virtual nsresult Cancel() override
{
mIsCanceled = true;
return NS_OK;
}
private:
bool mIsCanceled;
};
class MemoryReporter final : public nsIMemoryReporter
{
~MemoryReporter() {}
@ -318,12 +357,17 @@ protected:
// Convenience method to return the first matching family (if any) as found
// by FindAndAddFamilies().
gfxFontFamily*
FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle = nullptr,
FindFamily(const nsAString& aFamily,
bool aDeferOtherFamilyNamesLoading = true,
gfxFontStyle* aStyle = nullptr,
gfxFloat aDevToCssSize = 1.0)
{
AutoTArray<gfxFontFamily*,1> families;
return FindAndAddFamilies(aFamily, &families, aStyle, aDevToCssSize)
? families[0] : nullptr;
return FindAndAddFamilies(aFamily,
&families,
aDeferOtherFamilyNamesLoading,
aStyle,
aDevToCssSize) ? families[0] : nullptr;
}
// Lookup family name in global family list without substitutions or
@ -374,7 +418,9 @@ protected:
gfxFontFamily* CheckFamily(gfxFontFamily *aFamily);
// initialize localized family names
void InitOtherFamilyNames();
void InitOtherFamilyNames(bool aDeferOtherFamilyNamesLoading);
void InitOtherFamilyNamesInternal(bool aDeferOtherFamilyNamesLoading);
void CancelInitOtherFamilyNamesTask();
// search through font families, looking for a given name, initializing
// facename lists along the way. first checks all families with names
@ -454,6 +500,9 @@ protected:
// flag set after InitOtherFamilyNames is called upon first name lookup miss
bool mOtherFamilyNamesInitialized;
// The pending InitOtherFamilyNames() task.
RefPtr<mozilla::CancelableRunnable> mPendingOtherFamilyNameTask;
// flag set after fullname and Postcript name lists are populated
bool mFaceNameListsInitialized;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше