Merge mozilla-central to mozilla-inbound. a=merge CLOSED TREE

This commit is contained in:
Ciure Andrei 2018-12-15 00:03:24 +02:00
Родитель 1bd05f5530 acfba8e927
Коммит 814adb5c46
44 изменённых файлов: 756 добавлений и 361 удалений

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

@ -3,14 +3,6 @@ build/clang-plugin/.*
# The two templates cannot be formatted
config/gcc-stl-wrapper.template.h
config/msvc-stl-wrapper.template.h
dom/base/test/.*
dom/bindings/test/.*
dom/media/gtest/.*
gfx/testsd/.*
.*/gtest/ExampleStylesheet.h
image/test/.*
ipc/ipdl/test/.*
ipc/testshell/.*
# Generated code
js/src/builtin/intl/TimeZoneDataGenerated.h
@ -35,16 +27,6 @@ layout/style/nsCSSVisitedDependentPropList.h
layout/style/nsDOMCSSValueList.h
layout/style/nsStyleStructList.h
media/mtransport/test/.*
mfbt/tests/.*
storage/test/.*
testing/gtest/.*
tools/profiler/tests/.*
uriloader/exthandler/tests/.*
widget/tests/.*
xpcom/glue/tests/.*
xpcom/tests/.*
# Generated by protobuf
.*/.*.pb.h
.*/.*.pb.cc

10
Cargo.lock сгенерированный
Просмотреть файл

