Merge autoland to mozilla-central. a=merge

This commit is contained in:
Daniel Varga 2019-04-11 07:21:46 +03:00
Родитель 4a56b6ca02 b68b37149c
Коммит 2f4a6dc373
13 изменённых файлов: 121 добавлений и 101 удалений

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

@ -361,35 +361,16 @@ class JSStreamConsumer final : public nsIInputStreamCallback {
public:
NS_DECL_THREADSAFE_ISUPPORTS
static bool Start(nsIInputStream* aStream, JS::StreamConsumer* aConsumer,
nsIGlobalObject* aGlobal, WorkerPrivate* aMaybeWorker) {
nsresult rv;
bool nonBlocking = false;
rv = aStream->IsNonBlocking(&nonBlocking);
static bool Start(nsCOMPtr<nsIInputStream>&& aStream,
JS::StreamConsumer* aConsumer, nsIGlobalObject* aGlobal,
WorkerPrivate* aMaybeWorker) {
nsCOMPtr<nsIAsyncInputStream> asyncStream;
nsresult rv = NS_MakeAsyncNonBlockingInputStream(
aStream.forget(), getter_AddRefs(asyncStream));
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
// Use a pipe to create an nsIAsyncInputStream if we don't already have one.
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aStream);
if (!asyncStream || !nonBlocking) {
nsCOMPtr<nsIAsyncOutputStream> pipe;
rv = NS_NewPipe2(getter_AddRefs(asyncStream), getter_AddRefs(pipe), true,
true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
nsCOMPtr<nsIEventTarget> thread =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
rv = NS_AsyncCopy(aStream, pipe, thread, NS_ASYNCCOPY_VIA_WRITESEGMENTS);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
}
RefPtr<JSStreamConsumer> consumer;
if (aMaybeWorker) {
RefPtr<WorkerStreamOwner> owner =
@ -553,7 +534,8 @@ bool FetchUtil::StreamResponseToJS(JSContext* aCx, JS::HandleObject aObj,
nsIGlobalObject* global = xpc::NativeGlobal(js::UncheckedUnwrap(aObj));
if (!JSStreamConsumer::Start(body, aConsumer, global, aMaybeWorker)) {
if (!JSStreamConsumer::Start(std::move(body), aConsumer, global,
aMaybeWorker)) {
return ThrowException(aCx, JSMSG_OUT_OF_MEMORY);
}

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

@ -2966,30 +2966,7 @@ void HTMLInputElement::Focus(ErrorResult& aError) {
}
}
if (mType != NS_FORM_INPUT_FILE) {
nsGenericHTMLElement::Focus(aError);
return;
}
// For file inputs, focus the first button instead. In the case of there
// being two buttons (when the picker is a directory picker) the user can
// tab to the next one.
nsIFrame* frame = GetPrimaryFrame();
if (frame) {
for (nsIFrame* childFrame : frame->PrincipalChildList()) {
// See if the child is a button control.
nsCOMPtr<nsIFormControl> formCtrl =
do_QueryInterface(childFrame->GetContent());
if (formCtrl && formCtrl->ControlType() == NS_FORM_BUTTON_BUTTON) {
nsCOMPtr<Element> element = do_QueryInterface(formCtrl);
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm && element) {
fm->SetFocus(element, 0);
}
break;
}
}
}
nsGenericHTMLElement::Focus(aError);
}
#if !defined(ANDROID) && !defined(XP_MACOSX)
@ -3651,8 +3628,7 @@ bool HTMLInputElement::ShouldPreventDOMActivateDispatch(
return target->GetParent() == this &&
target->IsRootOfNativeAnonymousSubtree() &&
target->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
nsGkAtoms::button, eCaseMatters);
target->IsHTMLElement(nsGkAtoms::button);
}
nsresult HTMLInputElement::MaybeInitPickers(EventChainPostVisitor& aVisitor) {
@ -3910,6 +3886,7 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
case NS_FORM_INPUT_BUTTON:
case NS_FORM_INPUT_RESET:
case NS_FORM_INPUT_SUBMIT:
case NS_FORM_INPUT_FILE:
case NS_FORM_INPUT_IMAGE: // Bug 34418
case NS_FORM_INPUT_COLOR: {
DispatchSimulatedClick(this, aVisitor.mEvent->IsTrusted(),
@ -6324,18 +6301,13 @@ bool HTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
const bool defaultFocusable = true;
#endif
if (mType == NS_FORM_INPUT_FILE || mType == NS_FORM_INPUT_NUMBER ||
mType == NS_FORM_INPUT_TIME || mType == NS_FORM_INPUT_DATE) {
if (mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_TIME ||
mType == NS_FORM_INPUT_DATE) {
if (aTabIndex) {
// We only want our native anonymous child to be tabable to, not ourself.
*aTabIndex = -1;
}
if (mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_TIME ||
mType == NS_FORM_INPUT_DATE) {
*aIsFocusable = true;
} else {
*aIsFocusable = defaultFocusable;
}
*aIsFocusable = true;
return true;
}

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

@ -899,8 +899,9 @@ static bool WasmExtractCode(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
static bool WasmHasTier2CompilationCompleted(JSContext* cx, unsigned argc,
Value* vp) {
enum class Flag { Tier2Complete, Deserialized };
static bool WasmReturnFlag(JSContext* cx, unsigned argc, Value* vp, Flag flag) {
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.get(0).isObject()) {
@ -915,10 +916,29 @@ static bool WasmHasTier2CompilationCompleted(JSContext* cx, unsigned argc,
return false;
}
args.rval().set(BooleanValue(!module->module().testingTier2Active()));
bool b;
switch (flag) {
case Flag::Tier2Complete:
b = !module->module().testingTier2Active();
break;
case Flag::Deserialized:
b = module->module().loggingDeserialized();
break;
}
args.rval().set(BooleanValue(b));
return true;
}
static bool WasmHasTier2CompilationCompleted(JSContext* cx, unsigned argc,
Value* vp) {
return WasmReturnFlag(cx, argc, vp, Flag::Tier2Complete);
}
static bool WasmLoadedFromCache(JSContext* cx, unsigned argc, Value* vp) {
return WasmReturnFlag(cx, argc, vp, Flag::Deserialized);
}
static bool IsLazyFunction(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 1) {
@ -6041,6 +6061,11 @@ gc::ZealModeHelpText),
" Returns a boolean indicating whether a given module has finished compiled code for tier2. \n"
"This will return true early if compilation isn't two-tiered. "),
JS_FN_HELP("wasmLoadedFromCache", WasmLoadedFromCache, 1, 0,
"wasmLoadedFromCache(module)",
" Returns a boolean indicating whether a given module was deserialized directly from a\n"
" cache (as opposed to compiled from bytecode)."),
JS_FN_HELP("wasmReftypesEnabled", WasmReftypesEnabled, 1, 0,
"wasmReftypesEnabled()",
" Returns a boolean indicating whether the WebAssembly reftypes proposal is enabled."),

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

@ -1,6 +1,8 @@
// |jit-test| skip-if: !wasmStreamingIsSupported()
// |jit-test| skip-if: !wasmCachingIsSupported()
const {Module, Instance, compileStreaming} = WebAssembly;
load(libdir + "wasm-binary.js");
const {Module, Instance, compileStreaming, RuntimeError} = WebAssembly;
function testCached(code, imports, test) {
if (typeof code === 'string')
@ -12,20 +14,21 @@ function testCached(code, imports, test) {
compileStreaming(cache)
.then(m => {
test(new Instance(m, imports));
assertEq(wasmLoadedFromCache(m), false);
while (!wasmHasTier2CompilationCompleted(m)) {
sleep(1);
}
assertEq(cache.cached, wasmCachingIsSupported());
assertEq(cache.cached, true);
return compileStreaming(cache);
})
.then(m => {
test(new Instance(m, imports));
assertEq(cache.cached, wasmCachingIsSupported());
assertEq(wasmLoadedFromCache(m), true);
assertEq(cache.cached, true);
if (wasmCachingIsSupported()) {
let m2 = wasmCompileInSeparateProcess(code);
test(new Instance(m2, imports));
}
let m2 = wasmCompileInSeparateProcess(code);
test(new Instance(m2, imports));
assertEq(wasmLoadedFromCache(m2), true);
success = true;
})
@ -78,4 +81,16 @@ testCached(
}
);
testCached(
moduleWithSections([
sigSection([{args:[], ret:VoidCode}]),
declSection([0]),
exportSection([{funcIndex:0, name:"run"}]),
bodySection([funcBody({locals:[], body:[UnreachableCode]})]),
nameSection([funcNameSubsection([{name:"wee"}])])
]),
undefined,
i => assertErrorMessage(() => i.exports.run(), RuntimeError, /unreachable/)
);
// Note: a fuller behavioral test of caching is in bench/wasm_box2d.js.

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

@ -2778,6 +2778,12 @@ static bool Reject(JSContext* cx, const CompileArgs& args,
return PromiseObject::reject(cx, promise, rejectionValue);
}
static void LogAsync(JSContext* cx, const char* funcName,
const Module& module) {
Log(cx, "async %s succeeded%s", funcName,
module.loggingDeserialized() ? " (loaded from cache)" : "");
}
enum class Ret { Pair, Instance };
class AsyncInstantiateTask : public OffThreadPromiseTask {
@ -2840,7 +2846,7 @@ class AsyncInstantiateTask : public OffThreadPromiseTask {
return RejectWithPendingException(cx, promise);
}
Log(cx, "async instantiate succeeded");
LogAsync(cx, "instantiate", *module_);
return true;
}
};
@ -2875,7 +2881,7 @@ static bool ResolveCompile(JSContext* cx, const Module& module,
return RejectWithPendingException(cx, promise);
}
Log(cx, "async compile succeeded");
LogAsync(cx, "compile", module);
return true;
}

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

@ -286,14 +286,6 @@ MutableModule Module::deserialize(const uint8_t* begin, size_t size,
return nullptr;
}
if (metadata->nameCustomSectionIndex) {
metadata->namePayload =
customSections[*metadata->nameCustomSectionIndex].payload;
} else {
MOZ_RELEASE_ASSERT(!metadata->moduleName);
MOZ_RELEASE_ASSERT(metadata->funcNames.empty());
}
SharedCode code;
cursor = Code::deserialize(cursor, linkData, *metadata, &code);
if (!cursor) {
@ -303,9 +295,18 @@ MutableModule Module::deserialize(const uint8_t* begin, size_t size,
MOZ_RELEASE_ASSERT(cursor == begin + size);
MOZ_RELEASE_ASSERT(!!maybeMetadata == code->metadata().isAsmJS());
if (metadata->nameCustomSectionIndex) {
metadata->namePayload =
customSections[*metadata->nameCustomSectionIndex].payload;
} else {
MOZ_RELEASE_ASSERT(!metadata->moduleName);
MOZ_RELEASE_ASSERT(metadata->funcNames.empty());
}
return js_new<Module>(*code, std::move(imports), std::move(exports),
std::move(dataSegments), std::move(elemSegments),
std::move(customSections));
std::move(customSections), nullptr, nullptr, nullptr,
/* loggingDeserialized = */ true);
}
void Module::serialize(const LinkData& linkData,

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

@ -101,6 +101,11 @@ class Module : public JS::WasmModule {
mutable Tier2Listener tier2Listener_;
// This flag is used for logging (and testing) purposes to indicate
// whether the module was deserialized (from a cache).
const bool loggingDeserialized_;
// This flag is only used for testing purposes and is cleared on success or
// failure. The field is racily polled from various threads.
@ -140,7 +145,8 @@ class Module : public JS::WasmModule {
CustomSectionVector&& customSections,
UniqueConstBytes debugUnlinkedCode = nullptr,
UniqueLinkData debugLinkData = nullptr,
const ShareableBytes* debugBytecode = nullptr)
const ShareableBytes* debugBytecode = nullptr,
bool loggingDeserialized = false)
: code_(&code),
imports_(std::move(imports)),
exports_(std::move(exports)),
@ -151,6 +157,7 @@ class Module : public JS::WasmModule {
debugUnlinkedCode_(std::move(debugUnlinkedCode)),
debugLinkData_(std::move(debugLinkData)),
debugBytecode_(debugBytecode),
loggingDeserialized_(loggingDeserialized),
testingTier2Active_(false) {
MOZ_ASSERT_IF(metadata().debugEnabled,
debugUnlinkedCode_ && debugLinkData_);
@ -194,6 +201,7 @@ class Module : public JS::WasmModule {
JS::OptimizedEncodingListener& listener) const;
static RefPtr<Module> deserialize(const uint8_t* begin, size_t size,
Metadata* maybeMetadata = nullptr);
bool loggingDeserialized() const { return loggingDeserialized_; }
// JS API and JS::WasmModule implementation:

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

@ -212,8 +212,6 @@ static already_AddRefed<Element> MakeAnonButton(Document* aDoc,
// NOTE: SetIsNativeAnonymousRoot() has to be called before setting any
// attribute.
button->SetIsNativeAnonymousRoot();
button->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("button"), false);
// Set the file picking button text depending on the current locale.
nsAutoString buttonTxt;
@ -241,11 +239,8 @@ static already_AddRefed<Element> MakeAnonButton(Document* aDoc,
buttonElement->SetAccessKey(aAccessKey, IgnoreErrors());
}
// Both elements are given the same tab index so that the user can tab
// to the file control at the correct index, and then between the two
// buttons.
buttonElement->SetTabIndex(aInputElement->TabIndex(), IgnoreErrors());
// We allow tabbing over the input itself, not the button.
buttonElement->SetTabIndex(-1, IgnoreErrors());
return button.forget();
}
@ -277,7 +272,7 @@ nsresult nsFileControlFrame::CreateAnonymousContent(
// Update the displayed text to reflect the current element's value.
nsAutoString value;
HTMLInputElement::FromNode(mContent)->GetDisplayFileName(value);
fileContent->GetDisplayFileName(value);
UpdateDisplayedValue(value, false);
aElements.AppendElement(mTextContent);

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

@ -26,7 +26,7 @@ window.oTarget = null;
window.fileInputGotClick = false;
function test() {
// Try to find the 'Browse...' using tabbing.
// Try to find the '<input>' using tabbing.
var i = 0;
while (!window.oTarget && i < 100) {
++i;
@ -39,8 +39,7 @@ function test() {
return;
}
ok(window.oTarget instanceof HTMLButtonElement, "Should have focused an input element!")
ok(SpecialPowers.wrap(window.oTarget).type == "button", "Should have focused 'Browse...' button!");
ok(window.oTarget instanceof HTMLInputElement, "Should have focused the input element!");
var e = document.createEvent("mouseevents");
e.initMouseEvent("click", true, true, window, 0, 1, 1, 1, 1,
false, false, false, false, 0, null);

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

@ -495,7 +495,7 @@ input[type="file"] > label {
}
/* button part of file selector */
input[type="file"] > button[type="button"] {
input[type="file"] > button {
block-size: inherit;
font-size: unset;
letter-spacing: unset;
@ -703,8 +703,7 @@ button::-moz-focus-inner,
input[type="color"]::-moz-focus-inner,
input[type="reset"]::-moz-focus-inner,
input[type="button"]::-moz-focus-inner,
input[type="submit"]::-moz-focus-inner,
input[type="file"] > button[type="button"]::-moz-focus-inner {
input[type="submit"]::-moz-focus-inner {
/* Note this padding only affects the -moz-focus-inner ring, not the button itself */
padding-block-start: 0px;
padding-inline-end: 2px;
@ -717,8 +716,7 @@ button:-moz-focusring::-moz-focus-inner,
input[type="color"]:-moz-focusring::-moz-focus-inner,
input[type="reset"]:-moz-focusring::-moz-focus-inner,
input[type="button"]:-moz-focusring::-moz-focus-inner,
input[type="submit"]:-moz-focusring::-moz-focus-inner,
input[type="file"] > button[type="button"]:-moz-focusring::-moz-focus-inner {
input[type="submit"]:-moz-focusring::-moz-focus-inner {
border-color: ButtonText;
}

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

@ -715,7 +715,8 @@ canvas {
/* focusable content: anything w/ tabindex >=0 is focusable, but we
skip drawing a focus outline on a few things that handle it
themselves. */
:-moz-focusring:not(input):not(button):not(select):not(textarea):not(iframe):not(frame):not(body):not(html) {
:-moz-focusring:not(input):not(button):not(select):not(textarea):not(iframe):not(frame):not(body):not(html),
input[type="file"]:-moz-focusring {
/* Don't specify the outline-color, we should always use initial value. */
outline: 1px dotted;
}

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

@ -0,0 +1,18 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>HTML Test: file input can be programatically focused before layout</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#focus">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505355">
<link rel="author" title="Mozilla" href="https://mozilla.org/">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<input type="file">
<script>
test(function() {
let input = document.querySelector("input");
assert_not_equals(document.activeElement, input);
input.focus();
assert_equals(document.activeElement, input);
});
</script>

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

@ -399,7 +399,7 @@ function runBasicTest(aIsEditable, aInDesignMode, aDescription) {
description: "input[type=file]",
focusable: !aInDesignMode,
focusEventNotFired: aIsEditable && !aInDesignMode,
expectedEnabled: kEnabledStateOnReadonlyField },
expectedEnabled: kEnabledStateOnNonEditableElement },
{ id: "button",
description: "input[type=button]",
focusable: !aInDesignMode,