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

This commit is contained in:
Brindusan Cristian 2018-01-12 13:34:20 +02:00
Родитель 43644aaded 4de0807d09
Коммит 874238697d
85 изменённых файлов: 6524 добавлений и 452 удалений

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

@ -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

33
taskcluster/docker/recipes/hgrc Executable file
Просмотреть файл

@ -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;