@ -772,7 +772,7 @@ dependencies = [
[[package]]
name = "dwrote"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2933,7 +2933,7 @@ dependencies = [
"core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2961,7 +2961,7 @@ dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2977,7 +2977,7 @@ dependencies = [
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3183,7 +3183,7 @@ dependencies = [
"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
"checksum dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7b46afd0d0bbbea88fc083ea293e40865e26a75ec9d38cf5d05a23ac3e2ffe02"
"checksum dwrote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f0beca78470f26189a662e72afe7a54c625b4feb06b2d36c207ac15319bd57c5"
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
"checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621"
"checksum encoding_c 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "769ecb8b33323998e482b218c0d13cd64c267609023b4b7ec3ee740714c318ee"

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

@ -438,16 +438,59 @@ NS_IMPL_ISUPPORTS(nsScriptSecurityManager, nsIScriptSecurityManager)
///////////////// Security Checks /////////////////
#if defined(DEBUG) && !defined(ANDROID)
static void AssertEvalNotUsingSystemPrincipal(nsIPrincipal* subjectPrincipal,
JSContext* cx) {
if (!nsContentUtils::IsSystemPrincipal(subjectPrincipal)) {
return;
}
if (Preferences::GetBool("security.allow_eval_with_system_principal")) {
return;
}
static StaticAutoPtr<nsTArray<nsCString>> sUrisAllowEval;
JS::AutoFilename scriptFilename;
if (JS::DescribeScriptedCaller(cx, &scriptFilename)) {
if (!sUrisAllowEval) {
sUrisAllowEval = new nsTArray<nsCString>();
nsAutoCString urisAllowEval;
Preferences::GetCString("security.uris_using_eval_with_system_principal",
urisAllowEval);
for (const nsACString& filenameString : urisAllowEval.Split(',')) {
sUrisAllowEval->AppendElement(filenameString);
}
ClearOnShutdown(&sUrisAllowEval);
}
nsAutoCString fileName;
fileName = nsAutoCString(scriptFilename.get());
// Extract file name alone if scriptFilename contains line number
// separated by multiple space delimiters in few cases.
int32_t fileNameIndex = fileName.FindChar(' ');
if (fileNameIndex != -1) {
fileName = Substring(fileName, 0, fileNameIndex);
}
ToLowerCase(fileName);
for (auto& uriEntry : *sUrisAllowEval) {
if (StringEndsWith(fileName, uriEntry)) {
return;
}
}
}
MOZ_ASSERT(false, "do not use eval with system privileges");
}
#endif
bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
JSContext* cx, JS::HandleValue aValue) {
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
#if defined(DEBUG) && !defined(ANDROID)
if (!(Preferences::GetBool("security.allow_eval_with_system_principal"))) {
MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(subjectPrincipal),
"do not use eval with system privileges");
}
AssertEvalNotUsingSystemPrincipal(subjectPrincipal, cx);
#endif
nsCOMPtr<nsIContentSecurityPolicy> csp;

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

@ -37,6 +37,8 @@
--highlighter-font-size: 11px;
--highlighter-infobar-color: hsl(210, 30%, 85%);
--highlighter-marker-color: #000;
--grey-40: #b1b1b3;
}
/**
@ -642,6 +644,33 @@
/* Accessible highlighter */
:-moz-native-anonymous .accessible-infobar {
min-width: unset;
}
:-moz-native-anonymous .accessible-infobar-text {
display: grid;
grid-template-areas:
"role name"
"audit audit";
grid-template-columns: min-content 1fr;
}
:-moz-native-anonymous .accessible-infobar-role {
grid-area: role;
color: #9CDCFE;
}
:-moz-native-anonymous .accessible-infobar-name {
grid-area: name;
}
:-moz-native-anonymous .accessible-infobar-audit {
grid-area: audit;
padding-top: 5px;
padding-bottom: 2px;
}
:-moz-native-anonymous .accessible-bounds {
opacity: 0.6;
fill: #6a5acd;
@ -650,7 +679,17 @@
:-moz-native-anonymous .accessible-infobar-name,
:-moz-native-anonymous .accessible-infobar-audit {
color: var(--highlighter-infobar-color);
max-width: 90%;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty):before {
content: "";
height: 8px;
width: 8px;
display: inline-flex;
background-color: var(--accessibility-highlighter-contrast-ratio-color);
box-shadow: 0 0 0 1px var(--grey-40), 4px 3px var(--accessibility-highlighter-contrast-ratio-bg), 4px 3px 0 1px var(--grey-40);
margin-inline-start: 3px;
margin-inline-end: 9px;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty):after {
@ -676,25 +715,17 @@
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-label,
:-moz-native-anonymous .accessible-infobar-audit #accessible-contrast-ratio-max:not(:empty):before {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-separator:before {
margin-inline-end: 3px;
}
:-moz-native-anonymous .accessible-infobar-audit #accessible-contrast-ratio-max {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-separator:before {
content: "-";
margin-inline-start: 3px;
}
:-moz-native-anonymous .accessible-infobar-audit #accessible-contrast-ratio-max:not(:empty):before {
content: "-";
}
:-moz-native-anonymous .accessible-infobar-name:not(:empty),
:-moz-native-anonymous .accessible-infobar-audit:not(:empty) {
:-moz-native-anonymous .accessible-infobar-name:not(:empty) {
border-inline-start: 1px solid #5a6169;
margin-inline-start: 6px;
padding-inline-start: 6px;
}
:-moz-native-anonymous .accessible-infobar-role {
color: #9CDCFE;
}

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

@ -479,14 +479,13 @@ class ContrastRatio extends AuditReport {
"id": "contrast-ratio-label",
},
prefix: this.prefix,
text: L10N.getStr("accessibility.contrast.ratio.label"),
});
createNode(this.win, {
nodeType: "span",
parent: root,
attributes: {
"class": "contrast-ratio",
"class": "contrast-ratio-error",
"id": "contrast-ratio-error",
},
prefix: this.prefix,
@ -503,6 +502,16 @@ class ContrastRatio extends AuditReport {
prefix: this.prefix,
});
createNode(this.win, {
nodeType: "span",
parent: root,
attributes: {
"class": "contrast-ratio-separator",
"id": "contrast-ratio-separator",
},
prefix: this.prefix,
});
createNode(this.win, {
nodeType: "span",
parent: root,
@ -514,11 +523,14 @@ class ContrastRatio extends AuditReport {
});
}
_fillAndStyleContrastValue(el, value, isLargeText, stringName) {
_fillAndStyleContrastValue(el, { value, isLargeText, color, backgroundColor }) {
value = value.toFixed(2);
const style = getContrastRatioScoreStyle(value, isLargeText);
this.setTextContent(el, stringName ? L10N.getFormatStr(stringName, value) : value);
this.setTextContent(el, value);
el.classList.add(style);
el.setAttribute("style",
`--accessibility-highlighter-contrast-ratio-color: rgba(${color});` +
`--accessibility-highlighter-contrast-ratio-bg: rgba(${backgroundColor});`);
el.removeAttribute("hidden");
}
@ -532,7 +544,7 @@ class ContrastRatio extends AuditReport {
*/
update({ contrastRatio }) {
const els = {};
for (const key of ["label", "min", "max", "error"]) {
for (const key of ["label", "min", "max", "error", "separator"]) {
const el = els[key] = this.getElement(`contrast-ratio-${key}`);
if (["min", "max"].includes(key)) {
["fail", "AA", "AAA"].forEach(className => el.classList.remove(className));
@ -540,6 +552,7 @@ class ContrastRatio extends AuditReport {
}
el.setAttribute("hidden", true);
el.removeAttribute("style");
}
if (!contrastRatio) {
@ -547,6 +560,9 @@ class ContrastRatio extends AuditReport {
}
const { isLargeText, error } = contrastRatio;
this.setTextContent(els.label,
L10N.getFormatStr("accessibility.contrast.ratio.label2",
isLargeText ? L10N.getStr("accessibility.contrast.ratio.large") : ""));
els.label.removeAttribute("hidden");
if (error) {
els.error.removeAttribute("hidden");
@ -554,12 +570,18 @@ class ContrastRatio extends AuditReport {
}
if (contrastRatio.value) {
this._fillAndStyleContrastValue(els.min, contrastRatio.value, isLargeText);
const { value, color, backgroundColor } = contrastRatio;
this._fillAndStyleContrastValue(els.min,
{ value, isLargeText, color, backgroundColor });
return true;
}
this._fillAndStyleContrastValue(els.min, contrastRatio.min, isLargeText);
this._fillAndStyleContrastValue(els.max, contrastRatio.max, isLargeText);
const { min, max, color, backgroundColorMin, backgroundColorMax } = contrastRatio;
this._fillAndStyleContrastValue(els.min,
{ value: min, isLargeText, color, backgroundColor: backgroundColorMin });
els.separator.removeAttribute("hidden");
this._fillAndStyleContrastValue(els.max,
{ value: max, isLargeText, color, backgroundColor: backgroundColorMax });
return true;
}

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

@ -18,6 +18,8 @@ const ACCESSIBLE_BOUNDS_SHEET = "data:text/css;charset=utf-8," + encodeURICompon
--highlighter-bubble-background-color: hsl(214, 13%, 24%);
--highlighter-bubble-border-color: rgba(255, 255, 255, 0.2);
--highlighter-bubble-arrow-size: 8px;
--grey-40: #b1b1b3;
}
.accessible-bounds {
@ -39,7 +41,6 @@ const ACCESSIBLE_BOUNDS_SHEET = "data:text/css;charset=utf-8," + encodeURICompon
position: relative;
left: -50%;
background-color: var(--highlighter-bubble-background-color);
min-width: 75px;
border: 1px solid var(--highlighter-bubble-border-color);
border-radius: 3px;
padding: 5px;
@ -67,16 +68,47 @@ const ACCESSIBLE_BOUNDS_SHEET = "data:text/css;charset=utf-8," + encodeURICompon
}
.accessible-infobar-text {
display: grid;
grid-template-areas:
"role name"
"audit audit";
grid-template-columns: min-content 1fr;
overflow: hidden;
white-space: nowrap;
display: flex;
justify-content: center;
}
.accessible-infobar-role {
color: #9CDCFE;
grid-area: role;
}
.accessible-infobar-name {
grid-area: name;
}
.accessible-infobar-audit {
grid-area: audit;
padding-top: 5px;
padding-bottom: 2px;
}
.accessible-infobar-name,
.accessible-infobar-audit {
color: hsl(210, 30%, 85%);
max-width: 90%;
}
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty):before {
content: "";
height: 8px;
width: 8px;
display: inline-flex;
background-color: var(--accessibility-highlighter-contrast-ratio-color);
box-shadow: 0 0 0 1px var(--grey-40),
4px 3px var(--accessibility-highlighter-contrast-ratio-bg),
4px 3px 0 1px var(--grey-40);
margin-inline-start: 3px;
margin-inline-end: 9px;
}
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty):after {
@ -102,27 +134,19 @@ const ACCESSIBLE_BOUNDS_SHEET = "data:text/css;charset=utf-8," + encodeURICompon
}
.accessible-infobar-audit .accessible-contrast-ratio-label,
.accessible-infobar-audit #accessible-contrast-ratio-max:not(:empty):before {
.accessible-infobar-audit .accessible-contrast-ratio-separator:before {
margin-inline-end: 3px;
}
.accessible-infobar-audit #accessible-contrast-ratio-max {
.accessible-infobar-audit .accessible-contrast-ratio-separator:before {
content: "-";
margin-inline-start: 3px;
}
.accessible-infobar-audit #accessible-contrast-ratio-max:not(:empty):before {
content: "-";
}
.accessible-infobar-name:not(:empty),
.accessible-infobar-audit:not(:empty) {
.accessible-infobar-name:not(:empty) {
border-inline-start: 1px solid #5a6169;
margin-inline-start: 6px;
padding-inline-start: 6px;
}
.accessible-infobar-role {
color: #9CDCFE;
}`);
/**

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

@ -563,8 +563,8 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
* A promise that resolves to a JSON object representing the
* response.
*/
setBreakpoint: function(line, column, condition, noSliding) {
if (this.threadActor.state !== "paused") {
setBreakpoint: function(line, column, condition, noSliding, inNestedLoop) {
if (!inNestedLoop && this.threadActor.state !== "paused") {
const errorObject = {
error: "wrongState",
message: "Cannot set breakpoint while debuggee is running.",

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

@ -80,6 +80,10 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
// server.
this._hiddenBreakpoints = new Map();
// A Set of URLs string to watch for when new sources are found by
// the debugger instance.
this._onLoadBreakpointURLs = new Set();
this.global = global;
this._allEventsListener = this._allEventsListener.bind(this);
@ -96,9 +100,12 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
this._onOpeningRequest = this._onOpeningRequest.bind(this);
EventEmitter.on(this._parent, "window-ready", this._onWindowReady);
// Set a wrappedJSObject property so |this| can be sent via the observer svc
// for the xpcshell harness.
this.wrappedJSObject = this;
if (Services.obs) {
// Set a wrappedJSObject property so |this| can be sent via the observer svc
// for the xpcshell harness.
this.wrappedJSObject = this;
Services.obs.notifyObservers(this, "devtools-thread-instantiated");
}
},
// Used by the ObjectActor to keep track of the depth of grip() calls.
@ -306,6 +313,17 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
}
},
/**
* Tell the thread to automatically add a breakpoint on the first line of
* a given file, when it is first loaded.
*
* This is currently only used by the xpcshell test harness, and unless
* we decide to expand the scope of this feature, we should keep it that way.
*/
setBreakpointOnLoad(urls) {
this._onLoadBreakpointURLs = new Set(urls);
},
_findXHRBreakpointIndex(p, m) {
return this._xhrBreakpoints.findIndex(
({ path, method }) => path === p && method === m);
@ -2017,6 +2035,12 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
}
}
if (this._onLoadBreakpointURLs.has(source.url)) {
this.unsafeSynchronize(
sourceActor.setBreakpoint(1, undefined, undefined, undefined, true)
);
}
this._debuggerSourcesSeen.add(source);
return true;
},

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

@ -196,18 +196,27 @@ function getContrastRatioFor(node, options = {}) {
if (rgba.value) {
return {
value: colorUtils.calculateContrastRatio(rgba.value, color),
color,
backgroundColor: rgba.value,
isLargeText,
};
}
// calculateContrastRatio modifies the array, since we need to use color array twice,
// pass its copy to the method.
const min = colorUtils.calculateContrastRatio(rgba.min, Array.from(color));
const max = colorUtils.calculateContrastRatio(rgba.max, Array.from(color));
let min = colorUtils.calculateContrastRatio(rgba.min, color);
let max = colorUtils.calculateContrastRatio(rgba.max, color);
// Flip minimum and maximum contrast ratios if necessary.
if (min > max) {
[min, max] = [max, min];
[rgba.min, rgba.max] = [rgba.max, rgba.min];
}
return {
min: min < max ? min : max,
max: min < max ? max : min,
min,
max,
color,
backgroundColorMin: rgba.min,
backgroundColorMax: rgba.max,
isLargeText,
};
}

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

@ -1197,6 +1197,10 @@ function blendColors(foregroundColor, backgroundColor = [ 255, 255, 255, 1 ]) {
* @return {Number} The calculated luminance.
*/
function calculateContrastRatio(backgroundColor, textColor) {
// Do not modify given colors.
backgroundColor = Array.from(backgroundColor);
textColor = Array.from(textColor);
backgroundColor = blendColors(backgroundColor);
textColor = blendColors(textColor, backgroundColor);

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

@ -11,6 +11,13 @@ accessibility.contrast.ratio=Contrast: %S
# contrast ratio, used when the tool is unable to calculate the contrast ratio value.
accessibility.contrast.ratio.error=Unable to calculate
# LOCALIZATION NOTE (accessibility.contrast.ratio.label): A title text for the color
# contrast ratio description, used together with the actual values.
accessibility.contrast.ratio.label=Contrast:
# LOCALIZATION NOTE (accessibility.contrast.ratio.label2): A title text for the color
# contrast ratio description, used together with the actual values. %S in the
# content will optionally be replaced by the text that indicates that large text is being
# analyzed (see accessibility.contrast.ratio.large).
accessibility.contrast.ratio.label2=Contrast%S:
# LOCALIZATION NOTE (accessibility.contrast.ratio.large): A title text for the color
# contrast ratio that specifies that the color contrast criteria used is if for large
# text.
accessibility.contrast.ratio.large=\u0020(large text)

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

@ -23,7 +23,7 @@ default-features = false
features = ["capture", "serialize_program"]
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.6.2"
dwrote = "0.6.3"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.6"

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

@ -1 +1 @@
22f3f356ea1a9fe2760cd4a609cba78614e428c4
d2c673ada607f29846c3d1ac8ca7d2b272ba1b2d

10
gfx/wr/Cargo.lock сгенерированный
Просмотреть файл

@ -362,7 +362,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "dwrote"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1541,7 +1541,7 @@ dependencies = [
"core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1593,7 +1593,7 @@ dependencies = [
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1672,7 +1672,7 @@ dependencies = [
"core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
"font-loader 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1800,7 +1800,7 @@ dependencies = [
"checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
"checksum downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "18df8ce4470c189d18aa926022da57544f31e154631eb4cfe796aea97051fe6c"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7b46afd0d0bbbea88fc083ea293e40865e26a75ec9d38cf5d05a23ac3e2ffe02"
"checksum dwrote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f0beca78470f26189a662e72afe7a54c625b4feb06b2d36c207ac15319bd57c5"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a"
"checksum euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dbbf962bb6f877239a34491f2e0a12c6b824f389bc789eb90f1d70d4780b0727"

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

@ -74,7 +74,7 @@ rand = "0.4"
freetype = { version = "0.4", default-features = false }
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.6.2"
dwrote = "0.6.3"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.6"

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

@ -156,17 +156,6 @@ pub struct DisplayListFlattener<'a> {
/// The root picture index for this flattener. This is the picture
/// to start the culling phase from.
pub root_pic_index: PictureIndex,
/// TODO(gw): This is a complete hack that relies on knowledge of
/// what the Gecko display list looks like. It's used
/// for now to work out which scroll root to use to
/// create the picture cache for the content. It's only
/// ever used if picture caching is enabled in the
/// RendererOptions struct. We will need to work out
/// a better API to avoid this, before we enable it
/// for all users. Another alternative is that this
/// will disappear itself when document splitting is used.
picture_cache_scroll_root: Option<SpatialNodeIndex>,
}
impl<'a> DisplayListFlattener<'a> {
@ -204,7 +193,6 @@ impl<'a> DisplayListFlattener<'a> {
clip_store: ClipStore::new(),
resources,
root_pic_index: PictureIndex(0),
picture_cache_scroll_root: None,
};
flattener.push_root(
@ -220,12 +208,6 @@ impl<'a> DisplayListFlattener<'a> {
debug_assert!(flattener.sc_stack.is_empty());
// If picture caching is enabled, splice up the root
// stacking context to enable correct surface caching.
flattener.setup_picture_caching(
root_pipeline_id,
);
new_scene.root_pipeline_id = Some(root_pipeline_id);
new_scene.pipeline_epochs = scene.pipeline_epochs.clone();
new_scene.pipelines = scene.pipelines.clone();
@ -245,7 +227,7 @@ impl<'a> DisplayListFlattener<'a> {
/// content frame is that should get surface caching.
fn setup_picture_caching(
&mut self,
root_pipeline_id: PipelineId,
primitives: &mut Vec<PrimitiveInstance>,
) {
if !self.config.enable_picture_caching {
return;
@ -276,98 +258,102 @@ impl<'a> DisplayListFlattener<'a> {
// most of the content is embedded in its own picture.
//
// See if we found a scroll root for the cached surface root.
if let Some(picture_cache_scroll_root) = self.picture_cache_scroll_root {
// Get the list of existing primitives in the main stacking context.
let mut old_prim_list = mem::replace(
&mut self.prim_store.pictures[self.root_pic_index.0].prim_list,
PrimitiveList::empty(),
// Find the first primitive which has the desired scroll root.
let mut main_scroll_root = None;
let first_index = primitives.iter().position(|instance| {
let scroll_root = self.find_scroll_root(
instance.spatial_node_index,
);
// Find the first primitive which has the desired scroll root.
let first_index = old_prim_list.prim_instances.iter().position(|instance| {
let scroll_root = self.find_scroll_root(
instance.spatial_node_index,
);
if scroll_root == ROOT_SPATIAL_NODE_INDEX {
false
} else {
debug_assert!(main_scroll_root.is_none());
main_scroll_root = Some(scroll_root);
true
}
}).unwrap_or(primitives.len());
scroll_root == picture_cache_scroll_root
}).unwrap_or(old_prim_list.prim_instances.len());
let main_scroll_root = match main_scroll_root {
Some(main_scroll_root) => main_scroll_root,
None => ROOT_SPATIAL_NODE_INDEX,
};
// Split off the preceding primtives.
let mut remaining_prims = old_prim_list.prim_instances.split_off(first_index);
// Get the list of existing primitives in the main stacking context.
let mut old_prim_list = mem::replace(
primitives,
Vec::new(),
);
// Find the first primitive in reverse order that is not the root scroll node.
let last_index = remaining_prims.iter().rposition(|instance| {
let scroll_root = self.find_scroll_root(
instance.spatial_node_index,
);
// Split off the preceding primtives.
let mut remaining_prims = old_prim_list.split_off(first_index);
scroll_root != ROOT_SPATIAL_NODE_INDEX
}).unwrap_or(remaining_prims.len() - 1);
let preceding_prims = old_prim_list.prim_instances;
let trailing_prims = remaining_prims.split_off(last_index + 1);
let prim_list = PrimitiveList::new(
remaining_prims,
&self.resources,
// Find the first primitive in reverse order that is not the root scroll node.
let last_index = remaining_prims.iter().rposition(|instance| {
let scroll_root = self.find_scroll_root(
instance.spatial_node_index,
);
// Now, create a picture with tile caching enabled that will hold all
// of the primitives selected as belonging to the main scroll root.
let prim_key = PrimitiveKey::new(
true,
LayoutSize::zero(),
LayoutRect::max_rect(),
PrimitiveKeyKind::Unused,
);
scroll_root != ROOT_SPATIAL_NODE_INDEX
}).unwrap_or(remaining_prims.len() - 1);
let primitive_data_handle = self.resources
.prim_interner
.intern(&prim_key, || {
PrimitiveSceneData {
prim_relative_clip_rect: LayoutRect::max_rect(),
prim_size: LayoutSize::zero(),
is_backface_visible: true,
}
let preceding_prims = old_prim_list;
let trailing_prims = remaining_prims.split_off(last_index + 1);
let prim_list = PrimitiveList::new(
remaining_prims,
&self.resources,
);
// Now, create a picture with tile caching enabled that will hold all
// of the primitives selected as belonging to the main scroll root.
let prim_key = PrimitiveKey::new(
true,
LayoutSize::zero(),
LayoutRect::max_rect(),
PrimitiveKeyKind::Unused,
);
let primitive_data_handle = self.resources
.prim_interner
.intern(&prim_key, || {
PrimitiveSceneData {
prim_relative_clip_rect: LayoutRect::max_rect(),
prim_size: LayoutSize::zero(),
is_backface_visible: true,
}
);
}
);
let pic_index = self.prim_store.pictures.alloc().init(PicturePrimitive::new_image(
Some(PictureCompositeMode::TileCache { clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0) }),
Picture3DContext::Out,
root_pipeline_id,
None,
true,
RasterSpace::Screen,
prim_list,
picture_cache_scroll_root,
LayoutRect::max_rect(),
&self.clip_store,
));
let pic_index = self.prim_store.pictures.alloc().init(PicturePrimitive::new_image(
Some(PictureCompositeMode::TileCache { clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0) }),
Picture3DContext::Out,
self.scene.root_pipeline_id.unwrap(),
None,
true,
RasterSpace::Screen,
prim_list,
main_scroll_root,
LayoutRect::max_rect(),
&self.clip_store,
));
let instance = PrimitiveInstance::new(
LayoutPoint::zero(),
PrimitiveInstanceKind::Picture {
data_handle: primitive_data_handle,
pic_index: PictureIndex(pic_index)
},
ClipChainId::NONE,
picture_cache_scroll_root,
);
let instance = PrimitiveInstance::new(
LayoutPoint::zero(),
PrimitiveInstanceKind::Picture {
data_handle: primitive_data_handle,
pic_index: PictureIndex(pic_index)
},
ClipChainId::NONE,
main_scroll_root,
);
// This contains the tile caching picture, with preceding and
// trailing primitives outside the main scroll root.
let mut new_prim_list = preceding_prims;
new_prim_list.push(instance);
new_prim_list.extend(trailing_prims);
// Finally, store the sliced primitive list in the root picture.
self.prim_store.pictures[self.root_pic_index.0].prim_list = PrimitiveList::new(
new_prim_list,
&self.resources,
);
}
// This contains the tile caching picture, with preceding and
// trailing primitives outside the main scroll root.
primitives.extend(preceding_prims);
primitives.push(instance);
primitives.extend(trailing_prims);
}
/// Find the spatial node that is the scroll root for a given
@ -556,7 +542,7 @@ impl<'a> DisplayListFlattener<'a> {
self.add_clip_node(info.clip_id, clip_and_scroll_ids, clip_region);
let node_index = self.add_scroll_frame(
self.add_scroll_frame(
info.scroll_frame_id,
info.clip_id,
info.external_id,
@ -566,14 +552,6 @@ impl<'a> DisplayListFlattener<'a> {
info.scroll_sensitivity,
ScrollFrameKind::Explicit,
);
// TODO(gw): See description of picture_cache_scroll_root field for information
// about this temporary hack. What it's trying to identify is the first
// scroll root within the first iframe that we encounter in the display
// list.
if self.picture_cache_scroll_root.is_none() && pipeline_id != self.scene.root_pipeline_id.unwrap() {
self.picture_cache_scroll_root = Some(node_index);
}
}
fn flatten_reference_frame(
@ -1228,6 +1206,9 @@ impl<'a> DisplayListFlattener<'a> {
None
};
let create_tile_cache = is_pipeline_root &&
self.sc_stack.len() == 2;
// Get the transform-style of the parent stacking context,
// which determines if we *might* need to draw this on
// an intermediate surface for plane splitting purposes.
@ -1317,11 +1298,12 @@ impl<'a> DisplayListFlattener<'a> {
should_isolate,
transform_style,
context_3d,
create_tile_cache,
});
}
pub fn pop_stacking_context(&mut self) {
let stacking_context = self.sc_stack.pop().unwrap();
let mut stacking_context = self.sc_stack.pop().unwrap();
// If we encounter a stacking context that is effectively a no-op, then instead
// of creating a picture, just append the primitive list to the parent stacking
@ -1342,6 +1324,12 @@ impl<'a> DisplayListFlattener<'a> {
}
}
if stacking_context.create_tile_cache {
self.setup_picture_caching(
&mut stacking_context.primitives,
);
}
// An arbitrary large clip rect. For now, we don't
// specify a clip specific to the stacking context.
// However, now that they are represented as Picture
@ -2533,6 +2521,9 @@ struct FlattenedStackingContext {
/// Defines the relationship to a preserve-3D hiearachy.
context_3d: Picture3DContext<PrimitiveInstance>,
/// If true, create a tile cache for this stacking context.
create_tile_cache: bool,
}
impl FlattenedStackingContext {
@ -2582,6 +2573,11 @@ impl FlattenedStackingContext {
return false;
}
// If the pipelines are different, we care for purposes of selecting tile caches
if self.pipeline_id != parent.pipeline_id {
return false;
}
// It is redundant!
true
}

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

@ -160,7 +160,9 @@ impl<'a> From<&'a LayoutToWorldTransform> for FontTransform {
}
}
pub const FONT_SIZE_LIMIT: f64 = 1024.0;
// Some platforms (i.e. Windows) may have trouble rasterizing glyphs above this size.
// Ensure glyph sizes are reasonably limited to avoid that scenario.
pub const FONT_SIZE_LIMIT: f64 = 512.0;
#[derive(Clone, Hash, PartialEq, Eq, Debug, Ord, PartialOrd)]
#[cfg_attr(feature = "capture", derive(Serialize))]

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

@ -20,7 +20,7 @@ use gpu_types::{TransformPalette, TransformPaletteId, UvRectKind};
use internal_types::FastHashSet;
use plane_split::{Clipper, Polygon, Splitter};
use prim_store::{PictureIndex, PrimitiveInstance, SpaceMapper, VisibleFace, PrimitiveInstanceKind};
use prim_store::{get_raster_rects, CoordinateSpaceMapping};
use prim_store::{get_raster_rects, CoordinateSpaceMapping, PointKey};
use prim_store::{OpacityBindingStorage, PrimitiveTemplateKind, ImageInstanceStorage, OpacityBindingIndex, SizeKey};
use render_backend::FrameResources;
use render_task::{ClearMode, RenderTask, RenderTaskCacheEntryHandle, TileBlit};
@ -78,7 +78,8 @@ pub type TileRect = TypedRect<i32, TileCoordinate>;
/// The size in device pixels of a cached tile. The currently chosen
/// size is arbitrary. We should do some profiling to find the best
/// size for real world pages.
pub const TILE_SIZE_DP: i32 = 512;
pub const TILE_SIZE_WIDTH: i32 = 1024;
pub const TILE_SIZE_HEIGHT: i32 = 256;
/// Information about the state of a transform dependency.
#[derive(Debug)]
@ -247,13 +248,27 @@ impl Tile {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct TileTransformIndex(u32);
/// Defines a key that uniquely identifies a primitive instance.
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct PrimitiveDescriptor {
/// Uniquely identifies the content of the primitive template.
prim_uid: ItemUid,
/// The origin in local space of this primitive.
origin: PointKey,
/// The first clip in the clip_uids array of clips that affect this tile.
first_clip: u16,
/// The number of clips that affect this primitive instance.
clip_count: u16,
}
/// Uniquely describes the content of this tile, in a way that can be
/// (reasonably) efficiently hashed and compared.
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct TileDescriptor {
/// List of primitive unique identifiers. The uid is guaranteed
/// to uniquely describe the content of the primitive.
pub prim_uids: Vec<ItemUid>,
/// List of primitive instance unique identifiers. The uid is guaranteed
/// to uniquely describe the content of the primitive template, while
/// the other parameters describe the clip chain and instance params.
pub prims: Vec<PrimitiveDescriptor>,
/// List of clip node unique identifiers. The uid is guaranteed
/// to uniquely describe the content of the clip node.
@ -288,7 +303,7 @@ impl TileDescriptor {
raster_transform: TransformKey,
) -> Self {
TileDescriptor {
prim_uids: Vec::new(),
prims: Vec::new(),
clip_uids: Vec::new(),
transform_ids: Vec::new(),
opacity_bindings: Vec::new(),
@ -302,7 +317,7 @@ impl TileDescriptor {
/// Clear the dependency information for a tile, when the dependencies
/// are being rebuilt.
fn clear(&mut self) {
self.prim_uids.clear();
self.prims.clear();
self.clip_uids.clear();
self.transform_ids.clear();
self.transforms.clear();
@ -416,8 +431,8 @@ impl TileCache {
let world_tile_rect = WorldRect::from_floats(
0.0,
0.0,
TILE_SIZE_DP as f32 / frame_context.device_pixel_scale.0,
TILE_SIZE_DP as f32 / frame_context.device_pixel_scale.0,
TILE_SIZE_WIDTH as f32 / frame_context.device_pixel_scale.0,
TILE_SIZE_HEIGHT as f32 / frame_context.device_pixel_scale.0,
);
let local_tile_rect = world_mapper
.unmap(&world_tile_rect)
@ -556,15 +571,32 @@ impl TileCache {
// Get the tile coordinates in the picture space.
let pic_rect = TypedRect::from_untyped(&pic_rect.to_untyped());
let local_pic_rect = pic_rect.translate(&-self.local_origin.to_vector());
let x0 = (local_pic_rect.origin.x / self.local_tile_size.width).floor() as i32;
let y0 = (local_pic_rect.origin.y / self.local_tile_size.height).floor() as i32;
let x1 = ((local_pic_rect.origin.x + local_pic_rect.size.width) / self.local_tile_size.width).ceil() as i32;
let y1 = ((local_pic_rect.origin.y + local_pic_rect.size.height) / self.local_tile_size.height).ceil() as i32;
let (p0, p1) = self.get_tile_coords_for_rect(&pic_rect);
// Update the tile array allocation if needed.
self.reconfigure_tiles_if_required(x0, y0, x1, y1);
self.reconfigure_tiles_if_required(p0.x, p0.y, p1.x, p1.y);
}
/// Get the tile coordinates for a given rectangle.
fn get_tile_coords_for_rect(
&self,
rect: &LayoutRect,
) -> (TileOffset, TileOffset) {
// Translate the rectangle into the virtual tile space
let origin = rect.origin - self.local_origin;
// Get the tile coordinates in the picture space.
let p0 = TileOffset::new(
(origin.x / self.local_tile_size.width).floor() as i32,
(origin.y / self.local_tile_size.height).floor() as i32,
);
let p1 = TileOffset::new(
((origin.x + rect.size.width) / self.local_tile_size.width).ceil() as i32,
((origin.y + rect.size.height) / self.local_tile_size.height).ceil() as i32,
);
(p0, p1)
}
/// Resize the 2D tiles array if needed in order to fit dependencies
@ -692,14 +724,8 @@ impl TileCache {
return;
}
// Translate the rectangle into the virtual tile space
let origin = rect.origin - self.local_origin;
// Get the tile coordinates in the picture space.
let x0 = (origin.x / self.local_tile_size.width).floor() as i32;
let y0 = (origin.y / self.local_tile_size.height).floor() as i32;
let x1 = ((origin.x + rect.size.width) / self.local_tile_size.width).ceil() as i32;
let y1 = ((origin.y + rect.size.height) / self.local_tile_size.height).ceil() as i32;
let (p0, p1) = self.get_tile_coords_for_rect(&rect);
// Build the list of resources that this primitive has dependencies on.
let mut opacity_bindings: SmallVec<[PropertyBindingId; 4]> = SmallVec::new();
@ -795,8 +821,8 @@ impl TileCache {
// Normalize the tile coordinates before adding to tile dependencies.
// For each affected tile, mark any of the primitive dependencies.
for y in y0 - self.tile_rect.origin.y .. y1 - self.tile_rect.origin.y {
for x in x0 - self.tile_rect.origin.x .. x1 - self.tile_rect.origin.x {
for y in p0.y - self.tile_rect.origin.y .. p1.y - self.tile_rect.origin.y {
for x in p0.x - self.tile_rect.origin.x .. p1.x - self.tile_rect.origin.x {
let index = (y * self.tile_rect.size.width + x) as usize;
let tile = &mut self.tiles[index];
@ -835,7 +861,12 @@ impl TileCache {
}
// Update the tile descriptor, used for tile comparison during scene swaps.
tile.descriptor.prim_uids.push(prim_instance.uid());
tile.descriptor.prims.push(PrimitiveDescriptor {
prim_uid: prim_instance.uid(),
origin: prim_instance.prim_origin.into(),
first_clip: tile.descriptor.clip_uids.len() as u16,
clip_count: clip_chain_uids.len() as u16,
});
tile.descriptor.clip_uids.extend_from_slice(&clip_chain_uids);
}
}
@ -2184,8 +2215,8 @@ impl PicturePrimitive {
// we will need to correctly select an opacity
// here and a blend mode in batch.rs.
let descriptor = ImageDescriptor::new(
TILE_SIZE_DP,
TILE_SIZE_DP,
TILE_SIZE_WIDTH,
TILE_SIZE_HEIGHT,
ImageFormat::BGRA8,
true,
false,
@ -2235,8 +2266,8 @@ impl PicturePrimitive {
// Set up the blit command now that we know where the dest
// rect is in the texture cache.
let offset = DeviceIntPoint::new(
(x - dirty_region.tile_offset.x) * TILE_SIZE_DP,
(y - dirty_region.tile_offset.y) * TILE_SIZE_DP,
(x - dirty_region.tile_offset.x) * TILE_SIZE_WIDTH,
(y - dirty_region.tile_offset.y) * TILE_SIZE_HEIGHT,
);
blits.push(TileBlit {

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

@ -253,7 +253,7 @@ impl FontContext {
size: f32,
transform: Option<dwrote::DWRITE_MATRIX>,
bitmaps: bool,
) -> dwrote::GlyphRunAnalysis {
) -> (dwrote::GlyphRunAnalysis, dwrote::DWRITE_TEXTURE_TYPE, dwrote::RECT) {
let face = self.get_font_face(font);
let glyph = key.index() as u16;
let advance = 0.0f32;
@ -282,7 +282,7 @@ impl FontContext {
bitmaps,
);
dwrote::GlyphRunAnalysis::create(
let analysis = dwrote::GlyphRunAnalysis::create(
&glyph_run,
1.0,
transform,
@ -290,7 +290,28 @@ impl FontContext {
dwrite_measure_mode,
0.0,
0.0,
)
);
let texture_type = dwrite_texture_type(font.render_mode);
let bounds = analysis.get_alpha_texture_bounds(texture_type);
// If the bounds are empty, then we might not be able to render the glyph with cleartype.
// Try again with aliased rendering to check if that works instead.
if font.render_mode != FontRenderMode::Mono &&
(bounds.left == bounds.right || bounds.top == bounds.bottom) {
let analysis2 = dwrote::GlyphRunAnalysis::create(
&glyph_run,
1.0,
transform,
dwrote::DWRITE_RENDERING_MODE_ALIASED,
dwrite_measure_mode,
0.0,
0.0,
);
let bounds2 = analysis2.get_alpha_texture_bounds(dwrote::DWRITE_TEXTURE_ALIASED_1x1);
if bounds2.left != bounds2.right && bounds2.top != bounds2.bottom {
return (analysis2, dwrote::DWRITE_TEXTURE_ALIASED_1x1, bounds2);
}
}
(analysis, texture_type, bounds)
}
pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option<u32> {
@ -334,11 +355,7 @@ impl FontContext {
} else {
None
};
let analysis = self.create_glyph_analysis(font, key, size, transform, bitmaps);
let texture_type = dwrite_texture_type(font.render_mode);
let bounds = analysis.get_alpha_texture_bounds(texture_type);
let (_, _, bounds) = self.create_glyph_analysis(font, key, size, transform, bitmaps);
let width = (bounds.right - bounds.left) as i32;
let height = (bounds.bottom - bounds.top) as i32;
@ -373,11 +390,12 @@ impl FontContext {
fn convert_to_bgra(
&self,
pixels: &[u8],
texture_type: dwrote::DWRITE_TEXTURE_TYPE,
render_mode: FontRenderMode,
bitmaps: bool,
) -> Vec<u8> {
match (render_mode, bitmaps) {
(FontRenderMode::Mono, _) => {
match (texture_type, render_mode, bitmaps) {
(dwrote::DWRITE_TEXTURE_ALIASED_1x1, _, _) => {
let mut bgra_pixels: Vec<u8> = vec![0; pixels.len() * 4];
for i in 0 .. pixels.len() {
let alpha = pixels[i];
@ -388,7 +406,18 @@ impl FontContext {
}
bgra_pixels
}
(FontRenderMode::Alpha, _) | (_, true) => {
(_, FontRenderMode::Subpixel, false) => {
let length = pixels.len() / 3;
let mut bgra_pixels: Vec<u8> = vec![0; length * 4];
for i in 0 .. length {
bgra_pixels[i * 4 + 0] = pixels[i * 3 + 2];
bgra_pixels[i * 4 + 1] = pixels[i * 3 + 1];
bgra_pixels[i * 4 + 2] = pixels[i * 3 + 0];
bgra_pixels[i * 4 + 3] = 0xff;
}
bgra_pixels
}
_ => {
let length = pixels.len() / 3;
let mut bgra_pixels: Vec<u8> = vec![0; length * 4];
for i in 0 .. length {
@ -401,17 +430,6 @@ impl FontContext {
}
bgra_pixels
}
(FontRenderMode::Subpixel, false) => {
let length = pixels.len() / 3;
let mut bgra_pixels: Vec<u8> = vec![0; length * 4];
for i in 0 .. length {
bgra_pixels[i * 4 + 0] = pixels[i * 3 + 2];
bgra_pixels[i * 4 + 1] = pixels[i * 3 + 1];
bgra_pixels[i * 4 + 2] = pixels[i * 3 + 0];
bgra_pixels[i * 4 + 3] = 0xff;
}
bgra_pixels
}
}
}
@ -468,13 +486,10 @@ impl FontContext {
None
};
let analysis = self.create_glyph_analysis(font, key, size, transform, bitmaps);
let texture_type = dwrite_texture_type(font.render_mode);
let (analysis, texture_type, bounds) = self.create_glyph_analysis(font, key, size, transform, bitmaps);
let bounds = analysis.get_alpha_texture_bounds(texture_type);
let width = (bounds.right - bounds.left) as i32;
let height = (bounds.bottom - bounds.top) as i32;
// Alpha texture bounds can sometimes return an empty rect
// Such as for spaces
if width == 0 || height == 0 {
@ -482,7 +497,7 @@ impl FontContext {
}
let pixels = analysis.create_alpha_texture(texture_type, bounds);
let mut bgra_pixels = self.convert_to_bgra(&pixels, font.render_mode, bitmaps);
let mut bgra_pixels = self.convert_to_bgra(&pixels, texture_type, font.render_mode, bitmaps);
// These are the default values we use in Gecko.
// We use a gamma value of 2.3 for gdi fonts
@ -509,13 +524,21 @@ impl FontContext {
));
gamma_lut.preblend(&mut bgra_pixels, font.color);
let format = if bitmaps {
GlyphFormat::Bitmap
} else if texture_type == dwrote::DWRITE_TEXTURE_ALIASED_1x1 {
font.get_alpha_glyph_format()
} else {
font.get_glyph_format()
};
GlyphRasterResult::Bitmap(RasterizedGlyph {
left: bounds.left as f32,
top: -bounds.top as f32,
width,
height,
scale: (if bitmaps { scale / y_scale } else { scale }) as f32,
format: if bitmaps { GlyphFormat::Bitmap } else { font.get_glyph_format() },
format,
bytes: bgra_pixels,
})
}

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

@ -29,4 +29,4 @@ core-foundation = "0.6"
core-graphics = "0.17.1"
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.6.2"
dwrote = "0.6.3"

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

@ -39,7 +39,7 @@ headless = [ "osmesa-sys", "osmesa-src" ]
pathfinder = [ "webrender/pathfinder" ]
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.6.2"
dwrote = "0.6.3"
mozangle = {version = "0.1.5", features = ["egl"]}
[target.'cfg(all(unix, not(target_os = "android")))'.dependencies]

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

@ -16,7 +16,7 @@
== decorations.yaml decorations-ref.yaml
fuzzy(1,173) == decorations-suite.yaml decorations-suite.png
== 1658.yaml 1658-ref.yaml
== split-batch.yaml split-batch-ref.yaml
fuzzy(1,5) == split-batch.yaml split-batch-ref.yaml
== shadow-red.yaml shadow-red-ref.yaml
fuzzy(1,735) == shadow-grey.yaml shadow-grey-ref.yaml
fuzzy(1,663) == shadow-grey-transparent.yaml shadow-grey-ref.yaml

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

@ -52,6 +52,9 @@
#include <sys/wait.h>
#include <unistd.h>
#endif
#ifdef XP_LINUX
#include <sys/prctl.h>
#endif
#include "jsapi.h"
#include "jsfriendapi.h"
@ -10935,6 +10938,16 @@ int main(int argc, char** argv, char** envp) {
return EXIT_SUCCESS;
}
/*
* Allow dumping on Linux with the fuzzing flag set, even when running with
* the suid/sgid flag set on the shell.
*/
#ifdef XP_LINUX
if (op.getBoolOption("fuzzing-safe")) {
prctl(PR_SET_DUMPABLE, 1);
}
#endif
#ifdef DEBUG
/*
* Process OOM options as early as possible so that we can observe as many

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

@ -16,6 +16,20 @@ here = os.path.abspath(os.path.dirname(__file__))
setup_args = [False, 'reftest', 'reftest']
@pytest.fixture(scope='module')
def normalize():
"""A function that can take a relative path and append it to the 'files'
directory which contains the data necessary to run these tests.
"""
def inner(path):
if os.path.isabs(path):
return path
return os.path.join(here, 'files', path)
return inner
@pytest.fixture # noqa: F811
def parser(setup_test_harness):
setup_test_harness(*setup_args)
@ -24,20 +38,17 @@ def parser(setup_test_harness):
@pytest.fixture # noqa: F811
def runtests(setup_test_harness, binary, parser):
def get_reftest(setup_test_harness, binary, parser):
setup_test_harness(*setup_args)
runreftest = pytest.importorskip('runreftest')
harness_root = runreftest.SCRIPT_DIRECTORY
buf = StringIO()
build = parser.build_obj
options = vars(parser.parse_args([]))
options.update({
'app': binary,
'focusFilterMode': 'non-needs-focus',
'log_raw': [buf],
'suite': 'reftest',
'specialPowersExtensionPath': os.path.join(harness_root, 'specialpowers'),
})
if not os.path.isdir(build.bindir):
@ -47,6 +58,7 @@ def runtests(setup_test_harness, binary, parser):
'reftestExtensionPath': os.path.join(harness_root, 'reftest'),
'sandboxReadWhitelist': [here, os.environ['PYTHON_TEST_TMP']],
'utilityPath': os.path.join(package_root, 'bin'),
'specialPowersExtensionPath': os.path.join(harness_root, 'specialpowers'),
})
if 'MOZ_FETCHES_DIR' in os.environ:
@ -55,21 +67,43 @@ def runtests(setup_test_harness, binary, parser):
options.update({
'extraProfileFiles': [os.path.join(build.topobjdir, 'dist', 'plugins')],
'sandboxReadWhitelist': [build.topobjdir, build.topsrcdir],
'specialPowersExtensionPath': os.path.join(
build.distdir, 'xpi-stage', 'specialpowers'),
})
def normalize(test):
if os.path.isabs(test):
return test
return os.path.join(here, 'files', test)
def inner(**opts):
options.update(opts)
config = Namespace(**options)
# This is pulled from `runreftest.run_test_harness` minus some error
# checking that isn't necessary in this context. It should stay roughly
# in sync.
reftest = runreftest.RefTest(config.suite)
parser.validate(config, reftest)
config.app = reftest.getFullPath(config.app)
assert os.path.exists(config.app)
if config.xrePath is None:
config.xrePath = os.path.dirname(config.app)
return reftest, config
return inner
@pytest.fixture # noqa: F811
def runtests(get_reftest, normalize):
def inner(*tests, **opts):
assert len(tests) > 0
tests = map(normalize, tests)
opts['tests'] = map(normalize, tests)
options['tests'] = tests
options.update(opts)
buf = StringIO()
opts['log_raw'] = [buf]
reftest, options = get_reftest(**opts)
result = reftest.runTests(options.tests, options)
result = runreftest.run_test_harness(parser, Namespace(**options))
out = json.loads('[' + ','.join(buf.getvalue().splitlines()) + ']')
buf.close()
return result, out

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>scripttest-pass</title>
<script type="text/javascript">
function getTestCases()
{
return [
{ testPassed: (function () { return true; }), testDescription: (function () { return "passed"; }) }
];
}
</script>
</head>
<body>
<h1>scripttest-pass</h1>
</body>
</html>

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

@ -0,0 +1,5 @@
== green.html green.html
!= green.html red.html
load green.html
script scripttest-pass.html
print green.html green.html

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

@ -3,4 +3,5 @@ subsuite=reftest
sequential=true
skip-if = python == 3
[test_reftest_manifest_parser.py]
[test_reftest_output.py]

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

@ -0,0 +1,40 @@
# 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/.
import mozunit
import pytest
@pytest.fixture
def parse(get_reftest, normalize):
output = pytest.importorskip("output")
reftest, options = get_reftest(tests=["dummy"])
reftest._populate_logger(options)
reftest.outputHandler = output.OutputHandler(
reftest.log, options.utilityPath, options.symbolsPath)
def resolve(path):
path = normalize(path)
return "file://{}".format(path)
def inner(*manifests):
assert len(manifests) > 0
manifests = {m: None for m in map(resolve, manifests)}
return reftest.getActiveTests(manifests, options)
return inner
def test_parse_test_types(parse):
tests = parse('types.list')
assert tests[0]['type'] == '=='
assert tests[1]['type'] == '!='
assert tests[2]['type'] == 'load'
assert tests[3]['type'] == 'script'
assert tests[4]['type'] == 'print'
if __name__ == '__main__':
mozunit.main()

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

@ -243,6 +243,8 @@ std::vector<webrtc::VideoStream> VideoStreamFactory::CreateEncoderStreams(
}
streams.push_back(video_stream);
}
MOZ_RELEASE_ASSERT(streams.size(), "Should configure at least one stream");
return streams;
}

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

@ -2656,6 +2656,7 @@ pref("csp.overrule_about_uris_without_csp_whitelist", false);
pref("csp.skip_about_page_has_csp_assert", false);
// assertion flag will be set to false after fixing Bug 1473549
pref("security.allow_eval_with_system_principal", true);
pref("security.uris_using_eval_with_system_principal", "autocomplete.xml,redux.js,react-redux.js,content-task.js,content-task.js,tree.xml,dialog.xml,preferencesbindings.js,wizard.xml,lodash.js,jszip.js,ajv-4.1.1.js,updates.js,setup,jsol.js");
#endif
// Default Content Security Policy to apply to signed contents.

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

@ -959,10 +959,10 @@ public static final ElementName LINE = new ElementName("line", "line",
// CPPONLY: NS_NewHTMLUnknownElement,
// CPPONLY: NS_NewSVGLineElement,
TreeBuilder.OTHER);
public static final ElementName MARQUEE = new ElementName("marquee", "marquee",
// CPPONLY: NS_NewHTMLDivElement,
// CPPONLY: NS_NewSVGUnknownElement,
TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
public static final ElementName MARQUEE = new ElementName("marquee", "marquee",
// CPPONLY: NS_NewHTMLMarqueeElement,
// CPPONLY: NS_NewSVGUnknownElement,
TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
public static final ElementName POLYLINE = new ElementName("polyline", "polyline",
// CPPONLY: NS_NewHTMLUnknownElement,
// CPPONLY: NS_NewSVGPolylineElement,

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

@ -3298,17 +3298,19 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
}
}
String charset = null;
if (start != -1) {
if (end == -1) {
if (charsetState == CHARSET_UNQUOTED) {
end = buffer.length;
} else {
return null;
}
}
charset = Portability.newStringFromBuffer(buffer, start, end
- start
return Portability.newStringFromBuffer(buffer, start, end - start
// CPPONLY: , tb, false
);
}
return charset;
return null;
}
private void checkMetaCharset(HtmlAttributes attributes)

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

@ -2289,15 +2289,18 @@ nsHtml5String nsHtml5TreeBuilder::extractCharsetFromContent(
}
}
charsetloop_end:;
nsHtml5String charset = nullptr;
if (start != -1) {
if (end == -1) {
end = buffer.length;
if (charsetState == CHARSET_UNQUOTED) {
end = buffer.length;
} else {
return nullptr;
}
}
charset = nsHtml5Portability::newStringFromBuffer(buffer, start,
end - start, tb, false);
return nsHtml5Portability::newStringFromBuffer(buffer, start, end - start,
tb, false);
}
return charset;
return nullptr;
}
void nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes) {

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

@ -10,7 +10,7 @@ playback_cls = {
}
def get_playback(config):
def get_playback(config, android_device=None):
tool_name = config.get('playback_tool', None)
if tool_name is None:
LOG.critical("playback_tool name not found in config")
@ -20,4 +20,4 @@ def get_playback(config):
return None
cls = playback_cls.get(tool_name)
return cls(config)
return cls(config, android_device)

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

@ -11,8 +11,9 @@ from abc import ABCMeta, abstractmethod
class Playback(object):
__metaclass__ = ABCMeta
def __init__(self, config):
def __init__(self, config, android_device=None):
self.config = config
self.android_device = android_device
@abstractmethod
def download(self):

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

@ -90,12 +90,13 @@ POLICIES_CONTENT_OFF = '''{
class Mitmproxy(Playback, Python3Virtualenv, TestingMixin, MercurialScript):
def __init__(self, config):
def __init__(self, config, android_device=None):
self.config = config
self.mitmproxy_proc = None
self.mitmdump_path = None
self.recordings = config.get('playback_recordings', None)
self.browser_path = config.get('binary', None)
self.android_device = android_device
# raptor_dir is where we will download all mitmproxy required files
# when running locally it comes from obj_path via mozharness/mach
@ -202,9 +203,15 @@ class Mitmproxy(Playback, Python3Virtualenv, TestingMixin, MercurialScript):
# for google chromium this is not necessary as chromium will be
# started with --ignore-certificate-errors cmd line arg
if self.config['app'] == "firefox":
# install the generated CA certificate into Firefox
self.install_mitmproxy_cert(self.mitmproxy_proc,
self.browser_path)
# install the generated CA certificate into Firefox desktop
self.install_mitmproxy_cert_desktop(self.mitmproxy_proc,
self.browser_path)
elif self.config['app'] == "geckoview":
# install the generated CA certificate into android geckoview
self.install_mitmproxy_cert_android(self.mitmproxy_proc,
self.browser_path)
else:
return
def start(self):
# if on windows, the mitmdump_path was already set when creating py3 env
@ -223,19 +230,14 @@ class Mitmproxy(Playback, Python3Virtualenv, TestingMixin, MercurialScript):
self.turn_off_browser_proxy()
return
def install_mitmproxy_cert(self, mitmproxy_proc, browser_path):
def install_mitmproxy_cert_desktop(self, mitmproxy_proc, browser_path):
"""Install the CA certificate generated by mitmproxy, into Firefox
1. Create a directory called distribution in the same directory as the Firefox executable
2. Create a file called policies.json with:
{
"policies": {
"certificates": {
"Install": ["FULL_PATH_TO_CERT"]
}
}
}
1. Create a dir called 'distribution' in the same directory as the Firefox executable
2. Create the policies.json file inside that folder; which points to the certificate
location, and turns on the the browser proxy settings
"""
LOG.info("Installing mitmproxy CA certficate into Firefox")
# browser_path is the exe, we want the folder
self.policies_dir = os.path.dirname(browser_path)
# on macosx we need to remove the last folders 'MacOS'
@ -262,11 +264,68 @@ class Mitmproxy(Playback, Python3Virtualenv, TestingMixin, MercurialScript):
'host': self.config['host']})
# cannot continue if failed to add CA cert to Firefox, need to check
if not self.is_mitmproxy_cert_installed():
LOG.error('Aborting: failed to install mitmproxy CA cert into Firefox')
if not self.is_mitmproxy_cert_installed_desktop():
LOG.error('Aborting: failed to install mitmproxy CA cert into Firefox desktop')
self.stop_mitmproxy_playback()
sys.exit()
def install_mitmproxy_cert_android(self, mitmproxy_proc, browser_path):
"""Install the CA certificate generated by mitmproxy, into geckoview android
1. Get the `certutil` tool.
2. Create an NSS certificate database in the geckoview browser profile dir.
`certutil -N -d sql:<path to profile> --empty-password`
3. Import the mitmproxy certificate into the database.
`certutil -A -d sql:<path to profile> -n "some nickname" -t TC,, -a -i <path to CA.pem>`
"""
# get the certutil tool
if self.config.get("obj_path", None) is not None:
# when running locally, it is found in the Firefox desktop build (..obj../dist/bin)
self.certutil = os.path.join(self.config['obj_path'], 'dist', 'bin')
else:
# in production it is already downloaded on the host automation machines via hostutils
# self.certutil = TODO
LOG.info("TODO: where is the path in production to certutil/hostutils?")
bin_suffix = mozinfo.info.get('bin_suffix', '')
self.certutil = os.path.join(self.certutil, "certutil" + bin_suffix)
if os.path.isfile(self.certutil):
LOG.info("certutil is found at: %s" % self.certutil)
else:
LOG.critical("unable to find certutil at %s" % self.certutil)
# DEFAULT_CERT_PATH has local path and name of mitmproxy cert i.e.
# /home/cltbld/.mitmproxy/mitmproxy-ca-cert.cer
self.local_cert_path = DEFAULT_CERT_PATH
# create cert db
param1 = "sql:%s/" % self.config['local_profile_dir']
command = [self.certutil, '-N', '-d', param1, '--empty-password']
LOG.info("creating nss cert database using command: %s" % ' '.join(command))
cmd_proc = subprocess.Popen(command, env=os.environ.copy())
time.sleep(3)
cmd_terminated = cmd_proc.poll()
if cmd_terminated is None: # None value indicates process hasn't terminated
LOG.critical("nss cert db creation command failed to complete")
# import mitmproxy cert into the db
command = [self.certutil, '-A', '-d', param1, '-n',
'mitmproxy-cert', '-t', 'TC,,', '-a', '-i', self.local_cert_path]
LOG.info("importing mitmproxy cert into db using command: %s" % ' '.join(command))
cmd_proc = subprocess.Popen(command, env=os.environ.copy())
time.sleep(3)
cmd_terminated = cmd_proc.poll()
if cmd_terminated is None: # None value indicates process hasn't terminated
LOG.critical("command to import mitmproxy cert into cert db failed to complete")
# cannot continue if failed to add CA cert to Firefox, need to check
# if not self.is_mitmproxy_cert_installed_android():
# LOG.error('Aborting: failed to install mitmproxy CA cert into Firefox')
# self.stop_mitmproxy_playback()
# sys.exit()
def write_policies_json(self, location, policies_content):
policies_file = os.path.join(location, "policies.json")
LOG.info("writing: %s" % policies_file)
@ -281,7 +340,7 @@ class Mitmproxy(Playback, Python3Virtualenv, TestingMixin, MercurialScript):
with open(policies_file, 'r') as fd:
return fd.read()
def is_mitmproxy_cert_installed(self):
def is_mitmproxy_cert_installed_desktop(self):
"""Verify mitmxproy CA cert was added to Firefox"""
try:
# read autoconfig file, confirm mitmproxy cert is in there
@ -300,6 +359,11 @@ class Mitmproxy(Playback, Python3Virtualenv, TestingMixin, MercurialScript):
return False
return True
def is_mitmproxy_cert_installed_android(self):
"""Verify mitmxproy CA cert was added to Firefox"""
LOG.info("* TODO: verify cert is installed on android")
return False
def start_mitmproxy_playback(self,
mitmdump_path,
mitmproxy_recording_path,

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

@ -28,8 +28,6 @@ else:
mozharness_dir = os.path.join(here, '../../../mozharness')
sys.path.insert(0, mozharness_dir)
from mozharness.mozilla.firefox.autoconfig import _cfg_file_path, _autoconfig_path
webext_dir = os.path.join(os.path.dirname(here), 'webext')
sys.path.insert(0, here)
@ -50,16 +48,6 @@ from results import RaptorResultsHandler
from gecko_profile import GeckoProfile
def remove_autoconfig(binary):
bindir = os.path.dirname(binary)
mozillacfg = _cfg_file_path(bindir)
if os.path.isfile(mozillacfg):
os.unlink(mozillacfg)
autoconfig = _autoconfig_path(bindir)
if os.path.isfile(autoconfig):
os.unlink(autoconfig)
class Raptor(object):
"""Container class for Raptor"""
@ -86,6 +74,7 @@ class Raptor(object):
self.benchmark = None
self.gecko_profiler = None
self.post_startup_delay = 30000
self.device = None
# debug mode is currently only supported when running locally
self.debug_mode = debug_mode if self.config['run_local'] else False
@ -101,9 +90,6 @@ class Raptor(object):
self.profile = create_profile('firefox')
else:
self.profile = create_profile(self.config['app'])
# Clear any existing mozilla.cfg file to prevent earlier
# runs using mitmproxy from interfering with settings.
remove_autoconfig(binary)
# Merge in base profiles
with open(os.path.join(self.profile_data_dir, 'profiles.json'), 'r') as fh:
@ -114,6 +100,9 @@ class Raptor(object):
self.log.info("Merging profile: {}".format(path))
self.profile.merge(path)
# add profile dir to our config
self.config['local_profile_dir'] = self.profile.profile
# create results holder
self.results_handler = RaptorResultsHandler()
@ -177,6 +166,13 @@ class Raptor(object):
if test.get('type') == "benchmark":
self.benchmark = Benchmark(self.config, test)
benchmark_port = int(self.benchmark.port)
# for android we must make the benchmarks server available to the device
if self.config['app'] == "geckoview" and self.config['host'] \
in ('localhost', '127.0.0.1'):
self.log.info("making the raptor benchmarks server port available to device")
_tcp_port = "tcp:%s" % benchmark_port
self.device.create_socket_connection('reverse', _tcp_port, _tcp_port)
else:
benchmark_port = 0
@ -188,12 +184,6 @@ class Raptor(object):
b_port=benchmark_port,
debug_mode=1 if self.debug_mode else 0)
# for android we must make the benchmarks server available to the device
if self.config['app'] == "geckoview" and self.config['host'] in ('localhost', '127.0.0.1'):
self.log.info("making the raptor benchmarks server port available to device")
_tcp_port = "tcp:%s" % benchmark_port
self.device.create_socket_connection('reverse', _tcp_port, _tcp_port)
# must intall raptor addon each time because we dynamically update some content
# note: for chrome the addon is just a list of paths that ultimately are added
# to the chromium command line '--load-extension' argument
@ -213,11 +203,30 @@ class Raptor(object):
if self.config['app'] in ["firefox", "geckoview"]:
webext_id = self.profile.addons.addon_details(raptor_webext)['id']
# for android/geckoview, create a top-level raptor folder on the device
# sdcard; if it already exists remove it so we start fresh each time
if self.config['app'] == "geckoview":
self.device_raptor_dir = "/sdcard/raptor"
self.config['device_raptor_dir'] = self.device_raptor_dir
if self.device.is_dir(self.device_raptor_dir):
self.log.info("deleting existing device raptor dir: %s" % self.device_raptor_dir)
self.device.rm(self.device_raptor_dir, recursive=True)
self.log.info("creating raptor folder on sdcard: %s" % self.device_raptor_dir)
self.device.mkdir(self.device_raptor_dir)
self.device.chmod(self.device_raptor_dir, recursive=True)
# some tests require tools to playback the test pages
if test.get('playback', None) is not None:
self.get_playback_config(test)
# startup the playback tool
self.playback = get_playback(self.config)
self.playback = get_playback(self.config, self.device)
# for android we must make the playback server available to the device
if self.config['app'] == "geckoview" and self.config['host'] \
in ('localhost', '127.0.0.1'):
self.log.info("making the raptor playback server port available to device")
_tcp_port = "tcp:8080"
self.device.create_socket_connection('reverse', _tcp_port, _tcp_port)
if self.config['app'] in ("geckoview", "firefox") and \
self.config['host'] not in ('localhost', '127.0.0.1'):
@ -230,19 +239,36 @@ class Raptor(object):
with open(userjspath, 'w') as userjsfile:
userjsfile.writelines(prefs)
# for geckoview we must copy the profile onto the device and set perms
# for geckoview/android pageload playback we can't use a policy to turn on the
# proxy; we need to set prefs instead; note that the 'host' may be different
# than '127.0.0.1' so we must set the prefs accordingly
if self.config['app'] == "geckoview" and test.get('playback', None) is not None:
self.log.info("setting profile prefs to turn on the geckoview browser proxy")
no_proxies_on = "localhost, 127.0.0.1, %s" % self.config['host']
proxy_prefs = {}
proxy_prefs["network.proxy.type"] = 1
proxy_prefs["network.proxy.http"] = self.config['host']
proxy_prefs["network.proxy.http_port"] = 8080
proxy_prefs["network.proxy.ssl"] = self.config['host']
proxy_prefs["network.proxy.ssl_port"] = 8080
proxy_prefs["network.proxy.no_proxies_on"] = no_proxies_on
self.profile.set_preferences(proxy_prefs)
# now some final settings, and then startup of the browser under test
if self.config['app'] == "geckoview":
# for android/geckoview we must copy the profile onto the device and set perms
if not self.device.is_app_installed(self.config['binary']):
raise Exception('%s is not installed' % self.config['binary'])
self.log.info("copying firefox profile onto the android device")
self.device_profile = "/sdcard/raptor-profile"
self.device_profile = os.path.join(self.device_raptor_dir, "profile")
if self.device.is_dir(self.device_profile):
self.log.info("deleting existing device profile folder: %s" % self.device_profile)
self.device.rm(self.device_profile, recursive=True)
self.log.info("creating profile folder on device: %s" % self.device_profile)
self.device.mkdir(self.device_profile)
self.log.info("copying firefox profile onto the device")
self.log.info("note: the profile folder being copied is: %s" % self.profile.profile)
self.log.info('the adb push cmd copies that profile dir to a new temp dir before copy')
self.device.push(self.profile.profile, self.device_profile)
self.log.info("setting permisions to profile dir on the device")
self.device.chmod(self.device_profile, recursive=True)
# now start the geckoview app
@ -425,7 +451,6 @@ class Raptor(object):
self.device.remove_socket_connections('reverse')
else:
pass
remove_autoconfig(self.config['binary'])
self.log.info("finished")

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

@ -0,0 +1,12 @@
<!doctype html>
<meta http-equiv="Content-Type" content='charset="windows-1251'>
<meta charset=windows-1250>
<title></title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<link rel=help href="https://html.spec.whatwg.org/#algorithm-for-extracting-a-character-encoding-from-a-meta-element">
<script>
test(function() {
assert_equals(document.characterSet, "windows-1250");
});
</script>

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

@ -397,7 +397,6 @@ function _setupDebuggerServer(breakpointFiles, callback) {
"See also https://bugzil.la/1215378.");
}
let { DebuggerServer } = require("devtools/server/main");
let { OriginalLocation } = require("devtools/server/actors/common");
DebuggerServer.init();
DebuggerServer.registerAllActors();
let { createRootActor } = require("resource://testing-common/dbg-actors.js");
@ -406,29 +405,14 @@ function _setupDebuggerServer(breakpointFiles, callback) {
// An observer notification that tells us when we can "resume" script
// execution.
const TOPICS = ["devtools-thread-resumed", "xpcshell-test-devtools-shutdown"];
const TOPICS = ["devtools-thread-instantiated", "devtools-thread-resumed", "xpcshell-test-devtools-shutdown"];
let observe = function(subject, topic, data) {
switch (topic) {
case "devtools-thread-resumed":
// Exceptions in here aren't reported and block the debugger from
// resuming, so...
try {
// Add a breakpoint for the first line in our test files.
let threadActor = subject.wrappedJSObject;
for (let file of breakpointFiles) {
// Pass an empty `source` object to workaround `source` function assertion
let sourceActor = threadActor.sources.source({originalUrl: file, source: {}});
sourceActor._getOrCreateBreakpointActor(new OriginalLocation(sourceActor, 1));
}
} catch (ex) {
info("Failed to initialize breakpoints: " + ex + "\n" + ex.stack);
}
break;
case "xpcshell-test-devtools-shutdown":
// the debugger has shutdown before we got a resume event - nothing
// special to do here.
break;
if (topic === "devtools-thread-instantiated") {
const threadActor = subject.wrappedJSObject;
threadActor.setBreakpointOnLoad(breakpointFiles);
return;
}
for (let topicToRemove of TOPICS) {
_Services.obs.removeObserver(observe, topicToRemove);
}

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

@ -1 +1 @@
{"files":{"Cargo.toml":"7e1fc76f204e32123bd7c8964377fa5b5231187f312683210393360ead036908","README.md":"d69d75705e2582721cbfb2d3b4b2af052c71679057a0b2ac53a22c03f1755bba","appveyor.yml":"7c1e0718a363d3567cecd1ef772d4e17c2a17f18906dc464dce8a2411adff6be","src/bitmap_render_target.rs":"fc13525d7459515e4bf9769c8a8961b046b4d1ba4042591aaf0925dd5edebf64","src/com_helpers.rs":"02535b27bfb0cee6e4d8db3abd22f2d2e8137a4ce3ab3504beaf4fa3ca9370df","src/comptr.rs":"84794cf04b772398e75fdb5d55fd8fa015abf26c61b1f9c761a597133682b2e1","src/font.rs":"a79b944f2f5125bbef9e24921355dc6996f073e3742ddd410b8efaa0df3a3ee2","src/font_collection.rs":"67cd566714f4c0a20cba24dd064ba471e75016fa2672b2153a19878e6b71f24d","src/font_collection_impl.rs":"a585a6ce62083b3346d67619ea47fec46423a7fb04cc11372828389ab26c5a05","src/font_face.rs":"7f78c4132df39857d8118ac3eacbb57e11bca1d69f9d7f8e1c1c24b7a2b69749","src/font_family.rs":"4e948542dba0c158187d0cb2d72343c443380480cacd12894070d0ef1351dd0a","src/font_file.rs":"1c012d0b436c2831d31cd76f77a59dab1edc5d63881c495eb486cd4febe23031","src/font_file_loader_impl.rs":"71c4153971dbfc21d42ba2e33f159fcb145f7dcfbd17e856e9fd75f0571d41e0","src/gdi_interop.rs":"04dbef7c34bb0fe62c4f2c2ceca62ca94c75a964d744b29b3322a6c3bbb4eabd","src/geometry_sink_impl.rs":"d615de212e55b8b8d95c8d605fc5d78044b4ae4dfd846f706911a16cc3afc049","src/glyph_run_analysis.rs":"3b2a351422098a19e8f490421e5b19227fc14a41a0df97d488c536fd1d4b552c","src/helpers.rs":"2f3c57642b24b80c45bbd012e7d6ca1fc524b1b42a8be004cb9b52ea13f4166d","src/lib.rs":"b634e62dd088d804429f451ba9f14aaab0b6a1179042d70fed825f3253ffacfb","src/outline_builder.rs":"0f5c842b2ffe75e21d68f93be6a3834c120bd43303d4e490fdfee9f4f964cdc4","src/rendering_params.rs":"850a51143790f5d29422dc49cbceddc232d814ecd0e6933434ad644e6eec539b","src/test.rs":"158aa4d03655f4efef00327fe72a03dfb504659176aa0eef976ca2485b2c1d74","src/types.rs":"587aea2e50720e85b28efe237c8ea10bc45b52049ca724447a0fc9b0e6672b11"},"package":"7b46afd0d0bbbea88fc083ea293e40865e26a75ec9d38cf5d05a23ac3e2ffe02"}
{"files":{"Cargo.toml":"5f9a26a7a0f3fffc7093b0ac9e2fd84db133ba5516a9bfb53ed4f842b350564f","README.md":"d69d75705e2582721cbfb2d3b4b2af052c71679057a0b2ac53a22c03f1755bba","appveyor.yml":"7c1e0718a363d3567cecd1ef772d4e17c2a17f18906dc464dce8a2411adff6be","src/bitmap_render_target.rs":"fc13525d7459515e4bf9769c8a8961b046b4d1ba4042591aaf0925dd5edebf64","src/com_helpers.rs":"02535b27bfb0cee6e4d8db3abd22f2d2e8137a4ce3ab3504beaf4fa3ca9370df","src/comptr.rs":"84794cf04b772398e75fdb5d55fd8fa015abf26c61b1f9c761a597133682b2e1","src/font.rs":"a79b944f2f5125bbef9e24921355dc6996f073e3742ddd410b8efaa0df3a3ee2","src/font_collection.rs":"67cd566714f4c0a20cba24dd064ba471e75016fa2672b2153a19878e6b71f24d","src/font_collection_impl.rs":"a585a6ce62083b3346d67619ea47fec46423a7fb04cc11372828389ab26c5a05","src/font_face.rs":"7f78c4132df39857d8118ac3eacbb57e11bca1d69f9d7f8e1c1c24b7a2b69749","src/font_family.rs":"4e948542dba0c158187d0cb2d72343c443380480cacd12894070d0ef1351dd0a","src/font_file.rs":"1c012d0b436c2831d31cd76f77a59dab1edc5d63881c495eb486cd4febe23031","src/font_file_loader_impl.rs":"71c4153971dbfc21d42ba2e33f159fcb145f7dcfbd17e856e9fd75f0571d41e0","src/gdi_interop.rs":"04dbef7c34bb0fe62c4f2c2ceca62ca94c75a964d744b29b3322a6c3bbb4eabd","src/geometry_sink_impl.rs":"d615de212e55b8b8d95c8d605fc5d78044b4ae4dfd846f706911a16cc3afc049","src/glyph_run_analysis.rs":"3b2a351422098a19e8f490421e5b19227fc14a41a0df97d488c536fd1d4b552c","src/helpers.rs":"2f3c57642b24b80c45bbd012e7d6ca1fc524b1b42a8be004cb9b52ea13f4166d","src/lib.rs":"d6a109158cb69cf4a113722169ba8b339d9d38eccb2c9d6b2fe68dd40da22814","src/outline_builder.rs":"0f5c842b2ffe75e21d68f93be6a3834c120bd43303d4e490fdfee9f4f964cdc4","src/rendering_params.rs":"850a51143790f5d29422dc49cbceddc232d814ecd0e6933434ad644e6eec539b","src/test.rs":"158aa4d03655f4efef00327fe72a03dfb504659176aa0eef976ca2485b2c1d74","src/types.rs":"587aea2e50720e85b28efe237c8ea10bc45b52049ca724447a0fc9b0e6672b11"},"package":"f0beca78470f26189a662e72afe7a54c625b4feb06b2d36c207ac15319bd57c5"}

2
third_party/rust/dwrote/Cargo.toml поставляемый
Просмотреть файл

@ -12,7 +12,7 @@
[package]
name = "dwrote"
version = "0.6.2"
version = "0.6.3"
authors = ["Vladimir Vukicevic <vladimir@pobox.com>"]
description = "Lightweight binding to DirectWrite."
license = "MPL-2.0"

1
third_party/rust/dwrote/src/lib.rs поставляемый
Просмотреть файл

@ -65,6 +65,7 @@ pub use winapi::um::dwrite::{DWRITE_RENDERING_MODE};
pub use winapi::um::dwrite::{DWRITE_TEXTURE_TYPE};
pub use winapi::um::dwrite_3::{DWRITE_FONT_AXIS_VALUE};
pub use winapi::um::dcommon::{DWRITE_MEASURING_MODE};
pub use winapi::shared::windef::RECT;
use winapi::um::libloaderapi::{GetProcAddress, LoadLibraryW};
#[macro_use] mod com_helpers;

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

@ -66,10 +66,6 @@ if (Cu) {
XPCOMUtils.defineLazyServiceGetter(this, "FinalizationWitnessService",
"@mozilla.org/toolkit/finalizationwitness;1",
"nsIFinalizationWitnessService");
// For now, we're worried about add-ons using Promises with CPOWs, so we'll
// permit them in this scope, but this support will go away soon.
Cu.permitCPOWsInScope(this);
}
const STATUS_PENDING = 0;

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

@ -87,10 +87,6 @@ var EXPORTED_SYMBOLS = [
// Globals
// For now, we're worried about add-ons using Tasks with CPOWs, so we'll
// permit them in this scope, but this support will go away soon.
Cu.permitCPOWsInScope(this);
// The following error types are considered programmer errors, which should be
// reported (possibly redundantly) so as to let programmers fix their code.
const ERRORS_TO_REPORT = ["EvalError", "RangeError", "ReferenceError", "TypeError"];