зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to inbound. r=merge a=merge on a CLOSED TREE
This commit is contained in:
Коммит
874238697d
|
@ -115,11 +115,6 @@
|
|||
// xul:text, i.e. the tab label text
|
||||
role: ROLE_TEXT_LEAF,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
// xul:toolbarbutton ("Close Tab")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -131,11 +126,6 @@
|
|||
// xul:text, i.e. the tab label text
|
||||
role: ROLE_TEXT_LEAF,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
// xul:toolbarbutton ("Close Tab")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -7835,8 +7835,7 @@
|
|||
Therefore it should only be used as a child of the tab or the tabs
|
||||
element (in both cases, when they are anonymous nodes of <tabbrowser>).
|
||||
-->
|
||||
<binding id="tabbrowser-close-tab-button"
|
||||
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image">
|
||||
<binding id="tabbrowser-close-tab-button">
|
||||
<handlers>
|
||||
<handler event="click" button="0"><![CDATA[
|
||||
var bindingParent = document.getBindingParent(this);
|
||||
|
@ -7913,9 +7912,10 @@
|
|||
anonid="soundplaying-icon"
|
||||
class="tab-icon-sound"
|
||||
role="presentation"/>
|
||||
<xul:toolbarbutton anonid="close-button"
|
||||
xbl:inherits="fadein,pinned,selected=visuallyselected"
|
||||
class="tab-close-button close-icon"/>
|
||||
<xul:image anonid="close-button"
|
||||
xbl:inherits="fadein,pinned,selected=visuallyselected"
|
||||
class="tab-close-button close-icon"
|
||||
role="presentation"/>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</content>
|
||||
|
|
|
@ -846,20 +846,6 @@ html|span.ac-emphasize-text-url {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In-tab close button
|
||||
*/
|
||||
|
||||
.tab-close-button > .toolbarbutton-icon {
|
||||
margin-inline-end: 0px !important;
|
||||
}
|
||||
|
||||
.tab-close-button {
|
||||
border: none !important;
|
||||
background: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Bookmarks toolbar */
|
||||
#PlacesToolbarDropIndicator {
|
||||
list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
|
||||
|
|
|
@ -360,7 +360,6 @@ tabbrowser {
|
|||
|
||||
.tab-close-button {
|
||||
margin-inline-end: -2px;
|
||||
padding: 0;
|
||||
-moz-context-properties: fill, fill-opacity, stroke-opacity;
|
||||
stroke-opacity: var(--toolbarbutton-icon-fill-opacity);
|
||||
}
|
||||
|
|
|
@ -789,12 +789,6 @@ html|span.ac-emphasize-text-url {
|
|||
z-index: 3;
|
||||
}
|
||||
|
||||
/* Tab close button */
|
||||
.tab-close-button {
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* All tabs menupopup */
|
||||
|
||||
.alltabs-item[selected="true"] {
|
||||
|
|
|
@ -198,10 +198,14 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$DEVELOPER_OPTIONS"; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# bionic in Android < 4.1 doesn't support PIE
|
||||
# On OSX, the linker defaults to building PIE programs when targeting OSX 10.7.
|
||||
# On other Unix systems, some file managers (Nautilus) can't start PIE programs
|
||||
MOZ_PIE=
|
||||
if test "$OS_TARGET" = Android; then
|
||||
# bionic in Android >= 4.1 supports PIE, and we target those versions.
|
||||
MOZ_PIE=1
|
||||
else
|
||||
MOZ_PIE=
|
||||
fi
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(pie,
|
||||
[ --enable-pie Enable Position Independent Executables],
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -49,7 +49,7 @@ prepare() {
|
|||
mpc-*.tar.*)
|
||||
# If download_prerequisites wants 0.8.1, use 0.8.2 instead.
|
||||
file=${file/0.8.1/0.8.2}
|
||||
download_and_check http://www.multiprecision.org/mpc/download $file.asc
|
||||
download_and_check http://www.multiprecision.org/downloads $file.asc
|
||||
;;
|
||||
*)
|
||||
download $(dirname $url) $file
|
||||
|
|
|
@ -262,6 +262,28 @@
|
|||
fun:recalc_style_at<style::gecko::wrapper::GeckoElement,style::gecko::traversal::RecalcStyleOnly,closure>
|
||||
}
|
||||
|
||||
# Similar issue triggered by rust 1.23.0 on builds of stylo.
|
||||
#
|
||||
# at 0x11819B3E: std::sync::once::Once::call_once::{{closure}} (raw_vec.rs:225)
|
||||
# by 0x118FDCCC: std::sync::once::Once::call_inner (once.rs:341)
|
||||
# by 0x1139C761: UnknownInlinedFun (once.rs:228)
|
||||
{
|
||||
Bug 1418083 Servo::TraverseSubtree, January 2018
|
||||
Memcheck:Cond
|
||||
fun:*ZN3std4sync4once4Once9call_once*
|
||||
fun:*ZN3std4sync4once4Once10call_inner*
|
||||
...
|
||||
fun:Servo_TraverseSubtree
|
||||
}
|
||||
|
||||
# Issue triggered by rust 1.23.0 on builds of stylo.
|
||||
{
|
||||
Bug 1418083 SelectorList::parse, January 2018
|
||||
Memcheck:Cond
|
||||
fun:_ZN36_$LT$smallvec..SmallVec*
|
||||
fun:_ZN52_$LT$selectors..parser..SelectorList*
|
||||
}
|
||||
|
||||
###################################################
|
||||
# For valgrind-mochitest ("tc-M-V [tier 2]") runs on taskcluster.
|
||||
# See bug 1248365.
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"node": ">=6.9.0"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "cd ../netmonitor && npm install && cd ../webconsole",
|
||||
"start": "cross-env NODE_ENV=production node bin/dev-server",
|
||||
"dev": "node bin/dev-server",
|
||||
"test": "cross-env NODE_ENV=test NODE_PATH=../../../ mocha new-console-output/test/**/*.test.js --compilers js:babel-register -r jsdom-global/register -r ./new-console-output/test/require-helper.js"
|
||||
|
|
|
@ -1288,7 +1288,7 @@ KeyframeEffectReadOnly::GetKeyframes(JSContext*& aCx,
|
|||
} // else if null, leave easing as its default "linear".
|
||||
|
||||
if (keyframe.mComposite) {
|
||||
keyframeDict.mComposite.Construct(keyframe.mComposite.value());
|
||||
keyframeDict.mComposite.SetValue(keyframe.mComposite.value());
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> keyframeJSValue(aCx);
|
||||
|
|
|
@ -658,7 +658,7 @@ ConvertKeyframeSequence(JSContext* aCx,
|
|||
keyframe->mOffset.emplace(keyframeDict.mOffset.Value());
|
||||
}
|
||||
|
||||
if (keyframeDict.mComposite.WasPassed()) {
|
||||
if (!keyframeDict.mComposite.IsNull()) {
|
||||
keyframe->mComposite.emplace(keyframeDict.mComposite.Value());
|
||||
}
|
||||
|
||||
|
@ -1547,23 +1547,27 @@ GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
|
|||
//
|
||||
// This corresponds to step 5, "Otherwise," branch, substep 12 of
|
||||
// https://drafts.csswg.org/web-animations/#processing-a-keyframes-argument
|
||||
const FallibleTArray<dom::CompositeOperation>* compositeOps;
|
||||
AutoTArray<dom::CompositeOperation, 1> singleCompositeOp;
|
||||
const FallibleTArray<Nullable<dom::CompositeOperation>>* compositeOps =
|
||||
nullptr;
|
||||
AutoTArray<Nullable<dom::CompositeOperation>, 1> singleCompositeOp;
|
||||
auto& composite = keyframeDict.mComposite;
|
||||
if (composite.IsCompositeOperation()) {
|
||||
singleCompositeOp.AppendElement(composite.GetAsCompositeOperation());
|
||||
const FallibleTArray<dom::CompositeOperation>& asFallibleArray =
|
||||
const FallibleTArray<Nullable<dom::CompositeOperation>>& asFallibleArray =
|
||||
singleCompositeOp;
|
||||
compositeOps = &asFallibleArray;
|
||||
} else {
|
||||
compositeOps = &composite.GetAsCompositeOperationSequence();
|
||||
} else if (composite.IsCompositeOperationOrNullSequence()) {
|
||||
compositeOps = &composite.GetAsCompositeOperationOrNullSequence();
|
||||
}
|
||||
|
||||
// Fill in and repeat as needed.
|
||||
if (!compositeOps->IsEmpty()) {
|
||||
if (compositeOps && !compositeOps->IsEmpty()) {
|
||||
size_t length = compositeOps->Length();
|
||||
for (size_t i = 0; i < aResult.Length(); i++) {
|
||||
aResult[i].mComposite.emplace(
|
||||
compositeOps->ElementAt(i % compositeOps->Length()));
|
||||
if (!compositeOps->ElementAt(i % length).IsNull()) {
|
||||
aResult[i].mComposite.emplace(
|
||||
compositeOps->ElementAt(i % length).Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,16 +225,16 @@ test(function(t) {
|
|||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
color: "rgb(0, 0, 0)" },
|
||||
color: "rgb(0, 0, 0)", composite: null },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
color: "rgb(255, 255, 255)" },
|
||||
color: "rgb(255, 255, 255)", composite: null },
|
||||
];
|
||||
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
|
||||
}
|
||||
}, 'KeyframeEffectReadOnly.getKeyframes() returns expected frames for a simple'
|
||||
+ 'animation');
|
||||
+ ' animation');
|
||||
|
||||
test(function(t) {
|
||||
kTimingFunctionValues.forEach(function(easing) {
|
||||
|
@ -295,10 +295,10 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
marginBottom: "8px", marginLeft: "8px",
|
||||
marginRight: "8px", marginTop: "8px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
marginBottom: "16px", marginLeft: "16px",
|
||||
marginRight: "16px", marginTop: "16px" },
|
||||
];
|
||||
|
@ -319,9 +319,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
color: "rgb(0, 0, 255)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
color: "rgb(255, 255, 255)" },
|
||||
];
|
||||
|
||||
|
@ -341,9 +341,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
color: "rgb(255, 255, 255)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
color: "rgb(0, 0, 255)" },
|
||||
];
|
||||
|
||||
|
@ -363,11 +363,11 @@ test(function(t) {
|
|||
assert_equals(frames.length, 3, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
color: "rgb(255, 255, 255)" },
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "ease",
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: null,
|
||||
color: "rgb(0, 0, 255)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
color: "rgb(255, 255, 255)" },
|
||||
];
|
||||
|
||||
|
@ -387,9 +387,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
marginTop: '50px', marginBottom: '100px' },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
marginTop: '250px', marginBottom: '200px' },
|
||||
];
|
||||
|
||||
|
@ -409,13 +409,13 @@ test(function(t) {
|
|||
assert_equals(frames.length, 4, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
color: "rgb(0, 0, 0)", marginTop: "8px" },
|
||||
{ offset: 0.25, computedOffset: 0.25, easing: "ease",
|
||||
{ offset: 0.25, computedOffset: 0.25, easing: "ease", composite: null,
|
||||
color: "rgb(0, 0, 255)" },
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease",
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: null,
|
||||
marginTop: "12px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
color: "rgb(255, 255, 255)", marginTop: "16px" },
|
||||
];
|
||||
|
||||
|
@ -435,13 +435,13 @@ test(function(t) {
|
|||
assert_equals(frames.length, 4, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "linear",
|
||||
{ offset: 0, computedOffset: 0, easing: "linear", composite: null,
|
||||
color: "rgb(0, 0, 0)", marginTop: "8px" },
|
||||
{ offset: 0.25, computedOffset: 0.25, easing: "steps(1)",
|
||||
{ offset: 0.25, computedOffset: 0.25, easing: "steps(1)", composite: null,
|
||||
color: "rgb(0, 0, 255)" },
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in",
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in", composite: null,
|
||||
marginTop: "12px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
color: "rgb(255, 255, 255)", marginTop: "16px" },
|
||||
];
|
||||
|
||||
|
@ -461,9 +461,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
color: "rgb(0, 0, 0)", marginTop: "8px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
color: "rgb(255, 255, 255)", marginTop: "16px" },
|
||||
];
|
||||
|
||||
|
@ -483,11 +483,11 @@ test(function(t) {
|
|||
assert_equals(frames.length, 3, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(1)",
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: null,
|
||||
color: "rgb(0, 0, 0)", fontSize: "16px" },
|
||||
{ offset: 0, computedOffset: 0, easing: "linear",
|
||||
{ offset: 0, computedOffset: 0, easing: "linear", composite: null,
|
||||
marginTop: "8px", paddingLeft: "2px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
color: "rgb(255, 255, 255)", fontSize: "32px", marginTop: "16px",
|
||||
paddingLeft: "4px" },
|
||||
];
|
||||
|
@ -508,11 +508,11 @@ test(function(t) {
|
|||
assert_equals(frames.length, 3, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(1)",
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: null,
|
||||
marginTop: "0px", marginRight: "0px", marginBottom: "0px" },
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "steps(1)",
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "steps(1)", composite: null,
|
||||
marginTop: "10px", marginRight: "10px", marginBottom: "10px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
|
||||
];
|
||||
|
||||
|
@ -532,17 +532,17 @@ test(function(t) {
|
|||
assert_equals(frames.length, 6, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
paddingTop: "30px" },
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "ease",
|
||||
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: null,
|
||||
paddingTop: "20px" },
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease",
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: null,
|
||||
paddingTop: "20px" },
|
||||
{ offset: 0.85, computedOffset: 0.85, easing: "ease",
|
||||
{ offset: 0.85, computedOffset: 0.85, easing: "ease", composite: null,
|
||||
paddingTop: "30px" },
|
||||
{ offset: 0.851, computedOffset: 0.851, easing: "ease",
|
||||
{ offset: 0.851, computedOffset: 0.851, easing: "ease", composite: null,
|
||||
paddingTop: "60px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
paddingTop: "70px" },
|
||||
];
|
||||
|
||||
|
@ -564,9 +564,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
filter: "none" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
filter: "blur(5px) sepia(60%) saturate(30%)" },
|
||||
];
|
||||
|
||||
|
@ -585,9 +585,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
filter: "drop-shadow(rgb(0, 255, 0) 10px 10px 10px)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
filter: "drop-shadow(rgb(255, 0, 0) 50px 30px 10px)" },
|
||||
];
|
||||
|
||||
|
@ -613,11 +613,12 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
textShadow: "rgb(0, 0, 0) 1px 1px 2px,"
|
||||
+ " rgb(0, 0, 255) 0px 0px 16px,"
|
||||
+ " rgb(0, 0, 255) 0px 0px 3.2px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", textShadow: "none" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
textShadow: "none" },
|
||||
];
|
||||
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
|
@ -639,9 +640,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
backgroundSize: "auto auto" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
backgroundSize: "50% auto, 6px auto, contain" },
|
||||
];
|
||||
|
||||
|
@ -671,9 +672,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
transform: "none" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
transform: "translate(100px, 0px)" },
|
||||
];
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
|
@ -691,12 +692,12 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
marginBottom: "0px",
|
||||
marginLeft: "0px",
|
||||
marginRight: "0px",
|
||||
marginTop: "0px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
marginBottom: "100px",
|
||||
marginLeft: "100px",
|
||||
marginRight: "100px",
|
||||
|
@ -717,9 +718,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
color: "rgb(0, 0, 0)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
color: "rgb(0, 255, 0)" },
|
||||
];
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
|
@ -737,9 +738,9 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease",
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
transform: "translate(100px, 0px)" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease",
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: null,
|
||||
transform: "none" },
|
||||
];
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
|
|
|
@ -36,8 +36,10 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", left: "0px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "linear", left: "100px" },
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: null,
|
||||
left: "0px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "linear", composite: null,
|
||||
left: "100px" },
|
||||
];
|
||||
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
|
@ -59,8 +61,10 @@ test(function(t) {
|
|||
assert_equals(frames.length, 2, "number of frames");
|
||||
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(2)", left: "0px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "linear", left: "100px" },
|
||||
{ offset: 0, computedOffset: 0, easing: "steps(2)", composite: null,
|
||||
left: "0px" },
|
||||
{ offset: 1, computedOffset: 1, easing: "linear", composite: null,
|
||||
left: "100px" },
|
||||
];
|
||||
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
|
@ -81,8 +85,10 @@ test(function(t) {
|
|||
// CSS transition endpoints are based on the computed value so we
|
||||
// shouldn't see the variable reference
|
||||
var expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: 'ease', left: '0px' },
|
||||
{ offset: 1, computedOffset: 1, easing: 'linear', left: '100px' },
|
||||
{ offset: 0, computedOffset: 0, easing: 'ease', composite: null,
|
||||
left: '0px' },
|
||||
{ offset: 1, computedOffset: 1, easing: 'linear', composite: null,
|
||||
left: '100px' },
|
||||
];
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
|
||||
|
|
|
@ -1130,15 +1130,8 @@ nsFrameLoader::AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
|
|||
NS_PRECONDITION(mOwnerContent, "Must have owning content");
|
||||
|
||||
nsAutoString value;
|
||||
bool isContent = false;
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, TypeAttrName(), value);
|
||||
|
||||
// we accept "content" and "content-xxx" values.
|
||||
// We ignore anything that comes after 'content-'.
|
||||
isContent = value.LowerCaseEqualsLiteral("content") ||
|
||||
StringBeginsWith(value, NS_LITERAL_STRING("content-"),
|
||||
nsCaseInsensitiveStringComparator());
|
||||
|
||||
bool isContent = mOwnerContent->AttrValueIs(
|
||||
kNameSpaceID_None, TypeAttrName(), nsGkAtoms::content, eIgnoreCase);
|
||||
|
||||
// Force mozbrowser frames to always be typeContent, even if the
|
||||
// mozbrowser interfaces are disabled.
|
||||
|
@ -3182,12 +3175,8 @@ nsFrameLoader::TryRemoteBrowser()
|
|||
return false;
|
||||
}
|
||||
|
||||
nsAutoString value;
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
|
||||
|
||||
if (!value.LowerCaseEqualsLiteral("content") &&
|
||||
!StringBeginsWith(value, NS_LITERAL_STRING("content-"),
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
if (!mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||
nsGkAtoms::content, eIgnoreCase)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3748,13 +3737,7 @@ nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
|
|||
#endif
|
||||
|
||||
parentTreeOwner->ContentShellRemoved(mDocShell);
|
||||
|
||||
nsAutoString value;
|
||||
aElement->GetAttr(kNameSpaceID_None, TypeAttrName(), value);
|
||||
|
||||
if (value.LowerCaseEqualsLiteral("content") ||
|
||||
StringBeginsWith(value, NS_LITERAL_STRING("content-"),
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
if (aElement->AttrValueIs(kNameSpaceID_None, TypeAttrName(), nsGkAtoms::content, eIgnoreCase)) {
|
||||
parentTreeOwner->ContentShellAdded(mDocShell, is_primary);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,5 +95,5 @@
|
|||
});
|
||||
]]></script>
|
||||
|
||||
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
|
||||
<browser type="content" primary="true" flex="1" id="content" src="about:blank"/>
|
||||
</window>
|
||||
|
|
|
@ -22,13 +22,13 @@ enum CompositeOperation { "replace", "add", "accumulate" };
|
|||
dictionary BasePropertyIndexedKeyframe {
|
||||
(double? or sequence<double?>) offset = [];
|
||||
(DOMString or sequence<DOMString>) easing = [];
|
||||
(CompositeOperation or sequence<CompositeOperation>) composite = [];
|
||||
(CompositeOperation? or sequence<CompositeOperation?>) composite = [];
|
||||
};
|
||||
|
||||
dictionary BaseKeyframe {
|
||||
double? offset = null;
|
||||
DOMString easing = "linear";
|
||||
CompositeOperation composite;
|
||||
CompositeOperation? composite = null;
|
||||
|
||||
// Non-standard extensions
|
||||
|
||||
|
|
|
@ -77,6 +77,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1271240
|
|||
|
||||
]]>
|
||||
</script>
|
||||
<!-- <browser type="content-primary" flex="1" id="content" />
|
||||
<browser type="content-primary" flex="1" id="content-remote" remote="true" /> -->
|
||||
<!-- <browser type="content" flex="1" id="content" />
|
||||
<browser type="content" flex="1" id="content-remote" remote="true" /> -->
|
||||
</window>
|
||||
|
|
|
@ -4,15 +4,11 @@
|
|||
# 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/.
|
||||
|
||||
# Any changes that affect Android need to be made in pie/moz.build as well.
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||
Program(CONFIG['MOZ_CHILD_PROCESS_NAME'])
|
||||
SOURCES += [
|
||||
'MozillaRuntimeMainAndroid.cpp',
|
||||
]
|
||||
|
||||
DIRS += ['pie']
|
||||
else:
|
||||
GeckoProgram(CONFIG['MOZ_CHILD_PROCESS_NAME'], linkage='dependent')
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
Program(CONFIG['MOZ_CHILD_PROCESS_NAME_PIE'])
|
||||
SOURCES += [
|
||||
'../MozillaRuntimeMainAndroid.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/toolkit/xre',
|
||||
'/xpcom/base',
|
||||
]
|
||||
|
||||
LDFLAGS += ['-pie']
|
|
@ -219,8 +219,8 @@ include('/ipc/chromium/chromium-config.mozbuild')
|
|||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_NAME_PIE',
|
||||
'MOZ_CHILD_PROCESS_BUNDLE', 'DLL_PREFIX', 'DLL_SUFFIX'):
|
||||
for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_BUNDLE',
|
||||
'DLL_PREFIX', 'DLL_SUFFIX'):
|
||||
DEFINES[var] = '"%s"' % CONFIG[var]
|
||||
|
||||
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
|
||||
|
|
|
@ -614,9 +614,11 @@ WasmTextToBinary(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
}
|
||||
|
||||
uintptr_t stackLimit = GetNativeStackLimit(cx);
|
||||
|
||||
wasm::Bytes bytes;
|
||||
UniqueChars error;
|
||||
if (!wasm::TextToBinary(twoByteChars.twoByteChars(), &bytes, &error)) {
|
||||
if (!wasm::TextToBinary(twoByteChars.twoByteChars(), stackLimit, &bytes, &error)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_TEXT_FAIL,
|
||||
error.get() ? error.get() : "out of memory");
|
||||
return false;
|
||||
|
|
|
@ -15,4 +15,12 @@ var code = `(module
|
|||
(export "run" 0)
|
||||
)`;
|
||||
|
||||
wasmFullPass(code, Math.fround(13.37), {}, 13.37);
|
||||
try {
|
||||
wasmFullPass(code, Math.fround(13.37), {}, 13.37);
|
||||
} catch (e) {
|
||||
// ASAN will fail these tests because its stack frames are much bigger than
|
||||
// usual ones and the parser will bail out during its recursive descent.
|
||||
// Ignore those errors specifically.
|
||||
assertEq(e.message.includes('out of memory'), true);
|
||||
assertEq(getBuildConfiguration().asan, true);
|
||||
}
|
||||
|
|
|
@ -1057,7 +1057,7 @@ CheckRecursionLimit(JSContext* cx, uintptr_t limit)
|
|||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
CheckRecursionLimitDontReport(JSContext* cx, uintptr_t limit)
|
||||
CheckRecursionLimitDontReport(uintptr_t limit)
|
||||
{
|
||||
int stackDummy;
|
||||
|
||||
|
@ -1076,7 +1076,7 @@ CheckRecursionLimit(JSContext* cx)
|
|||
// use. To work around this, check the untrusted limit first to avoid the
|
||||
// overhead in most cases.
|
||||
uintptr_t untrustedLimit = GetNativeStackLimit(cx, JS::StackForUntrustedScript);
|
||||
if (MOZ_LIKELY(CheckRecursionLimitDontReport(cx, untrustedLimit)))
|
||||
if (MOZ_LIKELY(CheckRecursionLimitDontReport(untrustedLimit)))
|
||||
return true;
|
||||
return CheckRecursionLimit(cx, GetNativeStackLimit(cx));
|
||||
}
|
||||
|
@ -1084,7 +1084,7 @@ CheckRecursionLimit(JSContext* cx)
|
|||
MOZ_ALWAYS_INLINE bool
|
||||
CheckRecursionLimitDontReport(JSContext* cx)
|
||||
{
|
||||
return CheckRecursionLimitDontReport(cx, GetNativeStackLimit(cx));
|
||||
return CheckRecursionLimitDontReport(GetNativeStackLimit(cx));
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
|
@ -1123,8 +1123,8 @@ CheckRecursionLimitConservative(JSContext* cx)
|
|||
MOZ_ALWAYS_INLINE bool
|
||||
CheckRecursionLimitConservativeDontReport(JSContext* cx)
|
||||
{
|
||||
return CheckRecursionLimitDontReport(cx, GetNativeStackLimit(cx, JS::StackForUntrustedScript,
|
||||
-1024 * int(sizeof(size_t))));
|
||||
return CheckRecursionLimitDontReport(GetNativeStackLimit(cx, JS::StackForUntrustedScript,
|
||||
-1024 * int(sizeof(size_t))));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
|
|
|
@ -1665,12 +1665,15 @@ struct WasmParseContext
|
|||
LifoAlloc& lifo;
|
||||
UniqueChars* error;
|
||||
DtoaState* dtoaState;
|
||||
uintptr_t stackLimit;
|
||||
|
||||
WasmParseContext(const char16_t* text, LifoAlloc& lifo, UniqueChars* error)
|
||||
WasmParseContext(const char16_t* text, uintptr_t stackLimit, LifoAlloc& lifo,
|
||||
UniqueChars* error)
|
||||
: ts(text, error),
|
||||
lifo(lifo),
|
||||
error(error),
|
||||
dtoaState(NewDtoaState())
|
||||
dtoaState(NewDtoaState()),
|
||||
stackLimit(stackLimit)
|
||||
{}
|
||||
|
||||
~WasmParseContext() {
|
||||
|
@ -2869,6 +2872,8 @@ ParseGrowMemory(WasmParseContext& c, bool inParens)
|
|||
static AstExpr*
|
||||
ParseExprBody(WasmParseContext& c, WasmToken token, bool inParens)
|
||||
{
|
||||
if (!CheckRecursionLimitDontReport(c.stackLimit))
|
||||
return nullptr;
|
||||
switch (token.kind()) {
|
||||
case WasmToken::Unreachable:
|
||||
return new(c.lifo) AstUnreachable;
|
||||
|
@ -3728,9 +3733,10 @@ ParseBinaryModule(WasmParseContext& c, AstModule* module)
|
|||
}
|
||||
|
||||
static AstModule*
|
||||
ParseModule(const char16_t* text, LifoAlloc& lifo, UniqueChars* error, bool* binary)
|
||||
ParseModule(const char16_t* text, uintptr_t stackLimit, LifoAlloc& lifo, UniqueChars* error,
|
||||
bool* binary)
|
||||
{
|
||||
WasmParseContext c(text, lifo, error);
|
||||
WasmParseContext c(text, stackLimit, lifo, error);
|
||||
|
||||
*binary = false;
|
||||
|
||||
|
@ -5436,12 +5442,12 @@ EncodeBinaryModule(const AstModule& module, Bytes* bytes)
|
|||
/*****************************************************************************/
|
||||
|
||||
bool
|
||||
wasm::TextToBinary(const char16_t* text, Bytes* bytes, UniqueChars* error)
|
||||
wasm::TextToBinary(const char16_t* text, uintptr_t stackLimit, Bytes* bytes, UniqueChars* error)
|
||||
{
|
||||
LifoAlloc lifo(AST_LIFO_DEFAULT_CHUNK_SIZE);
|
||||
|
||||
bool binary = false;
|
||||
AstModule* module = ParseModule(text, lifo, error, &binary);
|
||||
AstModule* module = ParseModule(text, stackLimit, lifo, error, &binary);
|
||||
if (!module)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace wasm {
|
|||
// other than out-of-memory an error message string will be stored in 'error'.
|
||||
|
||||
extern MOZ_MUST_USE bool
|
||||
TextToBinary(const char16_t* text, Bytes* bytes, UniqueChars* error);
|
||||
TextToBinary(const char16_t* text, uintptr_t stackLimit, Bytes* bytes, UniqueChars* error);
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace js
|
||||
|
|
|
@ -50,9 +50,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
|||
'xul.dll',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'Android':
|
||||
LDFLAGS += ['-pie']
|
||||
|
||||
CFLAGS += CONFIG['TK_CFLAGS']
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
OS_LIBS += CONFIG['TK_LIBS']
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# NOTE: bug 1084564 covers "fails"/"skip" annotations for android below:
|
||||
fuzzy(255,5000) random-if(webrender) == 444-1.html 444-1-ref.html
|
||||
fuzzy(255,5000) == 444-1.html 444-1-ref.html
|
||||
fails-if(Android) == aspect-ratio-1a.xhtml aspect-ratio-1-ref.html
|
||||
fails-if(Android) == aspect-ratio-1b.xhtml aspect-ratio-1-ref.html
|
||||
fails-if(Android) skip-if(gtkWidget) == aspect-ratio-2a.xhtml aspect-ratio-2-ref.html
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "mozilla/CachedAnonBoxStyles.h"
|
||||
#include "mozilla/CachedInheritingStyles.h"
|
||||
#include "mozilla/ServoStyleContext.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
CachedAnonBoxStyles::Insert(ServoStyleContext* aStyle)
|
||||
CachedInheritingStyles::Insert(ServoStyleContext* aStyle)
|
||||
{
|
||||
MOZ_ASSERT(aStyle);
|
||||
MOZ_ASSERT(aStyle->IsInheritingAnonBox());
|
||||
MOZ_ASSERT(aStyle->IsInheritingAnonBox() || aStyle->IsLazilyCascadedPseudoElement());
|
||||
|
||||
if (IsEmpty()) {
|
||||
RefPtr<ServoStyleContext> s = aStyle;
|
||||
|
@ -32,12 +32,13 @@ CachedAnonBoxStyles::Insert(ServoStyleContext* aStyle)
|
|||
}
|
||||
|
||||
ServoStyleContext*
|
||||
CachedAnonBoxStyles::Lookup(nsAtom* aAnonBox) const
|
||||
CachedInheritingStyles::Lookup(nsAtom* aPseudoTag) const
|
||||
{
|
||||
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
|
||||
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aPseudoTag) ||
|
||||
nsCSSPseudoElements::IsPseudoElement(aPseudoTag));
|
||||
if (IsIndirect()) {
|
||||
for (auto& style : *AsIndirect()) {
|
||||
if (style->GetPseudo() == aAnonBox) {
|
||||
if (style->GetPseudo() == aPseudoTag) {
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
@ -46,11 +47,11 @@ CachedAnonBoxStyles::Lookup(nsAtom* aAnonBox) const
|
|||
}
|
||||
|
||||
ServoStyleContext* direct = AsDirect();
|
||||
return direct && direct->GetPseudo() == aAnonBox ? direct : nullptr;
|
||||
return direct && direct->GetPseudo() == aPseudoTag ? direct : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CachedAnonBoxStyles::AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const
|
||||
CachedInheritingStyles::AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const
|
||||
{
|
||||
if (IsIndirect()) {
|
||||
for (auto& style : *AsIndirect()) {
|
|
@ -4,8 +4,8 @@
|
|||
* 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_CachedAnonBoxStyles_h
|
||||
#define mozilla_CachedAnonBoxStyles_h
|
||||
#ifndef mozilla_CachedInheritingStyles_h
|
||||
#define mozilla_CachedInheritingStyles_h
|
||||
|
||||
#include "nsAtom.h"
|
||||
#include "nsTArray.h"
|
||||
|
@ -16,20 +16,20 @@ namespace mozilla {
|
|||
|
||||
class ServoStyleContext;
|
||||
|
||||
// Cache of anonymous box styles that inherit from a given style.
|
||||
// Cache of anonymous box and lazy pseudo styles that inherit from a given style.
|
||||
//
|
||||
// To minimize memory footprint, the cache is word-sized with a tagged pointer
|
||||
// If there is only one entry, it's stored inline. If there are more, they're
|
||||
// stored in an out-of-line buffer. See bug 1429126 comment 0 and comment 1 for
|
||||
// the measurements and rationale that influenced the design.
|
||||
class CachedAnonBoxStyles
|
||||
class CachedInheritingStyles
|
||||
{
|
||||
public:
|
||||
void Insert(ServoStyleContext* aStyle);
|
||||
ServoStyleContext* Lookup(nsAtom* aAnonBox) const;
|
||||
ServoStyleContext* Lookup(nsAtom* aPseudoTag) const;
|
||||
|
||||
CachedAnonBoxStyles() : mBits(0) {}
|
||||
~CachedAnonBoxStyles()
|
||||
CachedInheritingStyles() : mBits(0) {}
|
||||
~CachedInheritingStyles()
|
||||
{
|
||||
if (IsIndirect()) {
|
||||
delete AsIndirect();
|
||||
|
@ -64,4 +64,4 @@ private:
|
|||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_CachedAnonBoxStyles_h
|
||||
#endif // mozilla_CachedInheritingStyles_h
|
|
@ -45,13 +45,7 @@ ServoStyleContext::GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto* current = mNextLazyPseudoStyle.get();
|
||||
|
||||
while (current && current->GetPseudoType() != aPseudo) {
|
||||
current = current->mNextLazyPseudoStyle.get();
|
||||
}
|
||||
|
||||
return current;
|
||||
return mCachedInheritingStyles.Lookup(nsCSSPseudoElements::GetPseudoAtom(aPseudo));
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "nsWindowSizes.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "mozilla/CachedAnonBoxStyles.h"
|
||||
#include "mozilla/CachedInheritingStyles.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -50,13 +50,13 @@ public:
|
|||
ServoStyleContext* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const
|
||||
{
|
||||
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
|
||||
return mInheritingAnonBoxStyles.Lookup(aAnonBox);
|
||||
return mCachedInheritingStyles.Lookup(aAnonBox);
|
||||
}
|
||||
|
||||
void SetCachedInheritedAnonBoxStyle(nsAtom* aAnonBox, ServoStyleContext* aStyle)
|
||||
{
|
||||
MOZ_ASSERT(!GetCachedInheritingAnonBoxStyle(aAnonBox));
|
||||
mInheritingAnonBoxStyles.Insert(aStyle);
|
||||
mCachedInheritingStyles.Insert(aStyle);
|
||||
}
|
||||
|
||||
ServoStyleContext* GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const;
|
||||
|
@ -65,7 +65,6 @@ public:
|
|||
{
|
||||
MOZ_ASSERT(aStyle->GetPseudo() && !aStyle->IsAnonBox());
|
||||
MOZ_ASSERT(!GetCachedLazyPseudoStyle(aStyle->GetPseudoType()));
|
||||
MOZ_ASSERT(!aStyle->mNextLazyPseudoStyle);
|
||||
MOZ_ASSERT(!IsLazilyCascadedPseudoElement(), "lazy pseudos can't inherit lazy pseudos");
|
||||
MOZ_ASSERT(aStyle->IsLazilyCascadedPseudoElement());
|
||||
|
||||
|
@ -82,8 +81,7 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
mNextLazyPseudoStyle.swap(aStyle->mNextLazyPseudoStyle);
|
||||
mNextLazyPseudoStyle = aStyle;
|
||||
mCachedInheritingStyles.Insert(aStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,32 +101,15 @@ public:
|
|||
// clearly identify in DMD's output the memory measured here.
|
||||
*aCVsSize += ServoComputedValuesMallocEnclosingSizeOf(this);
|
||||
mSource.AddSizeOfExcludingThis(aSizes);
|
||||
mInheritingAnonBoxStyles.AddSizeOfIncludingThis(aSizes, aCVsSize);
|
||||
|
||||
if (mNextLazyPseudoStyle &&
|
||||
!aSizes.mState.HaveSeenPtr(mNextLazyPseudoStyle)) {
|
||||
mNextLazyPseudoStyle->AddSizeOfIncludingThis(aSizes, aCVsSize);
|
||||
}
|
||||
mCachedInheritingStyles.AddSizeOfIncludingThis(aSizes, aCVsSize);
|
||||
}
|
||||
|
||||
private:
|
||||
nsPresContext* mPresContext;
|
||||
ServoComputedData mSource;
|
||||
|
||||
// A cache of inheriting anon boxes inheriting from this style _if the style
|
||||
// isn't an inheriting anon-box_.
|
||||
CachedAnonBoxStyles mInheritingAnonBoxStyles;
|
||||
|
||||
// A linked-list cache of lazy pseudo styles inheriting from this style _if
|
||||
// the style isn't a lazy pseudo style itself_.
|
||||
//
|
||||
// Otherwise it represents the next entry in the cache of the parent style
|
||||
// context.
|
||||
//
|
||||
// Note that we store these separately from inheriting anonymous boxes so that
|
||||
// text nodes inheriting from lazy pseudo styles can share styles, which is
|
||||
// very important on some pages.
|
||||
RefPtr<ServoStyleContext> mNextLazyPseudoStyle;
|
||||
// A cache of anonymous box and lazy pseudo styles inheriting from this style.
|
||||
CachedInheritingStyles mCachedInheritingStyles;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -80,7 +80,7 @@ EXPORTS += [
|
|||
EXPORTS.mozilla += [
|
||||
'AnimationCollection.h',
|
||||
'BindingStyleRule.h',
|
||||
'CachedAnonBoxStyles.h',
|
||||
'CachedInheritingStyles.h',
|
||||
'CSSEnabledState.h',
|
||||
'CSSStyleSheet.h',
|
||||
'CSSVariableDeclarations.h',
|
||||
|
@ -179,7 +179,7 @@ EXPORTS.mozilla.css += [
|
|||
UNIFIED_SOURCES += [
|
||||
'AnimationCollection.cpp',
|
||||
'BindingStyleRule.cpp',
|
||||
'CachedAnonBoxStyles.cpp',
|
||||
'CachedInheritingStyles.cpp',
|
||||
'CounterStyleManager.cpp',
|
||||
'CSS.cpp',
|
||||
'CSSFontFeatureValuesRule.cpp',
|
||||
|
|
|
@ -49,16 +49,14 @@ must be one of the following:
|
|||
|
||||
1. Inclusion of another manifest
|
||||
|
||||
<failure-type>* include <relative_path>
|
||||
<skip-type>* include <relative_path>
|
||||
|
||||
<failure-type> is the same as listed below for a test item. As for
|
||||
test items, multiple failure types listed on the same line are
|
||||
combined by using the last matching failure type listed on the line.
|
||||
However, the failure type on a manifest is combined with the failure
|
||||
type on the test (or on a nested manifest) with the rule that the
|
||||
last in the following list wins: fails, random, skip. (In other
|
||||
words, when combining <failure-type> from the manifest include and
|
||||
the test line, skip always wins, and random beats fails.)
|
||||
<skip-type> is one of the skip or skip-if items (see their definitions
|
||||
in <failure-type> below). If any of the skip types evaluate to true (i.e.
|
||||
they are a plain "skip" or they are a "skip-if" with a condition that
|
||||
evaluates to true), then the include statement is skipped. Otherwise,
|
||||
reftests in the specified manifest are included in the set of reftests
|
||||
that are run.
|
||||
|
||||
2. A test item
|
||||
|
||||
|
|
|
@ -31,16 +31,16 @@ function ReadTopManifest(aFileURL, aFilter)
|
|||
throw "Expected a file or http URL for the manifest.";
|
||||
|
||||
g.manifestsLoaded = {};
|
||||
ReadManifest(url, EXPECTED_PASS, aFilter);
|
||||
ReadManifest(url, aFilter);
|
||||
}
|
||||
|
||||
// Note: If you materially change the reftest manifest parsing,
|
||||
// please keep the parser in print-manifest-dirs.py in sync.
|
||||
function ReadManifest(aURL, inherited_status, aFilter)
|
||||
function ReadManifest(aURL, aFilter)
|
||||
{
|
||||
// Ensure each manifest is only read once. This assumes that manifests that are
|
||||
// included with an unusual inherited_status or filters will be read via their
|
||||
// include before they are read directly in the case of a duplicate
|
||||
// Ensure each manifest is only read once. This assumes that manifests that
|
||||
// are included with filters will be read via their include before they are
|
||||
// read directly in the case of a duplicate
|
||||
if (g.manifestsLoaded.hasOwnProperty(aURL.spec)) {
|
||||
if (g.manifestsLoaded[aURL.spec] === null)
|
||||
return;
|
||||
|
@ -132,6 +132,7 @@ function ReadManifest(aURL, inherited_status, aFilter)
|
|||
var fuzzy_delta = { min: 0, max: 2 };
|
||||
var fuzzy_pixels = { min: 0, max: 1 };
|
||||
var chaosMode = false;
|
||||
var nonSkipUsed = false;
|
||||
|
||||
while (items[0].match(/^(fails|needs-focus|random|skip|asserts|slow|require-or|silentfail|pref|test-pref|ref-pref|fuzzy|chaos-mode)/)) {
|
||||
var item = items.shift();
|
||||
|
@ -219,6 +220,10 @@ function ReadManifest(aURL, inherited_status, aFilter)
|
|||
throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": unexpected item " + item;
|
||||
}
|
||||
|
||||
if (stat != "skip") {
|
||||
nonSkipUsed = true;
|
||||
}
|
||||
|
||||
if (cond) {
|
||||
if (stat == "fails") {
|
||||
expected_status = EXPECTED_FAIL;
|
||||
|
@ -232,8 +237,6 @@ function ReadManifest(aURL, inherited_status, aFilter)
|
|||
}
|
||||
}
|
||||
|
||||
expected_status = Math.max(expected_status, inherited_status);
|
||||
|
||||
if (minAsserts > maxAsserts) {
|
||||
throw "Bad range in manifest file " + aURL.spec + " line " + lineNo;
|
||||
}
|
||||
|
@ -271,10 +274,28 @@ function ReadManifest(aURL, inherited_status, aFilter)
|
|||
throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": incorrect number of arguments to include";
|
||||
if (runHttp)
|
||||
throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": use of include with http";
|
||||
var incURI = g.ioService.newURI(items[1], null, listURL);
|
||||
secMan.checkLoadURIWithPrincipal(principal, incURI,
|
||||
CI.nsIScriptSecurityManager.DISALLOW_SCRIPT);
|
||||
ReadManifest(incURI, expected_status, aFilter);
|
||||
|
||||
// If the expected_status is EXPECTED_PASS (the default) then allow
|
||||
// the include. If it is EXPECTED_DEATH, that means there was a skip
|
||||
// or skip-if annotation (with a true condition) on this include
|
||||
// statement, so we should skip the include. Any other expected_status
|
||||
// is disallowed since it's nonintuitive as to what the intended
|
||||
// effect is.
|
||||
if (nonSkipUsed) {
|
||||
throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": include statement with annotation other than 'skip' or 'skip-if'";
|
||||
} else if (expected_status == EXPECTED_DEATH) {
|
||||
g.logger.info("Skipping included manifest at " + aURL.spec + " line " + lineNo + " due to matching skip condition");
|
||||
} else {
|
||||
// poor man's assertion
|
||||
if (expected_status != EXPECTED_PASS) {
|
||||
throw "Error in manifest file parsing code: we should never get expected_status=" + expected_status + " when nonSkipUsed=false (from " + aURL.spec + " line " + lineNo + ")";
|
||||
}
|
||||
|
||||
var incURI = g.ioService.newURI(items[1], null, listURL);
|
||||
secMan.checkLoadURIWithPrincipal(principal, incURI,
|
||||
CI.nsIScriptSecurityManager.DISALLOW_SCRIPT);
|
||||
ReadManifest(incURI, aFilter);
|
||||
}
|
||||
} else if (items[0] == TYPE_LOAD) {
|
||||
if (items.length != 2)
|
||||
throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": incorrect number of arguments to load";
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
The source from this directory was copied from the cubeb
|
||||
git repository using the update.sh script. The only changes
|
||||
made were those applied by update.sh and the addition of
|
||||
Makefile.in build files for the Mozilla build system.
|
||||
made were those applied by update.sh, the addition of
|
||||
Makefile.in build files for the Mozilla build system,
|
||||
and the following patches, which may be overwritten when
|
||||
included upstream.
|
||||
https://github.com/kinetiknz/cubeb/pull/398/commits/c8e66dee61a35e6a6d54e3630e1668bdbd6984b4
|
||||
https://github.com/kinetiknz/cubeb/pull/398/commits/2ed979bc891cf1a7822799947a357d4d3b625964
|
||||
|
||||
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
|
||||
|
||||
|
|
|
@ -497,13 +497,15 @@ TEST(cubeb, resampler_output_only_noop)
|
|||
cubeb_resampler_destroy(resampler);
|
||||
}
|
||||
|
||||
long test_drain_data_cb(cubeb_stream * /*stm*/, void * /*user_ptr*/,
|
||||
long test_drain_data_cb(cubeb_stream * /*stm*/, void * user_ptr,
|
||||
const void * input_buffer,
|
||||
void * output_buffer, long frame_count)
|
||||
{
|
||||
EXPECT_TRUE(output_buffer);
|
||||
EXPECT_TRUE(!input_buffer);
|
||||
return frame_count - 10;
|
||||
auto cb_count = static_cast<int *>(user_ptr);
|
||||
(*cb_count)++;
|
||||
return frame_count - 1;
|
||||
}
|
||||
|
||||
TEST(cubeb, resampler_drain)
|
||||
|
@ -515,10 +517,11 @@ TEST(cubeb, resampler_drain)
|
|||
output_params.channels = 1;
|
||||
output_params.format = CUBEB_SAMPLE_FLOAT32NE;
|
||||
target_rate = 48000;
|
||||
int cb_count = 0;
|
||||
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, nullptr, &output_params, target_rate,
|
||||
test_drain_data_cb, nullptr,
|
||||
test_drain_data_cb, &cb_count,
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
const long out_frames = 128;
|
||||
|
@ -530,9 +533,9 @@ TEST(cubeb, resampler_drain)
|
|||
out_buffer, out_frames);
|
||||
} while (got == out_frames);
|
||||
|
||||
/* If the above is not an infinite loop, the drain was a success, just mark
|
||||
* this test as such. */
|
||||
ASSERT_TRUE(true);
|
||||
/* The callback should be called once but not again after returning <
|
||||
* frame_count. */
|
||||
ASSERT_EQ(cb_count, 1);
|
||||
|
||||
cubeb_resampler_destroy(resampler);
|
||||
}
|
||||
|
|
|
@ -145,27 +145,33 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
|||
assert(!input_buffer && (!input_frames_count || *input_frames_count == 0) &&
|
||||
output_buffer && output_frames_needed);
|
||||
|
||||
long got = 0;
|
||||
T * out_unprocessed = nullptr;
|
||||
long output_frames_before_processing = 0;
|
||||
if (!draining) {
|
||||
long got = 0;
|
||||
T * out_unprocessed = nullptr;
|
||||
long output_frames_before_processing = 0;
|
||||
|
||||
/* fill directly the input buffer of the output processor to save a copy */
|
||||
output_frames_before_processing =
|
||||
output_processor->input_needed_for_output(output_frames_needed);
|
||||
/* fill directly the input buffer of the output processor to save a copy */
|
||||
output_frames_before_processing =
|
||||
output_processor->input_needed_for_output(output_frames_needed);
|
||||
|
||||
out_unprocessed =
|
||||
output_processor->input_buffer(output_frames_before_processing);
|
||||
out_unprocessed =
|
||||
output_processor->input_buffer(output_frames_before_processing);
|
||||
|
||||
got = data_callback(stream, user_ptr,
|
||||
nullptr, out_unprocessed,
|
||||
output_frames_before_processing);
|
||||
got = data_callback(stream, user_ptr,
|
||||
nullptr, out_unprocessed,
|
||||
output_frames_before_processing);
|
||||
|
||||
if (got < 0) {
|
||||
return got;
|
||||
if (got < output_frames_before_processing) {
|
||||
draining = true;
|
||||
|
||||
if (got < 0) {
|
||||
return got;
|
||||
}
|
||||
}
|
||||
|
||||
output_processor->written(got);
|
||||
}
|
||||
|
||||
output_processor->written(got);
|
||||
|
||||
/* Process the output. If not enough frames have been returned from the
|
||||
* callback, drain the processors. */
|
||||
return output_processor->output(output_buffer, output_frames_needed);
|
||||
|
@ -204,11 +210,16 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
|||
::fill_internal_duplex(T * in_buffer, long * input_frames_count,
|
||||
T * out_buffer, long output_frames_needed)
|
||||
{
|
||||
if (draining) {
|
||||
// discard input and drain any signal remaining in the resampler.
|
||||
return output_processor->output(out_buffer, output_frames_needed);
|
||||
}
|
||||
|
||||
/* The input data, after eventual resampling. This is passed to the callback. */
|
||||
T * resampled_input = nullptr;
|
||||
/* The output buffer passed down in the callback, that might be resampled. */
|
||||
T * out_unprocessed = nullptr;
|
||||
size_t output_frames_before_processing = 0;
|
||||
long output_frames_before_processing = 0;
|
||||
/* The number of frames returned from the callback. */
|
||||
long got = 0;
|
||||
|
||||
|
@ -243,8 +254,12 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
|||
resampled_input, out_unprocessed,
|
||||
output_frames_before_processing);
|
||||
|
||||
if (got < 0) {
|
||||
return got;
|
||||
if (got < output_frames_before_processing) {
|
||||
draining = true;
|
||||
|
||||
if (got < 0) {
|
||||
return got;
|
||||
}
|
||||
}
|
||||
|
||||
output_processor->written(got);
|
||||
|
|
|
@ -62,11 +62,11 @@ public:
|
|||
: channels(channels)
|
||||
{}
|
||||
protected:
|
||||
size_t frames_to_samples(size_t frames)
|
||||
size_t frames_to_samples(size_t frames) const
|
||||
{
|
||||
return frames * channels;
|
||||
}
|
||||
size_t samples_to_frames(size_t samples)
|
||||
size_t samples_to_frames(size_t samples) const
|
||||
{
|
||||
assert(!(samples % channels));
|
||||
return samples / channels;
|
||||
|
@ -157,6 +157,7 @@ private:
|
|||
cubeb_stream * const stream;
|
||||
const cubeb_data_callback data_callback;
|
||||
void * const user_ptr;
|
||||
bool draining = false;
|
||||
};
|
||||
|
||||
/** Handles one way of a (possibly) duplex resampler, working on interleaved
|
||||
|
@ -282,7 +283,7 @@ public:
|
|||
* exactly `output_frame_count` resampled frames. This can return a number
|
||||
* slightly bigger than what is strictly necessary, but it guaranteed that the
|
||||
* number of output frames will be exactly equal. */
|
||||
uint32_t input_needed_for_output(uint32_t output_frame_count)
|
||||
uint32_t input_needed_for_output(uint32_t output_frame_count) const
|
||||
{
|
||||
int32_t unresampled_frames_left = samples_to_frames(resampling_in_buffer.length());
|
||||
int32_t resampled_frames_left = samples_to_frames(resampling_out_buffer.length());
|
||||
|
@ -461,7 +462,7 @@ public:
|
|||
* @parameter frames_needed the number of frames one want to write into the
|
||||
* delay_line
|
||||
* @returns the number of frames one will get. */
|
||||
size_t input_needed_for_output(uint32_t frames_needed)
|
||||
size_t input_needed_for_output(uint32_t frames_needed) const
|
||||
{
|
||||
return frames_needed;
|
||||
}
|
||||
|
|
|
@ -84,11 +84,12 @@ def main():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.platform == 'darwin':
|
||||
if sys.platform == 'darwin' or os.environ.get('MOZ_AUTOMATION') != '1':
|
||||
print main()
|
||||
else:
|
||||
# Mozilla builds cross-compile on Linux, so return some fake data to keep
|
||||
# the build system happy. These values aren't used anywhere.
|
||||
# Mozilla builds cross-compile on Linux or install an SDK from tooltool, so
|
||||
# return some fake data to keep the build system happy. These values aren't
|
||||
# used anywhere.
|
||||
print "."
|
||||
print "."
|
||||
sys.exit(0)
|
||||
|
|
|
@ -296,7 +296,7 @@ public class GeckoSession extends LayerSession
|
|||
}
|
||||
|
||||
@Override // IInterface
|
||||
public IBinder asBinder() {
|
||||
public Binder asBinder() {
|
||||
if (mBinder == null) {
|
||||
mBinder = new Binder();
|
||||
mBinder.attachInterface(this, Window.class.getName());
|
||||
|
@ -310,8 +310,22 @@ public class GeckoSession extends LayerSession
|
|||
GeckoBundle settings, String chromeUri,
|
||||
int screenId, boolean privateMode);
|
||||
|
||||
@WrapForJNI(dispatchTo = "proxy")
|
||||
@Override protected native void disposeNative();
|
||||
@Override // JNIObject
|
||||
protected void disposeNative() {
|
||||
// Detach ourselves from the binder as well, to prevent this window from being
|
||||
// read from any parcels.
|
||||
asBinder().attachInterface(null, Window.class.getName());
|
||||
|
||||
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
|
||||
nativeDisposeNative();
|
||||
} else {
|
||||
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
|
||||
this, "nativeDisposeNative");
|
||||
}
|
||||
}
|
||||
|
||||
@WrapForJNI(dispatchTo = "proxy", stubName = "DisposeNative")
|
||||
private native void nativeDisposeNative();
|
||||
|
||||
@WrapForJNI(dispatchTo = "proxy")
|
||||
public native void close();
|
||||
|
@ -528,14 +542,12 @@ public class GeckoSession extends LayerSession
|
|||
|
||||
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
|
||||
mWindow.close();
|
||||
mWindow.disposeNative();
|
||||
} else {
|
||||
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
|
||||
mWindow, "close");
|
||||
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
|
||||
mWindow, "disposeNative");
|
||||
}
|
||||
|
||||
mWindow.disposeNative();
|
||||
mWindow = null;
|
||||
onWindowChanged();
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ DEFINES += \
|
|||
-DPREF_DIR=$(PREF_DIR) \
|
||||
-DJAREXT= \
|
||||
-DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME) \
|
||||
-DMOZ_CHILD_PROCESS_NAME_PIE=$(MOZ_CHILD_PROCESS_NAME_PIE) \
|
||||
-DANDROID_CPU_ARCH=$(ANDROID_CPU_ARCH) \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
@BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
|
||||
# This should be MOZ_CHILD_PROCESS_NAME, but that has a "lib/" prefix.
|
||||
@BINPATH@/@MOZ_CHILD_PROCESS_NAME@
|
||||
@BINPATH@/@MOZ_CHILD_PROCESS_NAME_PIE@
|
||||
|
||||
#ifdef MOZ_ANDROID_GOOGLE_VR
|
||||
@BINPATH@/@DLL_PREFIX@gvr@DLL_SUFFIX@
|
||||
|
|
|
@ -445,7 +445,7 @@ Http2Session::AddStream(nsAHttpTransaction *aHttpTransaction,
|
|||
}
|
||||
|
||||
aHttpTransaction->SetConnection(this);
|
||||
aHttpTransaction->OnActivated(true);
|
||||
aHttpTransaction->OnActivated();
|
||||
|
||||
if (aUseTunnel) {
|
||||
LOG3(("Http2Session::AddStream session=%p trans=%p OnTunnel",
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
|
||||
// called by the connection after a successfull activation of this transaction
|
||||
// in other words, tells the transaction it transitioned to the "active" state.
|
||||
virtual void OnActivated(bool h2) {}
|
||||
virtual void OnActivated() {}
|
||||
|
||||
// used to obtain the connection associated with this transaction
|
||||
virtual nsAHttpConnection *Connection() = 0;
|
||||
|
|
|
@ -730,7 +730,7 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
|
|||
mTransaction = mTLSFilter;
|
||||
}
|
||||
|
||||
trans->OnActivated(false);
|
||||
trans->OnActivated();
|
||||
|
||||
rv = OnOutputStreamReady(mSocketOut);
|
||||
|
||||
|
|
|
@ -111,7 +111,6 @@ nsHttpTransaction::nsHttpTransaction()
|
|||
, mClosed(false)
|
||||
, mConnected(false)
|
||||
, mActivated(false)
|
||||
, mActivatedAsH2(false)
|
||||
, mHaveStatusLine(false)
|
||||
, mHaveAllHeaders(false)
|
||||
, mTransactionDone(false)
|
||||
|
@ -175,6 +174,7 @@ void nsHttpTransaction::ResumeReading()
|
|||
mThrottlingReadAllowance = THROTTLE_NO_LIMIT;
|
||||
|
||||
if (mConnection) {
|
||||
mConnection->TransactionHasDataToRecv(this);
|
||||
nsresult rv = mConnection->ResumeRecv();
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG((" resume failed with rv=%" PRIx32, static_cast<uint32_t>(rv)));
|
||||
|
@ -539,11 +539,10 @@ nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
|
|||
}
|
||||
|
||||
void
|
||||
nsHttpTransaction::OnActivated(bool h2)
|
||||
nsHttpTransaction::OnActivated()
|
||||
{
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
mActivatedAsH2 = h2;
|
||||
if (mActivated) {
|
||||
return;
|
||||
}
|
||||
|
@ -875,17 +874,6 @@ nsHttpTransaction::WritePipeSegment(nsIOutputStream *stream,
|
|||
|
||||
bool nsHttpTransaction::ShouldThrottle()
|
||||
{
|
||||
if (mActivatedAsH2) {
|
||||
// Throttling feature is now disabled for http/2 transactions
|
||||
// because of bug 1367861. The logic around mActivatedAsH2
|
||||
// will be removed when that is fixed.
|
||||
//
|
||||
// Calling ShouldThrottle on the manager just to make sure
|
||||
// the throttling time window is correctly updated by this transaction.
|
||||
Unused << gHttpHandler->ConnMgr()->ShouldThrottle(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mClassOfService & nsIClassOfService::DontThrottle) {
|
||||
// We deliberately don't touch the throttling window here since
|
||||
// DontThrottle requests are expected to be long-standing media
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
uint64_t topLevelOuterContentWindowId,
|
||||
nsIAsyncInputStream **responseBody);
|
||||
|
||||
void OnActivated(bool h2) override;
|
||||
void OnActivated() override;
|
||||
|
||||
// attributes
|
||||
nsHttpResponseHead *ResponseHead() { return mHaveAllHeaders ? mResponseHead : nullptr; }
|
||||
|
@ -349,7 +349,6 @@ private:
|
|||
bool mClosed;
|
||||
bool mConnected;
|
||||
bool mActivated;
|
||||
bool mActivatedAsH2;
|
||||
bool mHaveStatusLine;
|
||||
bool mHaveAllHeaders;
|
||||
bool mTransactionDone;
|
||||
|
|
|
@ -4431,8 +4431,6 @@ else
|
|||
# because the unpacked file will be under the lib/ subdirectory and will
|
||||
# need to be executed from that path.
|
||||
MOZ_CHILD_PROCESS_NAME="libplugin-container.so"
|
||||
MOZ_CHILD_PROCESS_NAME_PIE="libplugin-container-pie.so"
|
||||
AC_SUBST(MOZ_CHILD_PROCESS_NAME_PIE)
|
||||
fi
|
||||
MOZ_CHILD_PROCESS_BUNDLE="plugin-container.app/Contents/MacOS/"
|
||||
MOZ_CHILD_PROCESS_BUNDLENAME="${MOZ_APP_DISPLAYNAME}CP"
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -73,7 +73,7 @@ linux-rel-nogate:
|
|||
- ./mach clean-nightlies --keep 3 --force
|
||||
- env CC=gcc-5 CXX=g++-5 ./mach build --release
|
||||
- python ./etc/ci/chaos_monkey_test.py
|
||||
- env CC=gcc-5 CXX=g++-5 bash ./etc/ci/mutation_test.sh
|
||||
- env CC=gcc-5 CXX=g++-5 RUSTFLAGS= bash ./etc/ci/mutation_test.sh
|
||||
|
||||
mac-rel-intermittent:
|
||||
- ./mach clean-nightlies --keep 3 --force
|
||||
|
|
|
@ -32,7 +32,7 @@ fn size_of_selectors_dummy_types() {
|
|||
size_of_test!(test_size_of_rule, style::stylist::Rule, 32);
|
||||
|
||||
// Large pages generate tens of thousands of ComputedValues.
|
||||
size_of_test!(test_size_of_cv, ComputedValues, 256);
|
||||
size_of_test!(test_size_of_cv, ComputedValues, 248);
|
||||
|
||||
size_of_test!(test_size_of_option_arc_cv, Option<Arc<ComputedValues>>, 8);
|
||||
size_of_test!(test_size_of_option_rule_node, Option<StrongRuleNode>, 8);
|
||||
|
|
|
@ -27,6 +27,7 @@ jobs:
|
|||
symbol: I(toolchain)
|
||||
packages:
|
||||
- deb7-cmake
|
||||
- deb7-mercurial
|
||||
- deb7-ninja
|
||||
- deb7-python
|
||||
lint:
|
||||
|
|
|
@ -25,8 +25,9 @@ jobs:
|
|||
symbol: Deb7(python)
|
||||
run:
|
||||
using: debian-package
|
||||
dsc: "http://snapshot.debian.org/archive/debian/20160813T164221Z/pool/main/p/python2.7/python2.7_2.7.9-2+deb8u1.dsc"
|
||||
dsc-sha256: 274c293e7156edf59cb9f0a9d8cedcd94fa801df35adf39b8a9f3d776a250ead
|
||||
dsc:
|
||||
url: http://snapshot.debian.org/archive/debian/20160813T164221Z/pool/main/p/python2.7/python2.7_2.7.9-2+deb8u1.dsc
|
||||
sha256: 274c293e7156edf59cb9f0a9d8cedcd94fa801df35adf39b8a9f3d776a250ead
|
||||
patch: python-wheezy.diff
|
||||
pre-build-command: debian/rules control-file
|
||||
|
||||
|
@ -36,8 +37,9 @@ jobs:
|
|||
symbol: Deb7(cmake)
|
||||
run:
|
||||
using: debian-package
|
||||
dsc: "http://snapshot.debian.org/archive/debian-debug/20161204T031605Z/pool/main/c/cmake/cmake_3.7.1-1.dsc"
|
||||
dsc-sha256: 406a12c0d0a2e92d44a8d444fd1b32bcc29a8810e9631427161a7cb411f60172
|
||||
dsc:
|
||||
url: http://snapshot.debian.org/archive/debian-debug/20161204T031605Z/pool/main/c/cmake/cmake_3.7.1-1.dsc
|
||||
sha256: 406a12c0d0a2e92d44a8d444fd1b32bcc29a8810e9631427161a7cb411f60172
|
||||
patch: cmake-wheezy.diff
|
||||
|
||||
deb7-ninja:
|
||||
|
@ -46,6 +48,33 @@ jobs:
|
|||
symbol: Deb7(ninja)
|
||||
run:
|
||||
using: debian-package
|
||||
dsc: "http://snapshot.debian.org/archive/debian-debug/20160209T034956Z/pool/main/n/ninja-build/ninja-build_1.6.0-1.dsc"
|
||||
dsc-sha256: 25cd62b011d669c31bcd51d36d454dd826bc50af6a3af8d87bcab8948ec21626
|
||||
dsc:
|
||||
url: http://snapshot.debian.org/archive/debian-debug/20160209T034956Z/pool/main/n/ninja-build/ninja-build_1.6.0-1.dsc
|
||||
sha256: 25cd62b011d669c31bcd51d36d454dd826bc50af6a3af8d87bcab8948ec21626
|
||||
patch: ninja-wheezy.diff
|
||||
|
||||
deb7-mercurial:
|
||||
description: "Modern Mercurial for Debian wheezy"
|
||||
treeherder:
|
||||
symbol: Deb7(hg)
|
||||
run:
|
||||
using: debian-package
|
||||
tarball:
|
||||
url: https://www.mercurial-scm.org/release/mercurial-4.4.2.tar.gz
|
||||
sha256: dc2f72caccd6b760226753d48c2f4e8889fe176a6b23ef50775caac55ce28b85
|
||||
pre-build-command: >-
|
||||
cp -r contrib/debian debian &&
|
||||
sed -i -e "s/__VERSION__/$(awk -F\" '$2 {print $2}' mercurial/__version__.py)-1.deb7moz1/" \
|
||||
-e "s/__DATE__/$(date --rfc-2822)/" \
|
||||
-e "s/__CODENAME__/wheezy/" debian/changelog
|
||||
|
||||
deb7-valgrind:
|
||||
description: "Valgrind for Debian Wheezy"
|
||||
treeherder:
|
||||
symbol: Deb7(valgrind)
|
||||
run:
|
||||
using: debian-package
|
||||
dsc:
|
||||
url: http://snapshot.debian.org/archive/debian/20170725T040438Z/pool/main/v/valgrind/valgrind_3.13.0-1.dsc
|
||||
sha256: ab84e017d1660efd30e9e0593a4c8b976aeda013cefb8c416dd284cc7222c11c
|
||||
patch: valgrind-wheezy.diff
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# By default the progress bar starts after 3s and updates every 0.1s. We
|
||||
# change this so it shows and updates every 1.0s.
|
||||
# We also tell progress to assume a TTY is present so updates are printed
|
||||
# even if there is no known TTY.
|
||||
[progress]
|
||||
delay = 1.0
|
||||
refresh = 1.0
|
||||
assume-tty = true
|
||||
|
||||
[extensions]
|
||||
share =
|
||||
sparse =
|
||||
robustcheckout = /usr/local/mercurial/robustcheckout.py
|
||||
|
||||
[hostsecurity]
|
||||
# When running a modern Python, Mercurial will default to TLS 1.1+.
|
||||
# When running on a legacy Python, Mercurial will default to TLS 1.0+.
|
||||
# There is no good reason we shouldn't be running a modern Python
|
||||
# capable of speaking TLS 1.2. And the only Mercurial servers we care
|
||||
# about should be running TLS 1.2. So make TLS 1.2 the minimum.
|
||||
minimumprotocol = tls1.2
|
||||
|
||||
# Settings to make 1-click loaners more useful.
|
||||
[extensions]
|
||||
histedit =
|
||||
rebase =
|
||||
|
||||
[diff]
|
||||
git = 1
|
||||
showfunc = 1
|
||||
|
||||
[pager]
|
||||
pager = LESS=FRSXQ less
|
|
@ -62,6 +62,7 @@ RUN apt-get -o Acquire::Check-Valid-Until=false update -q && \
|
|||
libtool \
|
||||
libx11-dev:i386 \
|
||||
make \
|
||||
mercurial \
|
||||
ninja-build \
|
||||
p7zip-full \
|
||||
procps \
|
||||
|
@ -83,22 +84,11 @@ RUN apt-get -o Acquire::Check-Valid-Until=false update -q && \
|
|||
&& \
|
||||
apt-get clean
|
||||
|
||||
# %include python/mozbuild/mozbuild/action/tooltool.py
|
||||
COPY topsrcdir/python/mozbuild/mozbuild/action/tooltool.py /setup/tooltool.py
|
||||
|
||||
# %include testing/mozharness/external_tools/robustcheckout.py
|
||||
COPY topsrcdir/testing/mozharness/external_tools/robustcheckout.py /usr/local/mercurial/robustcheckout.py
|
||||
|
||||
# %include taskcluster/docker/recipes/common.sh
|
||||
COPY topsrcdir/taskcluster/docker/recipes/common.sh /setup/common.sh
|
||||
|
||||
# %include taskcluster/docker/recipes/install-mercurial.sh
|
||||
COPY topsrcdir/taskcluster/docker/recipes/install-mercurial.sh /setup/install-mercurial.sh
|
||||
|
||||
# %include taskcluster/docker/recipes/debian-build-system-setup.sh
|
||||
COPY topsrcdir/taskcluster/docker/recipes/debian-build-system-setup.sh /setup/system-setup.sh
|
||||
|
||||
RUN bash /setup/system-setup.sh
|
||||
# %include taskcluster/docker/recipes/hgrc
|
||||
COPY topsrcdir/taskcluster/docker/recipes/hgrc /etc/mercurial/hgrc.d/mozilla.rc
|
||||
|
||||
# Add pip configuration, among other things.
|
||||
# %include taskcluster/docker/recipes/dot-config
|
||||
|
|
|
@ -8,9 +8,10 @@ Support for running spidermonkey jobs via dedicated scripts
|
|||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from taskgraph.util.schema import Schema
|
||||
from voluptuous import Optional, Required
|
||||
from voluptuous import Any, Optional, Required
|
||||
|
||||
from taskgraph.transforms.job import run_job_using
|
||||
from taskgraph.transforms.job.common import add_public_artifacts
|
||||
|
@ -19,6 +20,14 @@ from taskgraph.util.hash import hash_paths
|
|||
from taskgraph import GECKO
|
||||
from taskgraph.util.cached_tasks import add_optimization
|
||||
|
||||
DSC_PACKAGE_RE = re.compile('.*(?=_)')
|
||||
SOURCE_PACKAGE_RE = re.compile('.*(?=[-_]\d)')
|
||||
|
||||
source_definition = {
|
||||
Required('url'): basestring,
|
||||
Required('sha256'): basestring,
|
||||
}
|
||||
|
||||
run_schema = Schema({
|
||||
Required('using'): 'debian-package',
|
||||
# Debian distribution
|
||||
|
@ -29,11 +38,9 @@ run_schema = Schema({
|
|||
# (only the YYYYMMDD part).
|
||||
Optional('snapshot'): basestring,
|
||||
|
||||
# URL of the source control (.dsc) file to build.
|
||||
Required('dsc'): basestring,
|
||||
|
||||
# SHA256 of the source control (.dsc) file.
|
||||
Required('dsc-sha256'): basestring,
|
||||
# URL/SHA256 of a source file to build, which can either be a source
|
||||
# control (.dsc), or a tarball.
|
||||
Required(Any('dsc', 'tarball')): source_definition,
|
||||
|
||||
# Patch to apply to the extracted source.
|
||||
Optional('patch'): basestring,
|
||||
|
@ -57,8 +64,22 @@ def docker_worker_debian_package(config, job, taskdesc):
|
|||
|
||||
add_public_artifacts(config, job, taskdesc, path='/tmp/artifacts')
|
||||
|
||||
dsc_file = os.path.basename(run['dsc'])
|
||||
package = dsc_file[:dsc_file.index('_')]
|
||||
if 'dsc' in run:
|
||||
src = run['dsc']
|
||||
unpack = 'dpkg-source -x {src_file} {package}'
|
||||
package_re = DSC_PACKAGE_RE
|
||||
elif 'tarball' in run:
|
||||
src = run['tarball']
|
||||
unpack = ('mkdir {package} && '
|
||||
'tar -C {package} -axf {src_file} --strip-components=1')
|
||||
package_re = SOURCE_PACKAGE_RE
|
||||
else:
|
||||
raise RuntimeError('Unreachable')
|
||||
src_url = src['url']
|
||||
src_file = os.path.basename(src_url)
|
||||
src_sha256 = src['sha256']
|
||||
package = package_re.match(src_file).group(0)
|
||||
unpack = unpack.format(src_file=src_file, package=package)
|
||||
|
||||
adjust = ''
|
||||
if 'patch' in run:
|
||||
|
@ -73,6 +94,12 @@ def docker_worker_debian_package(config, job, taskdesc):
|
|||
)
|
||||
if 'pre-build-command' in run:
|
||||
adjust += run['pre-build-command'] + ' && '
|
||||
if 'tarball' in run:
|
||||
adjust += 'mv ../{src_file} ../{package}_{ver}.orig.tar.gz && '.format(
|
||||
src_file=src_file,
|
||||
package=package,
|
||||
ver='$(dpkg-parsechangelog | awk \'$1=="Version:"{print $2}\' | cut -f 1 -d -)',
|
||||
)
|
||||
|
||||
# We can't depend on docker images (since docker images depend on packages),
|
||||
# so we inline the whole script here.
|
||||
|
@ -85,6 +112,8 @@ def docker_worker_debian_package(config, job, taskdesc):
|
|||
'/{snapshot}/ {dist} main" > /etc/apt/sources.list && '
|
||||
'echo "deb http://snapshot.debian.org/archive/debian'
|
||||
'/{snapshot}/ {dist}-updates main" >> /etc/apt/sources.list && '
|
||||
'echo "deb http://snapshot.debian.org/archive/debian'
|
||||
'/{snapshot}/ {dist}-backports main" >> /etc/apt/sources.list && '
|
||||
'echo "deb http://snapshot.debian.org/archive/debian-security'
|
||||
'/{snapshot}/ {dist}/updates main" >> /etc/apt/sources.list && '
|
||||
# Install the base utilities required to build debian packages.
|
||||
|
@ -92,9 +121,9 @@ def docker_worker_debian_package(config, job, taskdesc):
|
|||
'apt-get install -yyq fakeroot build-essential devscripts apt-utils && '
|
||||
'cd /tmp && '
|
||||
# Get, validate and extract the package source.
|
||||
'dget -d -u {dsc} && '
|
||||
'echo "{dsc_sha256} {dsc_file}" | sha256sum -c && '
|
||||
'dpkg-source -x {dsc_file} {package} && '
|
||||
'dget -d -u {src_url} && '
|
||||
'echo "{src_sha256} {src_file}" | sha256sum -c && '
|
||||
'{unpack} && '
|
||||
'cd {package} && '
|
||||
# Optionally apply patch and/or pre-build command.
|
||||
'{adjust}'
|
||||
|
@ -115,9 +144,10 @@ def docker_worker_debian_package(config, job, taskdesc):
|
|||
package=package,
|
||||
snapshot=run['snapshot'],
|
||||
dist=run['dist'],
|
||||
dsc=run['dsc'],
|
||||
dsc_file=dsc_file,
|
||||
dsc_sha256=run['dsc-sha256'],
|
||||
src_url=src_url,
|
||||
src_file=src_file,
|
||||
src_sha256=src_sha256,
|
||||
unpack=unpack,
|
||||
adjust=adjust,
|
||||
artifacts='/tmp/artifacts',
|
||||
)
|
||||
|
@ -131,8 +161,9 @@ def docker_worker_debian_package(config, job, taskdesc):
|
|||
if 'patch' in run:
|
||||
files.append('build/debian-packages/{}'.format(run['patch']))
|
||||
data = [hash_paths(GECKO, files)]
|
||||
for k in ('snapshot', 'dist', 'dsc-sha256', 'pre-build-command'):
|
||||
for k in ('snapshot', 'dist', 'pre-build-command'):
|
||||
if k in run:
|
||||
data.append(run[k])
|
||||
data.append(src['sha256'])
|
||||
add_optimization(config, taskdesc, cache_type='packages.v1',
|
||||
cache_name=name, digest_data=data)
|
||||
|
|
|
@ -161,16 +161,28 @@ def check_schema(schema):
|
|||
return any(f(path) for f in WHITELISTED_SCHEMA_IDENTIFIERS)
|
||||
|
||||
def iter(path, sch):
|
||||
def check_identifier(path, k):
|
||||
if k in (basestring, voluptuous.Extra):
|
||||
pass
|
||||
elif isinstance(k, basestring):
|
||||
if not identifier_re.match(k) and not whitelisted(path):
|
||||
raise RuntimeError(
|
||||
'YAML schemas should use dashed lower-case identifiers, '
|
||||
'not {!r} @ {}'.format(k, path))
|
||||
elif isinstance(k, (voluptuous.Optional, voluptuous.Required)):
|
||||
check_identifier(path, k.schema)
|
||||
elif isinstance(k, voluptuous.Any):
|
||||
for v in k.validators:
|
||||
check_identifier(path, v)
|
||||
elif not whitelisted(path):
|
||||
raise RuntimeError(
|
||||
'Unexpected type in YAML schema: {} @ {}'.format(
|
||||
type(k).__name__, path))
|
||||
|
||||
if isinstance(sch, collections.Mapping):
|
||||
for k, v in sch.iteritems():
|
||||
child = "{}[{!r}]".format(path, k)
|
||||
if isinstance(k, (voluptuous.Optional, voluptuous.Required)):
|
||||
k = str(k)
|
||||
if isinstance(k, basestring):
|
||||
if not identifier_re.match(k) and not whitelisted(child):
|
||||
raise RuntimeError(
|
||||
'YAML schemas should use dashed lower-case identifiers, '
|
||||
'not {!r} @ {}'.format(k, child))
|
||||
check_identifier(child, k)
|
||||
iter(child, v)
|
||||
elif isinstance(sch, (list, tuple)):
|
||||
for i, v in enumerate(sch):
|
||||
|
|
|
@ -128,7 +128,7 @@ class TestTab(PuppeteerMixin, MarionetteTestCase):
|
|||
self.assertEqual(tab.window, self.browser)
|
||||
|
||||
self.assertEqual(tab.tab_element.get_property('localName'), 'tab')
|
||||
self.assertEqual(tab.close_button.get_property('localName'), 'toolbarbutton')
|
||||
self.assertEqual(tab.close_button.get_property('localName'), 'image')
|
||||
|
||||
def test_certificate(self):
|
||||
url = self.marionette.absolute_url('layout/mozilla.html')
|
||||
|
|
|
@ -150,8 +150,8 @@ this.GeckoDriver = function(appId, server) {
|
|||
this.capabilities = new session.Capabilities();
|
||||
|
||||
this.mm = globalMessageManager;
|
||||
this.listener = proxy.toListener(() => this.mm, this.sendAsync.bind(this),
|
||||
() => this.curBrowser);
|
||||
this.listener = proxy.toListener(
|
||||
this.sendAsync.bind(this), () => this.curBrowser);
|
||||
|
||||
// points to an alert instance if a modal dialog is present
|
||||
this.dialog = null;
|
||||
|
|
|
@ -627,9 +627,7 @@ function deregister() {
|
|||
* an empty dictionary.
|
||||
*/
|
||||
function sendToServer(uuid, data = undefined) {
|
||||
let channel = new proxy.AsyncMessageChannel(
|
||||
() => this,
|
||||
sendAsyncMessage.bind(this));
|
||||
let channel = new proxy.AsyncMessageChannel(sendAsyncMessage.bind(this));
|
||||
channel.reply(uuid, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,11 @@ this.EXPORTED_SYMBOLS = ["proxy"];
|
|||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this, "uuidgen", "@mozilla.org/uuid-generator;1", "nsIUUIDGenerator");
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this, "globalMessageManager", "@mozilla.org/globalmessagemanager;1",
|
||||
"nsIMessageBroadcaster");
|
||||
|
||||
const logger = Log.repository.getLogger("Marionette");
|
||||
const log = Log.repository.getLogger("Marionette");
|
||||
|
||||
// Proxy handler that traps requests to get a property. Will prioritise
|
||||
// properties that exist on the object's own prototype.
|
||||
|
@ -50,14 +53,13 @@ this.proxy = {};
|
|||
* passed literally. The latter specialisation is temporary to achieve
|
||||
* backwards compatibility with listener.js.
|
||||
*
|
||||
* @param {function(): (nsIMessageSender|nsIMessageBroadcaster)} mmFn
|
||||
* Closure function returning the current message manager.
|
||||
* @param {function(string, Object, number)} sendAsyncFn
|
||||
* Callback for sending async messages.
|
||||
* @param {function(): browser.Context} browserFn
|
||||
* Closure that returns the current browsing context.
|
||||
*/
|
||||
proxy.toListener = function(mmFn, sendAsyncFn, browserFn) {
|
||||
let sender = new proxy.AsyncMessageChannel(
|
||||
mmFn, sendAsyncFn, browserFn);
|
||||
proxy.toListener = function(sendAsyncFn, browserFn) {
|
||||
let sender = new proxy.AsyncMessageChannel(sendAsyncFn, browserFn);
|
||||
return new Proxy(sender, ownPriorityGetterTrap);
|
||||
};
|
||||
|
||||
|
@ -71,8 +73,7 @@ proxy.toListener = function(mmFn, sendAsyncFn, browserFn) {
|
|||
* <code>.reply(...)</code>.
|
||||
*/
|
||||
proxy.AsyncMessageChannel = class {
|
||||
constructor(mmFn, sendAsyncFn, browserFn) {
|
||||
this.mmFn_ = mmFn;
|
||||
constructor(sendAsyncFn, browserFn) {
|
||||
this.sendAsync = sendAsyncFn;
|
||||
this.browserFn_ = browserFn;
|
||||
|
||||
|
@ -88,10 +89,6 @@ proxy.AsyncMessageChannel = class {
|
|||
return this.browserFn_();
|
||||
}
|
||||
|
||||
get mm() {
|
||||
return this.mmFn_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message across the channel. The name of the function to
|
||||
* call must be registered as a message listener.
|
||||
|
@ -150,7 +147,7 @@ proxy.AsyncMessageChannel = class {
|
|||
// The currently selected tab or window has been closed. No clean-up
|
||||
// is necessary to do because all loaded listeners are gone.
|
||||
this.closeHandler = ({type, target}) => {
|
||||
logger.debug(`Received DOM event ${type} for ${target}`);
|
||||
log.debug(`Received DOM event ${type} for ${target}`);
|
||||
|
||||
switch (type) {
|
||||
case "TabClose":
|
||||
|
@ -165,7 +162,7 @@ proxy.AsyncMessageChannel = class {
|
|||
// the active command has to be aborted. Therefore remove all handlers,
|
||||
// and cancel any ongoing requests in the listener.
|
||||
this.dialogueObserver_ = (subject, topic) => {
|
||||
logger.debug(`Received observer notification ${topic}`);
|
||||
log.debug(`Received observer notification ${topic}`);
|
||||
|
||||
this.removeAllListeners_();
|
||||
// TODO(ato): It's not ideal to have listener specific behaviour here:
|
||||
|
@ -294,7 +291,7 @@ proxy.AsyncMessageChannel = class {
|
|||
callback(msg);
|
||||
};
|
||||
|
||||
this.mm.addMessageListener(path, autoRemover);
|
||||
globalMessageManager.addMessageListener(path, autoRemover);
|
||||
this.listeners_.set(path, autoRemover);
|
||||
}
|
||||
|
||||
|
@ -304,7 +301,7 @@ proxy.AsyncMessageChannel = class {
|
|||
}
|
||||
|
||||
let l = this.listeners_.get(path);
|
||||
this.mm.removeMessageListener(path, l[1]);
|
||||
globalMessageManager.removeMessageListener(path, l[1]);
|
||||
return this.listeners_.delete(path);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<html>
|
||||
<head>
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>DAMP - Devtools At Maximum Performance</title>
|
||||
|
||||
|
@ -29,6 +29,7 @@ var defaultConfig = {
|
|||
"complicated.saveAndReadHeapSnapshot": true,
|
||||
|
||||
"custom.inspector": true,
|
||||
"custom.debugger": true,
|
||||
|
||||
"console.bulklog": true,
|
||||
"console.streamlog": true,
|
||||
|
|
|
@ -37,6 +37,150 @@ function getActiveTab(window) {
|
|||
return window.gBrowser.selectedTab;
|
||||
}
|
||||
|
||||
/* ************* Debugger Helper ***************/
|
||||
/*
|
||||
* These methods are used for working with debugger state changes in order
|
||||
* to make it easier to manipulate the ui and test different behavior. These
|
||||
* methods roughly reflect those found in debugger/new/test/mochi/head.js with
|
||||
* a few exceptions. The `dbg` object is not exactly the same, and the methods
|
||||
* have been simplified. We may want to consider unifying them in the future
|
||||
*/
|
||||
|
||||
const DEBUGGER_POLLING_INTERVAL = 50;
|
||||
|
||||
const debuggerHelper = {
|
||||
waitForState(dbg, predicate, msg) {
|
||||
return new Promise(resolve => {
|
||||
dump(`Waiting for state change: ${msg}\n`);
|
||||
if (predicate(dbg.store.getState())) {
|
||||
dump(`Finished waiting for state change: ${msg}\n`);
|
||||
return resolve();
|
||||
}
|
||||
|
||||
const unsubscribe = dbg.store.subscribe(() => {
|
||||
if (predicate(dbg.store.getState())) {
|
||||
dump(`Finished waiting for state change: ${msg}\n`);
|
||||
unsubscribe();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
waitForDispatch(dbg, type) {
|
||||
return new Promise(resolve => {
|
||||
dbg.store.dispatch({
|
||||
type: "@@service/waitUntil",
|
||||
predicate: action => {
|
||||
if (action.type === type) {
|
||||
return action.status
|
||||
? action.status === "done" || action.status === "error"
|
||||
: true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
run: (dispatch, getState, action) => {
|
||||
resolve(action);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async waitUntil(predicate, msg) {
|
||||
dump(`Waiting until: ${msg}\n`);
|
||||
return new Promise(resolve => {
|
||||
const timer = setInterval(() => {
|
||||
if (predicate()) {
|
||||
clearInterval(timer);
|
||||
dump(`Finished Waiting until: ${msg}\n`);
|
||||
resolve();
|
||||
}
|
||||
}, DEBUGGER_POLLING_INTERVAL);
|
||||
});
|
||||
},
|
||||
|
||||
findSource(dbg, url) {
|
||||
const sources = dbg.selectors.getSources(dbg.getState());
|
||||
return sources.find(s => (s.get("url") || "").includes(url));
|
||||
},
|
||||
|
||||
getCM(dbg) {
|
||||
const el = dbg.win.document.querySelector(".CodeMirror");
|
||||
return el.CodeMirror;
|
||||
},
|
||||
|
||||
waitForText(dbg, url, text) {
|
||||
return this.waitUntil(() => {
|
||||
// the welcome box is removed once text is displayed
|
||||
const welcomebox = dbg.win.document.querySelector(".welcomebox");
|
||||
if (welcomebox) {
|
||||
return false;
|
||||
}
|
||||
const cm = this.getCM(dbg);
|
||||
const editorText = cm.doc.getValue();
|
||||
return editorText.includes(text);
|
||||
}, "text is visible");
|
||||
},
|
||||
|
||||
waitForMetaData(dbg) {
|
||||
return this.waitUntil(
|
||||
() => {
|
||||
const state = dbg.store.getState();
|
||||
const source = dbg.selectors.getSelectedSource(state);
|
||||
// wait for metadata -- this involves parsing the file to determine its type.
|
||||
// if the object is empty, the data has not yet loaded
|
||||
const metaData = dbg.selectors.getSourceMetaData(state, source.get("id"));
|
||||
return !!Object.keys(metaData).length;
|
||||
},
|
||||
"has file metadata"
|
||||
);
|
||||
},
|
||||
|
||||
waitForSources(dbg, expectedSources) {
|
||||
const { selectors } = dbg;
|
||||
function countSources(state) {
|
||||
const sources = selectors.getSources(state);
|
||||
return sources.size >= expectedSources;
|
||||
}
|
||||
return this.waitForState(dbg, countSources, "count sources");
|
||||
},
|
||||
|
||||
async createContext(panel) {
|
||||
const { store, selectors, actions } = panel.getVarsForTests();
|
||||
|
||||
return {
|
||||
actions,
|
||||
selectors,
|
||||
getState: store.getState,
|
||||
win: panel.panelWin,
|
||||
store
|
||||
};
|
||||
},
|
||||
|
||||
selectSource(dbg, url) {
|
||||
dump(`Selecting source: ${url}\n`);
|
||||
const line = 1;
|
||||
const source = this.findSource(dbg, url);
|
||||
dbg.actions.selectLocation({ sourceId: source.get("id"), line });
|
||||
return this.waitForState(
|
||||
dbg,
|
||||
state => {
|
||||
const source = dbg.selectors.getSelectedSource(state);
|
||||
const isLoaded = source && source.get("loadedState") === "loaded";
|
||||
if (!isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// wait for symbols -- a flat map of all named variables in a file -- to be calculated.
|
||||
// this is a slow process and becomes slower the larger the file is
|
||||
return dbg.selectors.hasSymbols(state, source.toJS());
|
||||
},
|
||||
"selected source"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
async function garbageCollect() {
|
||||
dump("Garbage collect\n");
|
||||
|
||||
|
@ -591,7 +735,44 @@ async _consoleOpenWithCachedMessagesTest() {
|
|||
await this.testTeardown();
|
||||
},
|
||||
|
||||
_getToolLoadingTests(url, label, { expectedMessages, expectedSources }) {
|
||||
async openDebuggerAndLog(label, expectedSources, selectedFile, expectedText) {
|
||||
const onLoad = async (toolbox, panel) => {
|
||||
const dbg = await debuggerHelper.createContext(panel);
|
||||
await debuggerHelper.waitForSources(dbg, expectedSources);
|
||||
await debuggerHelper.selectSource(dbg, selectedFile);
|
||||
await debuggerHelper.waitForText(dbg, selectedFile, expectedText);
|
||||
await debuggerHelper.waitForMetaData(dbg);
|
||||
};
|
||||
const toolbox = await this.openToolboxAndLog(label + ".jsdebugger", "jsdebugger", onLoad);
|
||||
return toolbox;
|
||||
},
|
||||
|
||||
async reloadDebuggerAndLog(label, toolbox, expectedSources, selectedFile, expectedText) {
|
||||
const onReload = async () => {
|
||||
const panel = await toolbox.getPanelWhenReady("jsdebugger");
|
||||
const dbg = await debuggerHelper.createContext(panel);
|
||||
await debuggerHelper.waitForDispatch(dbg, "NAVIGATE");
|
||||
await debuggerHelper.waitForSources(dbg, expectedSources);
|
||||
await debuggerHelper.waitForText(dbg, selectedFile, expectedText);
|
||||
await debuggerHelper.waitForMetaData(dbg);
|
||||
};
|
||||
await this.reloadPageAndLog(`${label}.jsdebugger`, toolbox, onReload);
|
||||
},
|
||||
|
||||
async customDebugger() {
|
||||
const label = "custom";
|
||||
const expectedSources = 7;
|
||||
let url = CUSTOM_URL.replace(/\$TOOL/, "debugger/index");
|
||||
await this.testSetup(url);
|
||||
const selectedFile = "App.js";
|
||||
const expectedText = "import React, { Component } from 'react';";
|
||||
const toolbox = await this.openDebuggerAndLog(label, expectedSources, selectedFile, expectedText);
|
||||
await this.reloadDebuggerAndLog(label, toolbox, expectedSources, selectedFile, expectedText);
|
||||
await this.closeToolboxAndLog("custom.jsdebugger", toolbox);
|
||||
await this.testTeardown();
|
||||
},
|
||||
|
||||
_getToolLoadingTests(url, label, { expectedMessages, expectedSources, selectedFile, expectedText }) {
|
||||
let tests = {
|
||||
async inspector() {
|
||||
await this.testSetup(url);
|
||||
|
@ -624,36 +805,8 @@ async _consoleOpenWithCachedMessagesTest() {
|
|||
|
||||
async debugger() {
|
||||
await this.testSetup(url);
|
||||
let onLoad = async function(toolbox, dbg) {
|
||||
await new Promise(done => {
|
||||
let { selectors, store } = dbg.panelWin.getGlobalsForTesting();
|
||||
let unsubscribe;
|
||||
function countSources() {
|
||||
const sources = selectors.getSources(store.getState());
|
||||
if (sources.size >= expectedSources) {
|
||||
unsubscribe();
|
||||
done();
|
||||
}
|
||||
}
|
||||
unsubscribe = store.subscribe(countSources);
|
||||
countSources();
|
||||
});
|
||||
};
|
||||
let toolbox = await this.openToolboxAndLog(label + ".jsdebugger", "jsdebugger", onLoad);
|
||||
let onReload = async function() {
|
||||
await new Promise(done => {
|
||||
let count = 0;
|
||||
let { client } = toolbox.target;
|
||||
let onSource = async (_, actor) => {
|
||||
if (++count >= expectedSources) {
|
||||
client.removeListener("newSource", onSource);
|
||||
done();
|
||||
}
|
||||
};
|
||||
client.addListener("newSource", onSource);
|
||||
});
|
||||
};
|
||||
await this.reloadPageAndLog(label + ".jsdebugger", toolbox, onReload);
|
||||
let toolbox = await this.openDebuggerAndLog(label, expectedSources, selectedFile, expectedText);
|
||||
await this.reloadDebuggerAndLog(label, toolbox, expectedSources, selectedFile, expectedText);
|
||||
await this.closeToolboxAndLog(label + ".jsdebugger", toolbox);
|
||||
await this.testTeardown();
|
||||
},
|
||||
|
@ -876,16 +1029,21 @@ async _consoleOpenWithCachedMessagesTest() {
|
|||
Object.assign(tests, this._getToolLoadingTests(SIMPLE_URL, "simple", {
|
||||
expectedMessages: 1,
|
||||
expectedSources: 1,
|
||||
selectedFile: "simple.html",
|
||||
expectedText: "This is a simple page"
|
||||
}));
|
||||
|
||||
// Run all tests against "complicated" document
|
||||
Object.assign(tests, this._getToolLoadingTests(COMPLICATED_URL, "complicated", {
|
||||
expectedMessages: 7,
|
||||
expectedSources: 14,
|
||||
selectedFile: "ga.js",
|
||||
expectedText: "Math;function ga(a,b){return a.name=b}"
|
||||
}));
|
||||
|
||||
// Run all tests against a document specific to each tool
|
||||
tests["custom.inspector"] = this.customInspector;
|
||||
tests["custom.debugger"] = this.customDebugger;
|
||||
|
||||
// Run individual tests covering a very precise tool feature
|
||||
tests["console.bulklog"] = this._consoleBulkLoggingTest;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
This is a fork of [Create React App](https://github.com/facebookincubator/create-react-app) that is
|
||||
being used as part of the DAMP test tool suite. Files in `src` can be modified freely.
|
||||
|
||||
The URL for this repository is https://www.github.com/codehag/debugger-talos-example. Changes can be
|
||||
added there
|
||||
|
||||
This package assumes yarn is installed.
|
||||
|
||||
To build and copy:
|
||||
|
||||
- ensure your firefox directory is listed in package.json under `firefox`.
|
||||
- run `yarn copy-assets`
|
|
@ -0,0 +1 @@
|
|||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="./manifest.json"><title>React App</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript" src="./static/js/main.447c224f.js"></script></body></html>
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -29,8 +29,8 @@ test(t => {
|
|||
|
||||
anim.effect.composite = 'add';
|
||||
const keyframes = anim.effect.getKeyframes();
|
||||
assert_equals(keyframes[0].composite, undefined,
|
||||
'unspecified keyframe composite value should be absent even ' +
|
||||
assert_equals(keyframes[0].composite, null,
|
||||
'unspecified keyframe composite value should be null even ' +
|
||||
'if effect composite is set');
|
||||
}, 'Unspecified keyframe composite value when setting effect composite');
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ test(t => {
|
|||
assert_equals(effect.getKeyframes()[0].composite, composite,
|
||||
`resulting composite for '${composite}'`);
|
||||
}
|
||||
for (const composite of gBadCompositeValueTests) {
|
||||
for (const composite of gBadKeyframeCompositeValueTests) {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target, getKeyframe(composite));
|
||||
});
|
||||
|
@ -76,7 +76,7 @@ test(t => {
|
|||
assert_equals(effect.getKeyframes()[0].composite, composite,
|
||||
`resulting composite for '${composite}'`);
|
||||
}
|
||||
for (const composite of gBadCompositeValueTests) {
|
||||
for (const composite of gBadKeyframeCompositeValueTests) {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target, getKeyframes(composite));
|
||||
});
|
||||
|
@ -89,17 +89,17 @@ test(t => {
|
|||
const effect = new KeyframeEffectReadOnly(target, {
|
||||
left: ['10px', '20px']
|
||||
}, { composite: composite });
|
||||
assert_equals(effect.getKeyframes()[0].composite, undefined,
|
||||
assert_equals(effect.getKeyframes()[0].composite, null,
|
||||
`resulting composite for '${composite}'`);
|
||||
}
|
||||
for (const composite of gBadCompositeValueTests) {
|
||||
for (const composite of gBadOptionsCompositeValueTests) {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target, {
|
||||
left: ['10px', '20px']
|
||||
}, { composite: composite });
|
||||
});
|
||||
}
|
||||
}, 'composite value is absent if the composite operation specified on the ' +
|
||||
}, 'composite value is null if the composite operation specified on the ' +
|
||||
'keyframe effect is being used');
|
||||
|
||||
for (const subtest of gKeyframesTests) {
|
||||
|
|
|
@ -180,9 +180,27 @@ test(() => {
|
|||
{ done: true },
|
||||
]));
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 0, easing: 'linear', left: '100px' },
|
||||
{ offset: null, computedOffset: 0.5, easing: 'linear', left: '300px' },
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', left: '200px' },
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
left: '100px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0.5,
|
||||
easing: 'linear',
|
||||
left: '300px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
left: '200px',
|
||||
composite: null,
|
||||
},
|
||||
]);
|
||||
}, 'Keyframes are read from a custom iterator');
|
||||
|
||||
|
@ -197,9 +215,27 @@ test(() => {
|
|||
keyframes.offset = '0.1';
|
||||
const effect = new KeyframeEffect(null, keyframes);
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 0, easing: 'linear', left: '100px' },
|
||||
{ offset: null, computedOffset: 0.5, easing: 'linear', left: '300px' },
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', left: '200px' },
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
left: '100px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0.5,
|
||||
easing: 'linear',
|
||||
left: '300px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
left: '200px',
|
||||
composite: null,
|
||||
},
|
||||
]);
|
||||
}, '\'easing\' and \'offset\' are ignored on iterable objects');
|
||||
|
||||
|
@ -211,11 +247,29 @@ test(() => {
|
|||
{ done: true },
|
||||
]));
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 0, easing: 'linear', left: '100px',
|
||||
top: '200px' },
|
||||
{ offset: null, computedOffset: 0.5, easing: 'linear', left: '300px' },
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', left: '200px',
|
||||
top: '100px' },
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
left: '100px',
|
||||
top: '200px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0.5,
|
||||
easing: 'linear',
|
||||
left: '300px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
left: '200px',
|
||||
top: '100px',
|
||||
composite: null,
|
||||
},
|
||||
]);
|
||||
}, 'Keyframes are read from a custom iterator with multiple properties'
|
||||
+ ' specified');
|
||||
|
@ -228,9 +282,27 @@ test(() => {
|
|||
{ done: true },
|
||||
]));
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 0, easing: 'linear', left: '100px' },
|
||||
{ offset: 0.75, computedOffset: 0.75, easing: 'linear', left: '250px' },
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', left: '200px' },
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
left: '100px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: 0.75,
|
||||
computedOffset: 0.75,
|
||||
easing: 'linear',
|
||||
left: '250px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
left: '200px',
|
||||
composite: null,
|
||||
},
|
||||
]);
|
||||
}, 'Keyframes are read from a custom iterator with where an offset is'
|
||||
+ ' specified');
|
||||
|
@ -253,7 +325,7 @@ test(() => {
|
|||
{ done: true },
|
||||
]));
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 1, easing: 'linear' }
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', composite: null }
|
||||
]);
|
||||
}, 'A list of values returned from a custom iterator should be ignored');
|
||||
|
||||
|
@ -270,8 +342,20 @@ test(() => {
|
|||
const effect = new KeyframeEffect(null, [keyframe, { height: '200px' }]);
|
||||
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 0, easing: 'linear', height: '100px' },
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', height: '200px' },
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
height: '100px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
height: '200px',
|
||||
composite: null,
|
||||
},
|
||||
]);
|
||||
}, 'Only enumerable properties on keyframes are read');
|
||||
|
||||
|
@ -289,8 +373,20 @@ test(() => {
|
|||
const effect = new KeyframeEffect(null, [keyframe, { top: '200px' }]);
|
||||
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 0, easing: 'linear', top: '100px' },
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', top: '200px' },
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
top: '100px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
top: '200px',
|
||||
composite: null,
|
||||
},
|
||||
]);
|
||||
}, 'Only properties defined directly on keyframes are read');
|
||||
|
||||
|
@ -305,8 +401,20 @@ test(() => {
|
|||
const effect = new KeyframeEffect(null, keyframes);
|
||||
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 0, easing: 'linear', height: '100px' },
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', height: '200px' },
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
height: '100px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
height: '200px',
|
||||
composite: null,
|
||||
},
|
||||
]);
|
||||
}, 'Only enumerable properties on property-indexed keyframes are read');
|
||||
|
||||
|
@ -324,8 +432,20 @@ test(() => {
|
|||
const effect = new KeyframeEffect(null, keyframes);
|
||||
|
||||
assert_frame_lists_equal(effect.getKeyframes(), [
|
||||
{ offset: null, computedOffset: 0, easing: 'linear', top: '100px' },
|
||||
{ offset: null, computedOffset: 1, easing: 'linear', top: '200px' },
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 0,
|
||||
easing: 'linear',
|
||||
top: '100px',
|
||||
composite: null,
|
||||
},
|
||||
{
|
||||
offset: null,
|
||||
computedOffset: 1,
|
||||
easing: 'linear',
|
||||
top: '200px',
|
||||
composite: null,
|
||||
},
|
||||
]);
|
||||
}, 'Only properties defined directly on property-indexed keyframes are read');
|
||||
|
||||
|
|
|
@ -12,14 +12,18 @@
|
|||
// ------------------------------
|
||||
|
||||
const gGoodKeyframeCompositeValueTests = [
|
||||
'replace', 'add', 'accumulate', undefined
|
||||
'replace', 'add', 'accumulate', null
|
||||
];
|
||||
|
||||
const gBadKeyframeCompositeValueTests = [
|
||||
'unrecognised', 'replace ', 'Replace'
|
||||
];
|
||||
|
||||
const gGoodOptionsCompositeValueTests = [
|
||||
'replace', 'add', 'accumulate'
|
||||
];
|
||||
|
||||
const gBadCompositeValueTests = [
|
||||
const gBadOptionsCompositeValueTests = [
|
||||
'unrecognised', 'replace ', 'Replace', null
|
||||
];
|
||||
|
||||
|
@ -50,9 +54,7 @@ const keyframe = (offset, props, easing='linear', composite) => {
|
|||
// Object.assign instead.
|
||||
const result = {};
|
||||
Object.assign(result, offset, props, { easing });
|
||||
if (composite) {
|
||||
result.composite = composite;
|
||||
}
|
||||
result.composite = composite || null;
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ toolkit.jar:
|
|||
content/payments/paymentDialog.xhtml (content/paymentDialog.xhtml)
|
||||
% resource payments %res/payments/
|
||||
res/payments (res/paymentRequest.*)
|
||||
res/payments/components/ (res/components/*.css)
|
||||
res/payments/components/ (res/components/*.js)
|
||||
res/payments/containers/ (res/containers/*.js)
|
||||
res/payments/debugging.html (res/debugging.html)
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* 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/. */
|
||||
|
||||
address-option {
|
||||
display: grid;
|
||||
grid-row-gap: 5px;
|
||||
grid-column-gap: 10px;
|
||||
grid-template-areas:
|
||||
"recipient "
|
||||
"addressLine";
|
||||
|
||||
border-bottom: 1px solid #ddd;
|
||||
background: #fff;
|
||||
padding: 5px;
|
||||
padding-inline-start: 20px;
|
||||
width: 400px;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
rich-select[open] > .rich-select-popup-box > address-option {
|
||||
grid-template-areas:
|
||||
"recipient recipient"
|
||||
"addressLine addressLine"
|
||||
"email phone ";
|
||||
}
|
||||
|
||||
address-option > .recipient {
|
||||
grid-area: recipient;
|
||||
}
|
||||
|
||||
address-option > .addressLine {
|
||||
grid-area: addressLine;
|
||||
}
|
||||
|
||||
address-option > .email {
|
||||
grid-area: email;
|
||||
}
|
||||
|
||||
address-option > .phone {
|
||||
grid-area: phone;
|
||||
}
|
||||
|
||||
address-option > .recipient,
|
||||
address-option > .addressLine,
|
||||
address-option > .email,
|
||||
address-option > .phone {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.rich-select-popup-box > address-option[selected] {
|
||||
background-color: #ffa;
|
||||
}
|
||||
|
||||
rich-select > .rich-select-selected-clone > .email,
|
||||
rich-select > .rich-select-selected-clone > .phone {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* 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/. */
|
||||
|
||||
/**
|
||||
* <rich-select>
|
||||
* <address-option addressLine="1234 Anywhere St"
|
||||
* city="Some City"
|
||||
* country="USA"
|
||||
* dependentLocality=""
|
||||
* languageCode="en-US"
|
||||
* phone=""
|
||||
* postalCode="90210"
|
||||
* recipient="Jared Wein"
|
||||
* region="MI"></address-option>
|
||||
* </rich-select>
|
||||
*/
|
||||
|
||||
/* global ObservedPropertiesMixin, RichOption */
|
||||
|
||||
class AddressOption extends ObservedPropertiesMixin(RichOption) {
|
||||
static get observedAttributes() {
|
||||
return RichOption.observedAttributes.concat([
|
||||
"addressLine",
|
||||
"city",
|
||||
"country",
|
||||
"dependentLocality",
|
||||
"email",
|
||||
"languageCode",
|
||||
"organization",
|
||||
"phone",
|
||||
"postalCode",
|
||||
"recipient",
|
||||
"region",
|
||||
"sortingCode",
|
||||
]);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
for (let child of this.children) {
|
||||
child.remove();
|
||||
}
|
||||
|
||||
let fragment = document.createDocumentFragment();
|
||||
RichOption._createElement(fragment, "recipient");
|
||||
RichOption._createElement(fragment, "addressLine");
|
||||
RichOption._createElement(fragment, "email");
|
||||
RichOption._createElement(fragment, "phone");
|
||||
this.appendChild(fragment);
|
||||
|
||||
super.connectedCallback();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.parentNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.querySelector(".recipient").textContent = this.recipient;
|
||||
this.querySelector(".addressLine").textContent =
|
||||
`${this.addressLine} ${this.city} ${this.region} ${this.postalCode} ${this.country}`;
|
||||
this.querySelector(".email").textContent = this.email;
|
||||
this.querySelector(".phone").textContent = this.phone;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("address-option", AddressOption);
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/* 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/. */
|
||||
|
||||
basic-card-option {
|
||||
display: grid;
|
||||
grid-row-gap: 5px;
|
||||
grid-column-gap: 10px;
|
||||
grid-template-areas:
|
||||
"owner type"
|
||||
"number ...";
|
||||
|
||||
border-bottom: 1px solid #ddd;
|
||||
background: #fff;
|
||||
padding: 5px;
|
||||
padding-inline-start: 20px;
|
||||
width: 400px;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
rich-select[open] > .rich-select-popup-box > basic-card-option {
|
||||
grid-template-areas:
|
||||
"owner type"
|
||||
"number expiration";
|
||||
}
|
||||
|
||||
basic-card-option > .number {
|
||||
grid-area: number;
|
||||
}
|
||||
|
||||
basic-card-option > .owner {
|
||||
grid-area: owner;
|
||||
}
|
||||
|
||||
basic-card-option > .expiration {
|
||||
grid-area: expiration;
|
||||
}
|
||||
|
||||
basic-card-option > .type {
|
||||
grid-area: type;
|
||||
}
|
||||
|
||||
basic-card-option > .number,
|
||||
basic-card-option > .owner,
|
||||
basic-card-option > .expiration,
|
||||
basic-card-option > .type {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.rich-select-popup-box > basic-card-option[selected] {
|
||||
background-color: #ffa;
|
||||
}
|
||||
|
||||
rich-select > .rich-select-selected-clone > .expiration {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/* 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/. */
|
||||
|
||||
/**
|
||||
* <rich-select>
|
||||
* <basic-card-option></basic-card-option>
|
||||
* </rich-select>
|
||||
*/
|
||||
|
||||
/* global ObservedPropertiesMixin, RichOption */
|
||||
|
||||
class BasicCardOption extends ObservedPropertiesMixin(RichOption) {
|
||||
static get observedAttributes() {
|
||||
return RichOption.observedAttributes.concat([
|
||||
"expiration",
|
||||
"number",
|
||||
"owner",
|
||||
"type",
|
||||
]);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
for (let child of this.children) {
|
||||
child.remove();
|
||||
}
|
||||
|
||||
let fragment = document.createDocumentFragment();
|
||||
RichOption._createElement(fragment, "owner");
|
||||
RichOption._createElement(fragment, "number");
|
||||
RichOption._createElement(fragment, "expiration");
|
||||
RichOption._createElement(fragment, "type");
|
||||
this.appendChild(fragment);
|
||||
|
||||
super.connectedCallback();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.parentNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.querySelector(".owner").textContent = this.owner;
|
||||
this.querySelector(".number").textContent = this.number;
|
||||
this.querySelector(".expiration").textContent = this.expiration;
|
||||
this.querySelector(".type").textContent = this.type;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("basic-card-option", BasicCardOption);
|
|
@ -0,0 +1,91 @@
|
|||
/* 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/. */
|
||||
|
||||
/**
|
||||
* <rich-select>
|
||||
* <rich-option></rich-option>
|
||||
* </rich-select>
|
||||
*/
|
||||
|
||||
/* global ObservedPropertiesMixin */
|
||||
/* exported RichOption */
|
||||
|
||||
class RichOption extends ObservedPropertiesMixin(HTMLElement) {
|
||||
static get observedAttributes() { return ["selected", "hidden"]; }
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.addEventListener("click", this);
|
||||
this.addEventListener("keypress", this);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
let richSelect = this.closest("rich-select");
|
||||
if (richSelect && richSelect.render) {
|
||||
richSelect.render();
|
||||
}
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "click": {
|
||||
this.onClick(event);
|
||||
break;
|
||||
}
|
||||
case "keypress": {
|
||||
this.onKeyPress(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
if (this.closest("rich-select").open &&
|
||||
!this.disabled &&
|
||||
event.button == 0) {
|
||||
for (let option of this.parentNode.children) {
|
||||
option.selected = option == this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onKeyPress(event) {
|
||||
if (!this.disabled &&
|
||||
event.which == 13 /* Enter */) {
|
||||
for (let option of this.parentNode.children) {
|
||||
option.selected = option == this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get selected() {
|
||||
return this.hasAttribute("selected");
|
||||
}
|
||||
|
||||
set selected(value) {
|
||||
if (value) {
|
||||
let oldSelectedOptions = this.parentNode.querySelectorAll("[selected]");
|
||||
for (let option of oldSelectedOptions) {
|
||||
option.removeAttribute("selected");
|
||||
}
|
||||
this.setAttribute("selected", value);
|
||||
} else {
|
||||
this.removeAttribute("selected");
|
||||
}
|
||||
let richSelect = this.closest("rich-select");
|
||||
if (richSelect && richSelect.render) {
|
||||
richSelect.render();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static _createElement(fragment, className) {
|
||||
let element = document.createElement("span");
|
||||
element.classList.add(className);
|
||||
fragment.appendChild(element);
|
||||
return element;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/* 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/. */
|
||||
|
||||
rich-select:not([open]) > .rich-select-popup-box {
|
||||
display: none;
|
||||
}
|
||||
|
||||
rich-select[open] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
rich-select[open] > .rich-select-popup-box {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 1em;
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/* 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/. */
|
||||
|
||||
/**
|
||||
* <rich-select>
|
||||
* <rich-option></rich-option>
|
||||
* </rich-select>
|
||||
*/
|
||||
|
||||
/* global ObservedPropertiesMixin */
|
||||
|
||||
class RichSelect extends ObservedPropertiesMixin(HTMLElement) {
|
||||
static get observedAttributes() {
|
||||
return [
|
||||
"open",
|
||||
"disabled",
|
||||
"hidden",
|
||||
];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.addEventListener("blur", this);
|
||||
this.addEventListener("click", this);
|
||||
this.addEventListener("keypress", this);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.setAttribute("tabindex", "0");
|
||||
this.render();
|
||||
}
|
||||
|
||||
get popupBox() {
|
||||
return this.querySelector(":scope > .rich-select-popup-box");
|
||||
}
|
||||
|
||||
get selectedOption() {
|
||||
return this.popupBox.querySelector(":scope > [selected]");
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "blur": {
|
||||
this.onBlur(event);
|
||||
break;
|
||||
}
|
||||
case "click": {
|
||||
this.onClick(event);
|
||||
break;
|
||||
}
|
||||
case "keypress": {
|
||||
this.onKeyPress(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onBlur(event) {
|
||||
if (event.target == this) {
|
||||
this.open = false;
|
||||
}
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
if (!this.disabled &&
|
||||
event.button == 0) {
|
||||
this.open = !this.open;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyPress(event) {
|
||||
if (event.key == " ") {
|
||||
this.open = !this.open;
|
||||
} else if (event.key == "ArrowDown") {
|
||||
let selectedOption = this.selectedOption;
|
||||
let next = selectedOption.nextElementSibling;
|
||||
if (next) {
|
||||
next.selected = true;
|
||||
selectedOption.selected = false;
|
||||
}
|
||||
} else if (event.key == "ArrowUp") {
|
||||
let selectedOption = this.selectedOption;
|
||||
let next = selectedOption.previousElementSibling;
|
||||
if (next) {
|
||||
next.selected = true;
|
||||
selectedOption.selected = false;
|
||||
}
|
||||
} else if (event.key == "Enter" ||
|
||||
event.key == "Escape") {
|
||||
this.open = false;
|
||||
}
|
||||
}
|
||||
|
||||
_optionsAreEquivalent(a, b) {
|
||||
if (!a || !b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let aAttrs = a.constructor.observedAttributes;
|
||||
let bAttrs = b.constructor.observedAttributes;
|
||||
if (aAttrs.length != bAttrs.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let aAttr of aAttrs) {
|
||||
if (a.getAttribute(aAttr) != b.getAttribute(aAttr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
render() {
|
||||
let popupBox = this.popupBox;
|
||||
if (!popupBox) {
|
||||
popupBox = document.createElement("div");
|
||||
popupBox.classList.add("rich-select-popup-box");
|
||||
this.appendChild(popupBox);
|
||||
}
|
||||
|
||||
/* eslint-disable max-len */
|
||||
let options =
|
||||
this.querySelectorAll(":scope > :not(.rich-select-popup-box):not(.rich-select-selected-clone)");
|
||||
/* eslint-enable max-len */
|
||||
for (let option of options) {
|
||||
popupBox.appendChild(option);
|
||||
}
|
||||
|
||||
let selectedChild;
|
||||
for (let child of popupBox.children) {
|
||||
if (child.selected) {
|
||||
selectedChild = child;
|
||||
}
|
||||
}
|
||||
if (!selectedChild && popupBox.children.length) {
|
||||
selectedChild = popupBox.children[0];
|
||||
selectedChild.selected = true;
|
||||
}
|
||||
|
||||
if (!this._optionsAreEquivalent(this._selectedChild, selectedChild)) {
|
||||
let selectedClone = this.querySelector(":scope > .rich-select-selected-clone");
|
||||
if (selectedClone) {
|
||||
selectedClone.remove();
|
||||
}
|
||||
|
||||
if (selectedChild) {
|
||||
this._selectedChild = selectedChild;
|
||||
selectedClone = selectedChild.cloneNode(false);
|
||||
selectedClone.removeAttribute("id");
|
||||
selectedClone.classList.add("rich-select-selected-clone");
|
||||
selectedClone = this.appendChild(selectedClone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("rich-select", RichSelect);
|
|
@ -8,6 +8,8 @@
|
|||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'"/>
|
||||
<title></title>
|
||||
<link rel="stylesheet" href="paymentRequest.css"/>
|
||||
<link rel="stylesheet" href="components/rich-select.css"/>
|
||||
<link rel="stylesheet" href="components/address-option.css"/>
|
||||
<script src="vendor/custom-elements.min.js"></script>
|
||||
|
||||
<script src="PaymentsStore.js"></script>
|
||||
|
@ -17,6 +19,9 @@
|
|||
|
||||
<script src="components/currency-amount.js"></script>
|
||||
|
||||
<script src="components/rich-select.js"></script>
|
||||
<script src="components/rich-option.js"></script>
|
||||
<script src="components/address-option.js"></script>
|
||||
<script src="containers/payment-dialog.js"></script>
|
||||
|
||||
<script src="paymentRequest.js"></script>
|
||||
|
@ -37,6 +42,50 @@
|
|||
<body>
|
||||
<iframe id="debugging-console" hidden="hidden" src="debugging.html"></iframe>
|
||||
|
||||
<rich-select>
|
||||
<address-option email="emzembrano92@example.com"
|
||||
recipient="Emily Zembrano"
|
||||
addressLine="717 Hyde Street #6"
|
||||
city="San Francisco"
|
||||
region="CA"
|
||||
phone="415 203 0845"
|
||||
postalCode="94109"
|
||||
country="USA"></address-option>
|
||||
<address-option email="jenz9382@example.com"
|
||||
recipient="Jennifer Zembrano"
|
||||
addressLine="42 Fairydust Lane"
|
||||
city="Lala Land"
|
||||
region="HI"
|
||||
phone="415 439 2827"
|
||||
postalCode="98765"
|
||||
country="USA"></address-option>
|
||||
<address-option email="johnz9382@example.com"
|
||||
recipient="John Zembrano"
|
||||
addressLine="42 Fairydust Lane"
|
||||
city="Lala Land"
|
||||
missinginformation="true"
|
||||
region="HI"
|
||||
phone="415 439 2827"
|
||||
postalCode="98765"
|
||||
country="USA"></address-option>
|
||||
<address-option email="adbrwodne@example.com"
|
||||
recipient="Andrew Browne"
|
||||
addressLine="42 Fairydust Lane"
|
||||
city="Lala Land"
|
||||
region="HI"
|
||||
phone="517 410 0845"
|
||||
postalCode="98765"
|
||||
country="USA"></address-option>
|
||||
<address-option email="johnz9382@example.com"
|
||||
recipient="Jacob Humphrey"
|
||||
addressLine="1855 Pinecrest Rd"
|
||||
city="East Lansing"
|
||||
region="MI"
|
||||
phone="517 439 2827"
|
||||
postalCode="48823"
|
||||
country="USA"></address-option>
|
||||
</rich-select>
|
||||
|
||||
<payment-dialog></payment-dialog>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -3,6 +3,13 @@ support-files =
|
|||
../../../../../testing/modules/sinon-2.3.2.js
|
||||
../../res/PaymentsStore.js
|
||||
../../res/components/currency-amount.js
|
||||
../../res/components/address-option.js
|
||||
../../res/components/address-option.css
|
||||
../../res/components/basic-card-option.js
|
||||
../../res/components/basic-card-option.css
|
||||
../../res/components/rich-option.js
|
||||
../../res/components/rich-select.css
|
||||
../../res/components/rich-select.js
|
||||
../../res/mixins/ObservedPropertiesMixin.js
|
||||
../../res/mixins/PaymentStateSubscriberMixin.js
|
||||
../../res/vendor/custom-elements.min.js
|
||||
|
@ -10,5 +17,6 @@ support-files =
|
|||
payments_common.js
|
||||
|
||||
[test_currency_amount.html]
|
||||
[test_rich_select.html]
|
||||
[test_ObservedPropertiesMixin.html]
|
||||
[test_PaymentStateSubscriberMixin.html]
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test the rich-select component
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the rich-select component</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script src="payments_common.js"></script>
|
||||
<script src="custom-elements.min.js"></script>
|
||||
<script src="ObservedPropertiesMixin.js"></script>
|
||||
<script src="rich-select.js"></script>
|
||||
<script src="rich-option.js"></script>
|
||||
<script src="address-option.js"></script>
|
||||
<script src="basic-card-option.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="rich-select.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="address-option.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="basic-card-option.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display">
|
||||
<rich-select id="select1">
|
||||
<address-option id="option1"
|
||||
email="emzembrano92@email.com"
|
||||
recipient="Emily Zembrano"
|
||||
addressLine="717 Hyde Street #6"
|
||||
city="San Francisco"
|
||||
region="CA"
|
||||
phone="415 203 0845"
|
||||
postalCode="94109"
|
||||
country="USA"></address-option>
|
||||
<address-option id="option2"
|
||||
email="jenz9382@email.com"
|
||||
recipient="Jennifer Zembrano"
|
||||
addressLine="42 Fairydust Lane"
|
||||
city="Lala Land"
|
||||
region="HI"
|
||||
phone="415 439 2827"
|
||||
postalCode="98765"
|
||||
country="USA"></address-option>
|
||||
<address-option id="option3"
|
||||
email="johnz9382@email.com"
|
||||
recipient="John Zembrano"
|
||||
addressLine="42 Fairydust Lane"
|
||||
city="Lala Land"
|
||||
missinginformation="true"
|
||||
region="HI"
|
||||
phone="415 439 2827"
|
||||
postalCode="98765"
|
||||
country="USA"></address-option>
|
||||
</rich-select>
|
||||
|
||||
<rich-select id="select2">
|
||||
<basic-card-option owner="Jared Wein"
|
||||
expiration="01/1970"
|
||||
number="4024007197293599"
|
||||
type="Visa"></basic-card-option>
|
||||
<basic-card-option owner="Whimsy Corn"
|
||||
expiration="01/1970"
|
||||
number="5220465104517667"
|
||||
type="Mastercard"></basic-card-option>
|
||||
<basic-card-option owner="Fire Fox"
|
||||
expiration="01/1970"
|
||||
number="6011777095481054"
|
||||
type="Discover"></basic-card-option>
|
||||
</rich-select>
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script type="application/javascript">
|
||||
/** Test the rich-select address-option component **/
|
||||
|
||||
/* import-globals-from payments_common.js */
|
||||
/* import-globals-from ../../res/components/address-option.js */
|
||||
/* import-globals-from ../../res/components/basic-card-option.js */
|
||||
|
||||
let select1 = document.getElementById("select1");
|
||||
let option1 = document.getElementById("option1");
|
||||
let option2 = document.getElementById("option2");
|
||||
let option3 = document.getElementById("option3");
|
||||
|
||||
function get_selected_clone() {
|
||||
return select1.querySelector(".rich-select-selected-clone");
|
||||
}
|
||||
|
||||
function is_visible(element, message) {
|
||||
ok(!isHidden(element), message);
|
||||
}
|
||||
|
||||
function is_hidden(element, message) {
|
||||
ok(isHidden(element), message);
|
||||
}
|
||||
|
||||
function dispatchKeyPress(key, keyCode) {
|
||||
select1.dispatchEvent(new KeyboardEvent("keypress", {key, keyCode}));
|
||||
}
|
||||
|
||||
add_task(async function test_addressLine_combines_address_city_region_postalCode_country() {
|
||||
ok(option1, "option1 exists");
|
||||
let addressLine = option1.querySelector(".addressLine");
|
||||
/* eslint-disable max-len */
|
||||
is(addressLine.textContent,
|
||||
`${option1.addressLine} ${option1.city} ${option1.region} ${option1.postalCode} ${option1.country}`);
|
||||
/* eslint-enable max-len */
|
||||
});
|
||||
|
||||
add_task(async function test_no_option_selected_first_displayed() {
|
||||
ok(select1, "select1 exists");
|
||||
|
||||
await asyncElementRendered();
|
||||
|
||||
is_hidden(option1, "option 1 should be hidden when popup is not open");
|
||||
is_hidden(option2, "option 2 should be hidden when popup is not open");
|
||||
is_hidden(option3, "option 3 should be hidden when popup is not open");
|
||||
ok(option1.selected, "option 1 should be selected");
|
||||
ok(option1.hasAttribute("selected"), "option 1 should have selected attribute");
|
||||
let selectedClone = get_selected_clone();
|
||||
is_visible(selectedClone, "The selected clone should be visible at all times");
|
||||
is(selectedClone.getAttribute("email"), option1.getAttribute("email"),
|
||||
"The selected clone email should be equivalent to the selected option 1");
|
||||
is(selectedClone.getAttribute("recipient"), option1.getAttribute("recipient"),
|
||||
"The selected clone recipient should be equivalent to the selected option 1");
|
||||
});
|
||||
|
||||
add_task(async function test_clicking_on_select_shows_all_options() {
|
||||
ok(select1, "select1 exists");
|
||||
ok(!select1.open, "select is not open by default");
|
||||
ok(option1.selected, "option 1 should be selected by default");
|
||||
|
||||
select1.click();
|
||||
|
||||
ok(select1.open, "select is open after clicking on it");
|
||||
ok(option1.selected, "option 1 should be selected when open");
|
||||
is_visible(option1, "option 1 is visible when select is open");
|
||||
is_visible(option2, "option 2 is visible when select is open");
|
||||
is_visible(option3, "option 3 is visible when select is open");
|
||||
|
||||
option2.click();
|
||||
|
||||
ok(!select1.open, "select is not open after blur");
|
||||
ok(!option1.selected, "option 1 is not selected after click on option 2");
|
||||
ok(option2.selected, "option 2 is selected after clicking on it");
|
||||
is_hidden(option1, "option 1 is hidden when select is closed");
|
||||
is_hidden(option2, "option 2 is hidden when select is closed");
|
||||
is_hidden(option3, "option 3 is hidden when select is closed");
|
||||
|
||||
await asyncElementRendered();
|
||||
|
||||
let selectedClone = get_selected_clone();
|
||||
is_visible(selectedClone, "The selected clone should be visible at all times");
|
||||
is(selectedClone.getAttribute("email"), option2.getAttribute("email"),
|
||||
"The selected clone email should be equivalent to the selected option 2");
|
||||
is(selectedClone.getAttribute("recipient"), option2.getAttribute("recipient"),
|
||||
"The selected clone recipient should be equivalent to the selected option 2");
|
||||
});
|
||||
|
||||
add_task(async function test_changing_option_selected_affects_other_options() {
|
||||
ok(option2.selected, "Option 2 should be selected from prior test");
|
||||
|
||||
option1.selected = true;
|
||||
ok(!option2.selected, "Option 2 should no longer be selected after making option 1 selected");
|
||||
ok(option1.hasAttribute("selected"), "Option 1 should now have selected attribute");
|
||||
});
|
||||
|
||||
add_task(async function test_up_down_keys_change_selected_item() {
|
||||
let openObserver = new MutationObserver(mutations => {
|
||||
for (let mutation of mutations) {
|
||||
ok(mutation.attributeName != "open", "the select should not open/close during this test");
|
||||
}
|
||||
});
|
||||
openObserver.observe(select1, {attributes: true});
|
||||
|
||||
ok(select1, "select1 exists");
|
||||
ok(option1.selected, "option 1 should be selected by default");
|
||||
|
||||
ok(!select1.open, "select should not be open before focusing");
|
||||
select1.focus();
|
||||
ok(!select1.open, "select should not be open after focusing");
|
||||
|
||||
dispatchKeyPress("ArrowDown", 40);
|
||||
ok(!option1.selected, "option 1 should no longer be selected");
|
||||
ok(option2.selected, "option 2 should now be selected");
|
||||
|
||||
dispatchKeyPress("ArrowDown", 40);
|
||||
ok(!option2.selected, "option 2 should no longer be selected");
|
||||
ok(option3.selected, "option 3 should now be selected");
|
||||
|
||||
dispatchKeyPress("ArrowDown", 40);
|
||||
ok(option3.selected, "option 3 should remain selected");
|
||||
ok(!option1.selected, "option 1 should not be selected");
|
||||
|
||||
dispatchKeyPress("ArrowUp", 38);
|
||||
ok(!option3.selected, "option 3 should no longer be selected");
|
||||
ok(option2.selected, "option 2 should now be selected");
|
||||
|
||||
dispatchKeyPress("ArrowUp", 38);
|
||||
ok(!option2.selected, "option 2 should no longer be selected");
|
||||
ok(option1.selected, "option 1 should now be selected");
|
||||
|
||||
dispatchKeyPress("ArrowUp", 38);
|
||||
ok(option1.selected, "option 1 should remain selected");
|
||||
ok(!option3.selected, "option 3 should not be selected");
|
||||
|
||||
// Wait for any mutation observer notifications to fire before exiting.
|
||||
await Promise.resolve();
|
||||
|
||||
openObserver.disconnect();
|
||||
});
|
||||
|
||||
add_task(async function test_open_close_from_keyboard() {
|
||||
select1.focus();
|
||||
|
||||
ok(!select1.open, "select should not be open by default");
|
||||
|
||||
dispatchKeyPress(" ", 32);
|
||||
ok(select1.open, "select should now be open");
|
||||
ok(option1.selected, "option 1 should be selected by default");
|
||||
|
||||
dispatchKeyPress("ArrowDown", 40);
|
||||
ok(!option1.selected, "option 1 should not be selected");
|
||||
ok(option2.selected, "option 2 should now be selected");
|
||||
ok(select1.open, "select should remain open");
|
||||
|
||||
dispatchKeyPress("ArrowUp", 38);
|
||||
ok(option1.selected, "option 1 should now be selected");
|
||||
ok(!option2.selected, "option 2 should not be selected");
|
||||
ok(select1.open, "select should remain open");
|
||||
|
||||
dispatchKeyPress("Enter", 13);
|
||||
ok(option1.selected, "option 1 should now be selected");
|
||||
ok(!select1.open, "select should be closed");
|
||||
|
||||
dispatchKeyPress(" ", 32);
|
||||
ok(select1.open, "select should now be open");
|
||||
|
||||
dispatchKeyPress("Escape", 27);
|
||||
ok(!select1.open, "select should be closed");
|
||||
});
|
||||
|
||||
add_task(async function test_clicking_on_options_maintain_one_item_always_selected() {
|
||||
ok(!select1.open, "select should be closed by default");
|
||||
ok(option1.selected, "option 1 should be selected by default");
|
||||
select1.click();
|
||||
ok(select1.open, "select should now be open");
|
||||
|
||||
option3.click();
|
||||
ok(!select1.open, "select should be closed");
|
||||
ok(!option1.selected, "option 1 should be unselected");
|
||||
ok(option3.selected, "option 3 should be selected");
|
||||
|
||||
select1.click();
|
||||
ok(select1.open, "select should open");
|
||||
ok(!option1.selected, "option 1 should be unselected");
|
||||
ok(option3.selected, "option 3 should be selected");
|
||||
|
||||
option1.click();
|
||||
ok(!select1.open, "select should be closed");
|
||||
ok(option1.selected, "option 1 should be selected");
|
||||
ok(!option3.selected, "option 3 should be unselected");
|
||||
});
|
||||
|
||||
add_task(async function test_selected_clone_should_equal_selected_option() {
|
||||
ok(option1.selected, "option 1 should be selected");
|
||||
await asyncElementRendered();
|
||||
|
||||
let clonedOptions = select1.querySelectorAll(".rich-select-selected-clone");
|
||||
is(clonedOptions.length, 1, "there should only be one cloned option");
|
||||
|
||||
let clonedOption = clonedOptions[0];
|
||||
for (let attrName of AddressOption.observedAttributes) {
|
||||
is(clonedOption.attributes[attrName] && clonedOption.attributes[attrName].value,
|
||||
option1.attributes[attrName] && option1.attributes[attrName].value,
|
||||
"attributes should have matching value; name=" + attrName);
|
||||
}
|
||||
|
||||
option2.selected = true;
|
||||
await asyncElementRendered();
|
||||
|
||||
clonedOptions = select1.querySelectorAll(".rich-select-selected-clone");
|
||||
is(clonedOptions.length, 1, "there should only be one cloned option");
|
||||
|
||||
clonedOption = clonedOptions[0];
|
||||
for (let attrName of AddressOption.observedAttributes) {
|
||||
is(clonedOption.attributes[attrName] && clonedOption.attributes[attrName].value,
|
||||
option2.attributes[attrName] && option2.attributes[attrName].value,
|
||||
"attributes should have matching value; name=" + attrName);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_basic_card_simple() {
|
||||
let select2 = document.getElementById("select2");
|
||||
ok(select2, "basic card select should exist");
|
||||
let selectPopupBox = select2.querySelector(".rich-select-popup-box");
|
||||
ok(selectPopupBox, "basic card popup box exists");
|
||||
|
||||
is(selectPopupBox.childElementCount, 3, "There should be three children in the popup box");
|
||||
|
||||
let clonedOption = select2.querySelector(".rich-select-selected-clone");
|
||||
let selectedOption = selectPopupBox.firstChild;
|
||||
for (let attrName of BasicCardOption.observedAttributes) {
|
||||
is(clonedOption.attributes[attrName] && clonedOption.attributes[attrName].value,
|
||||
selectedOption.attributes[attrName] && selectedOption.attributes[attrName].value,
|
||||
"attributes should have matching value; name=" + attrName);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -75,13 +75,6 @@
|
|||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="toolbarbutton-image"
|
||||
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
|
||||
<content>
|
||||
<xul:image class="toolbarbutton-icon" xbl:inherits="src=image"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="toolbarbutton-badged"
|
||||
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
|
||||
<content>
|
||||
|
|
|
@ -2292,7 +2292,7 @@ public:
|
|||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<> Args;
|
||||
static constexpr char name[] = "disposeNative";
|
||||
static constexpr char name[] = "nativeDisposeNative";
|
||||
static constexpr char signature[] =
|
||||
"()V";
|
||||
static const bool isStatic = false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче