зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
Коммит
7a0e800fa9
|
@ -1653,6 +1653,17 @@ nsDOMWindowUtils::GetFocusedInputType(nsAString& aType) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetFocusedActionHint(nsAString& aType) {
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aType = widget->GetInputContext().mActionHint;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetViewId(Element* aElement, nsViewID* aResult) {
|
||||
if (aElement && nsLayoutUtils::FindIDFor(aElement, aResult)) {
|
||||
|
|
|
@ -150,6 +150,23 @@ class nsFocusManager final : public nsIFocusManager,
|
|||
nsPIDOMWindowOuter* aWindow, SearchRange aSearchRange,
|
||||
nsPIDOMWindowOuter** aFocusedWindow);
|
||||
|
||||
/**
|
||||
* Helper function for MoveFocus which determines the next element
|
||||
* to move the focus to and returns it in aNextContent.
|
||||
*
|
||||
* aWindow is the window to adjust the focus within, and aStart is
|
||||
* the element to start navigation from. For tab key navigation,
|
||||
* this should be the currently focused element.
|
||||
*
|
||||
* aType is the type passed to MoveFocus. If aNoParentTraversal is set,
|
||||
* navigation is not done to parent documents and iteration returns to the
|
||||
* beginning (or end) of the starting document.
|
||||
*/
|
||||
nsresult DetermineElementToMoveFocus(nsPIDOMWindowOuter* aWindow,
|
||||
nsIContent* aStart, int32_t aType,
|
||||
bool aNoParentTraversal,
|
||||
nsIContent** aNextContent);
|
||||
|
||||
/**
|
||||
* Returns the content node that focus will be redirected to if aContent was
|
||||
* focused. This is used for the special case of certain XUL elements such
|
||||
|
@ -403,23 +420,6 @@ class nsFocusManager final : public nsIFocusManager,
|
|||
nsIContent** aStartContent,
|
||||
nsIContent** aEndContent);
|
||||
|
||||
/**
|
||||
* Helper function for MoveFocus which determines the next element
|
||||
* to move the focus to and returns it in aNextContent.
|
||||
*
|
||||
* aWindow is the window to adjust the focus within, and aStart is
|
||||
* the element to start navigation from. For tab key navigation,
|
||||
* this should be the currently focused element.
|
||||
*
|
||||
* aType is the type passed to MoveFocus. If aNoParentTraversal is set,
|
||||
* navigation is not done to parent documents and iteration returns to the
|
||||
* beginning (or end) of the starting document.
|
||||
*/
|
||||
nsresult DetermineElementToMoveFocus(nsPIDOMWindowOuter* aWindow,
|
||||
nsIContent* aStart, int32_t aType,
|
||||
bool aNoParentTraversal,
|
||||
nsIContent** aNextContent);
|
||||
|
||||
/**
|
||||
* Retrieve the next tabbable element in scope owned by aOwner, using
|
||||
* focusability and tabindex to determine the tab order.
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/BrowserBridgeChild.h"
|
||||
#include "mozilla/dom/HTMLFormElement.h"
|
||||
#include "mozilla/dom/HTMLTextAreaElement.h"
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
|
||||
|
@ -28,6 +29,7 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsIForm.h"
|
||||
|
@ -1179,6 +1181,123 @@ void IMEStateManager::SetInputContextForChildProcess(
|
|||
SetInputContext(widget, aInputContext, aAction);
|
||||
}
|
||||
|
||||
static bool IsNextFocusableElementTextOrNumberControl(Element* aInputContent) {
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (!fm) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIContent> nextContent;
|
||||
nsresult rv = fm->DetermineElementToMoveFocus(
|
||||
aInputContent->OwnerDoc()->GetWindow(), aInputContent,
|
||||
nsIFocusManager::MOVEFOCUS_FORWARD, true, getter_AddRefs(nextContent));
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || !nextContent) {
|
||||
return false;
|
||||
}
|
||||
nextContent = nextContent->FindFirstNonChromeOnlyAccessContent();
|
||||
nsCOMPtr<nsIFormControl> nextControl = do_QueryInterface(nextContent);
|
||||
if (!nextControl || !nextControl->IsTextOrNumberControl(false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX We don't consider next element is date/time control yet.
|
||||
nsGenericHTMLElement* nextElement =
|
||||
nsGenericHTMLElement::FromNodeOrNull(nextContent);
|
||||
if (!nextElement) {
|
||||
return false;
|
||||
}
|
||||
bool focusable = false;
|
||||
nextElement->IsHTMLFocusable(false, &focusable, nullptr);
|
||||
if (!focusable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check readonly attribute.
|
||||
if (nextElement->IsHTMLElement(nsGkAtoms::textarea)) {
|
||||
HTMLTextAreaElement* textAreaElement =
|
||||
HTMLTextAreaElement::FromNodeOrNull(nextElement);
|
||||
return !textAreaElement->ReadOnly();
|
||||
}
|
||||
|
||||
// If neither textarea nor input, what element type?
|
||||
MOZ_DIAGNOSTIC_ASSERT(nextElement->IsHTMLElement(nsGkAtoms::input));
|
||||
|
||||
HTMLInputElement* inputElement =
|
||||
HTMLInputElement::FromNodeOrNull(nextElement);
|
||||
return !inputElement->ReadOnly();
|
||||
}
|
||||
|
||||
static void GetActionHint(nsIContent& aContent, nsAString& aActionHint) {
|
||||
aContent.AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
|
||||
aActionHint);
|
||||
|
||||
if (!aActionHint.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the input content corresponding to the focused node,
|
||||
// which may be an anonymous child of the input content.
|
||||
nsIContent* inputContent = aContent.FindFirstNonChromeOnlyAccessContent();
|
||||
if (!inputContent->IsHTMLElement(nsGkAtoms::input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have an action hint and
|
||||
// return won't submit the form, use "next".
|
||||
bool willSubmit = false;
|
||||
bool isLastElement = false;
|
||||
nsCOMPtr<nsIFormControl> control(do_QueryInterface(inputContent));
|
||||
Element* formElement = nullptr;
|
||||
if (control) {
|
||||
formElement = control->GetFormElement();
|
||||
// is this a form and does it have a default submit element?
|
||||
if (formElement) {
|
||||
HTMLFormElement* htmlForm = nullptr;
|
||||
if (formElement->IsHTMLElement(nsGkAtoms::form)) {
|
||||
htmlForm = HTMLFormElement::FromNodeOrNull(formElement);
|
||||
if (htmlForm->IsLastActiveElement(control)) {
|
||||
isLastElement = true;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIForm> form = do_QueryInterface(formElement);
|
||||
if (form && form->GetDefaultSubmitElement()) {
|
||||
willSubmit = true;
|
||||
// is this an html form...
|
||||
} else if (htmlForm) {
|
||||
// ... and does it only have a single text input element ?
|
||||
if (!htmlForm->ImplicitSubmissionIsDisabled() ||
|
||||
// ... or is this the last non-disabled element?
|
||||
isLastElement) {
|
||||
willSubmit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLastElement && formElement) {
|
||||
// If next tabbable content in form is text control, hint should be "next"
|
||||
// even there is submit in form.
|
||||
if (IsNextFocusableElementTextOrNumberControl(
|
||||
inputContent->AsElement())) {
|
||||
// This is focusable text control
|
||||
// XXX What good hint for read only field?
|
||||
aActionHint.AssignLiteral("next");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!willSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (control->ControlType() == NS_FORM_INPUT_SEARCH) {
|
||||
aActionHint.AssignLiteral("search");
|
||||
return;
|
||||
}
|
||||
|
||||
aActionHint.AssignLiteral("go");
|
||||
}
|
||||
|
||||
// static
|
||||
void IMEStateManager::SetIMEState(const IMEState& aState,
|
||||
nsPresContext* aPresContext,
|
||||
|
@ -1245,46 +1364,7 @@ void IMEStateManager::SetIMEState(const IMEState& aState,
|
|||
}
|
||||
}
|
||||
|
||||
aContent->AsElement()->GetAttr(
|
||||
kNameSpaceID_None, nsGkAtoms::moz_action_hint, context.mActionHint);
|
||||
|
||||
// Get the input content corresponding to the focused node,
|
||||
// which may be an anonymous child of the input content.
|
||||
nsIContent* inputContent = aContent->FindFirstNonChromeOnlyAccessContent();
|
||||
|
||||
// If we don't have an action hint and
|
||||
// return won't submit the form, use "next".
|
||||
if (context.mActionHint.IsEmpty() &&
|
||||
inputContent->IsHTMLElement(nsGkAtoms::input)) {
|
||||
bool willSubmit = false;
|
||||
nsCOMPtr<nsIFormControl> control(do_QueryInterface(inputContent));
|
||||
mozilla::dom::Element* formElement = nullptr;
|
||||
nsCOMPtr<nsIForm> form;
|
||||
if (control) {
|
||||
formElement = control->GetFormElement();
|
||||
// is this a form and does it have a default submit element?
|
||||
if ((form = do_QueryInterface(formElement)) &&
|
||||
form->GetDefaultSubmitElement()) {
|
||||
willSubmit = true;
|
||||
// is this an html form...
|
||||
} else if (formElement && formElement->IsHTMLElement(nsGkAtoms::form)) {
|
||||
dom::HTMLFormElement* htmlForm =
|
||||
static_cast<dom::HTMLFormElement*>(formElement);
|
||||
// ... and does it only have a single text input element ?
|
||||
if (!htmlForm->ImplicitSubmissionIsDisabled() ||
|
||||
// ... or is this the last non-disabled element?
|
||||
htmlForm->IsLastActiveElement(control)) {
|
||||
willSubmit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
context.mActionHint.Assign(
|
||||
willSubmit
|
||||
? (control->ControlType() == NS_FORM_INPUT_SEARCH
|
||||
? NS_LITERAL_STRING("search")
|
||||
: NS_LITERAL_STRING("go"))
|
||||
: (formElement ? NS_LITERAL_STRING("next") : EmptyString()));
|
||||
}
|
||||
GetActionHint(*aContent, context.mActionHint);
|
||||
}
|
||||
|
||||
// XXX I think that we should use nsContentUtils::IsCallerChrome() instead
|
||||
|
|
|
@ -1621,7 +1621,8 @@ bool HTMLFormElement::IsLastActiveElement(
|
|||
MOZ_ASSERT(aControl, "Unexpected call");
|
||||
|
||||
for (auto* element : Reversed(mControls->mElements)) {
|
||||
if (element->IsSingleLineTextOrNumberControl(false) &&
|
||||
// XXX How about date/time control?
|
||||
if (element->IsTextOrNumberControl(false) &&
|
||||
!element->IsDisabled()) {
|
||||
return element == aControl;
|
||||
}
|
||||
|
|
|
@ -1466,6 +1466,11 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
*/
|
||||
readonly attribute AString focusedInputType;
|
||||
|
||||
/**
|
||||
* Get the action hint of the currently focused html input, if any.
|
||||
*/
|
||||
readonly attribute AString focusedActionHint;
|
||||
|
||||
/**
|
||||
* Find the view ID for a given element. This is the reverse of
|
||||
* findElementWithViewId().
|
||||
|
|
Двоичный файл не отображается.
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/**
|
||||
* This test is mainly to verify that string length is correctly computed for
|
||||
* database values containing NULs. See bug 1541681.
|
||||
*/
|
||||
|
||||
async function testSteps() {
|
||||
const principal = getPrincipal("http://example.org");
|
||||
|
||||
const data = {};
|
||||
data.key = "foobar";
|
||||
data.secondKey = "foobaz";
|
||||
data.value = {
|
||||
length: 19253,
|
||||
};
|
||||
data.usage = data.key.length + data.value.length;
|
||||
|
||||
async function checkUsage(expectedUsage) {
|
||||
info("Checking usage");
|
||||
|
||||
// This forces any pending changes to be flushed to disk. It also forces
|
||||
// data to be reloaded from disk at next localStorage API call.
|
||||
request = resetOrigin(principal);
|
||||
await requestFinished(request);
|
||||
|
||||
request = getOriginUsage(principal);
|
||||
await requestFinished(request);
|
||||
|
||||
is(request.result.usage, expectedUsage, "Correct usage");
|
||||
}
|
||||
|
||||
info("Setting pref");
|
||||
|
||||
Services.prefs.setBoolPref("dom.storage.next_gen", true);
|
||||
|
||||
info("Stage 1 - Checking usage after profile installation");
|
||||
|
||||
info("Clearing");
|
||||
|
||||
let request = clear();
|
||||
await requestFinished(request);
|
||||
|
||||
info("Installing package");
|
||||
|
||||
// The profile contains storage.sqlite and webappsstore.sqlite.
|
||||
installPackage("stringLength2_profile");
|
||||
|
||||
await checkUsage(0);
|
||||
|
||||
info("Stage 2 - Checking usage after archived data migration");
|
||||
|
||||
info("Opening database");
|
||||
|
||||
let storage = getLocalStorage(principal);
|
||||
storage.open();
|
||||
|
||||
await checkUsage(data.usage);
|
||||
|
||||
info("Stage 3 - Checking usage after copying the value");
|
||||
|
||||
info("Adding a second copy of the value");
|
||||
|
||||
let value = storage.getItem(data.key);
|
||||
storage.setItem(data.secondKey, value);
|
||||
|
||||
await checkUsage(2 * data.usage);
|
||||
|
||||
info("Stage 4 - Checking length of the copied value");
|
||||
|
||||
value = storage.getItem(data.secondKey);
|
||||
ok(value.length === data.value.length, "Correct string length");
|
||||
}
|
|
@ -9,6 +9,7 @@ support-files =
|
|||
corruptedDatabase_profile.zip
|
||||
groupMismatch_profile.zip
|
||||
migration_profile.zip
|
||||
stringLength2_profile.zip
|
||||
stringLength_profile.zip
|
||||
|
||||
[test_archive.js]
|
||||
|
@ -36,4 +37,5 @@ run-sequentially = this test depends on a file produced by test_databaseShadowin
|
|||
[test_originInit.js]
|
||||
[test_snapshotting.js]
|
||||
[test_stringLength.js]
|
||||
[test_stringLength2.js]
|
||||
[test_usage.js]
|
||||
|
|
|
@ -602,7 +602,7 @@ import java.lang.reflect.Proxy;
|
|||
case KeyEvent.KEYCODE_ENTER:
|
||||
if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 &&
|
||||
mIMEActionHint.equalsIgnoreCase("next")) {
|
||||
return new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB);
|
||||
return new KeyEvent(event.getDownTime(), event.getEventTime(), event.getAction(), KeyEvent.KEYCODE_TAB, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,29 @@
|
|||
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
if (AppConstants.platform != "android") {
|
||||
// We load HTML documents, which try to track link state, which requires
|
||||
// the history service, which requires a profile.
|
||||
do_get_profile();
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
// vectors by the html5security project (https://code.google.com/p/html5security/ & Creative Commons 3.0 BY), see CC-BY-LICENSE for the full license
|
||||
load("results.js"); // gives us a `vectors' array
|
||||
/* import-globals-from ./results.js */
|
||||
|
||||
if (AppConstants.platform != "android") {
|
||||
// xpcshell tests are weird. They fake shutdown after the test finishes. This upsets this test
|
||||
// because it will try to create the history service to check for visited state on the links
|
||||
// we're parsing.
|
||||
// Creating the history service midway through shutdown breaks.
|
||||
// We can't catch this in the history component because we're not *actually* shutting down,
|
||||
// and so the app startup's service's `shuttingDown` bool is false, even though normally that
|
||||
// is set to true *before* profile-change-teardown notifications are fired.
|
||||
// To work around this, just force the history service to be created earlier:
|
||||
|
||||
let {PlacesUtils} = ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
Assert.ok(PlacesUtils.history.databaseStatus <= 1, "ensure places database is successfully initialized.");
|
||||
}
|
||||
|
||||
var ParserUtils = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
|
||||
var sanitizeFlags = ParserUtils.SanitizerCidEmbedsOnly | ParserUtils.SanitizerDropForms | ParserUtils.SanitizerDropNonCSSPresentation;
|
||||
// flags according to
|
||||
|
|
|
@ -347,10 +347,7 @@ void utf16LengthFunction(sqlite3_context *aCtx, int aArgc,
|
|||
sqlite3_value **aArgv) {
|
||||
NS_ASSERTION(1 == aArgc, "Invalid number of arguments!");
|
||||
|
||||
nsDependentString data(
|
||||
static_cast<const char16_t *>(::sqlite3_value_text16(aArgv[0])));
|
||||
|
||||
int len = data.Length();
|
||||
int len = ::sqlite3_value_bytes16(aArgv[0]) / sizeof(char16_t);
|
||||
|
||||
// Set the result.
|
||||
::sqlite3_result_int(aCtx, len);
|
||||
|
|
|
@ -102,7 +102,8 @@ nsIWidget* nsWebBrowser::EnsureWidget() {
|
|||
already_AddRefed<nsWebBrowser> nsWebBrowser::Create(
|
||||
nsIWebBrowserChrome* aContainerWindow, nsIWidget* aParentWidget,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
dom::BrowsingContext* aBrowsingContext) {
|
||||
dom::BrowsingContext* aBrowsingContext,
|
||||
bool aDisableHistory /* = false */) {
|
||||
RefPtr<nsWebBrowser> browser = new nsWebBrowser(
|
||||
aBrowsingContext->IsContent() ? typeContentWrapper : typeChromeWrapper);
|
||||
|
||||
|
@ -152,7 +153,7 @@ already_AddRefed<nsWebBrowser> nsWebBrowser::Create(
|
|||
|
||||
docShell->InitSessionHistory();
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
if (XRE_IsParentProcess() && !aDisableHistory) {
|
||||
// Hook up global history. Do not fail if we can't - just warn.
|
||||
DebugOnly<nsresult> rv =
|
||||
browser->EnableGlobalHistory(browser->mShouldEnableHistory);
|
||||
|
|
|
@ -108,7 +108,8 @@ class nsWebBrowser final : public nsIWebBrowser,
|
|||
static already_AddRefed<nsWebBrowser> Create(
|
||||
nsIWebBrowserChrome* aContainerWindow, nsIWidget* aParentWidget,
|
||||
const mozilla::OriginAttributes& aOriginAttributes,
|
||||
mozilla::dom::BrowsingContext* aBrowsingContext);
|
||||
mozilla::dom::BrowsingContext* aBrowsingContext,
|
||||
bool aDisableHistory = false);
|
||||
|
||||
protected:
|
||||
virtual ~nsWebBrowser();
|
||||
|
|
|
@ -1445,6 +1445,16 @@ History::History()
|
|||
mObservers(VISIT_OBSERVERS_INITIAL_CACHE_LENGTH),
|
||||
mRecentlyVisitedURIs(RECENTLY_VISITED_URIS_SIZE) {
|
||||
NS_ASSERTION(!gService, "Ruh-roh! This service has already been created!");
|
||||
if (XRE_IsParentProcess()) {
|
||||
nsCOMPtr<nsIProperties> dirsvc = services::GetDirectoryService();
|
||||
bool haveProfile = false;
|
||||
MOZ_RELEASE_ASSERT(
|
||||
dirsvc &&
|
||||
NS_SUCCEEDED(
|
||||
dirsvc->Has(NS_APP_USER_PROFILE_50_DIR, &haveProfile)) &&
|
||||
haveProfile,
|
||||
"Can't construct history service if there is no profile.");
|
||||
}
|
||||
gService = this;
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
|
|
|
@ -3,6 +3,7 @@ support-files = utils.js
|
|||
|
||||
[test_AltGr_key_events_in_web_content_on_windows.html]
|
||||
skip-if = toolkit != 'windows' || headless # headless: Bug 1410525
|
||||
[test_actionhint.html]
|
||||
[test_assign_event_data.html]
|
||||
subsuite = clipboard
|
||||
skip-if = toolkit == "cocoa" || (toolkit == 'android' && debug) || android_version == '24' # Mac: Bug 933303, Android bug 1285414
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tests for action hint that is used by software keyboard</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SpecialPowers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<div>
|
||||
<form><input type="text" id="a1"><input type="text" id="a2"><input type="submit"></form>
|
||||
<form><input type="search" id="b1"><input type="submit"></form>
|
||||
<form><input type="text" id="c1"></form>
|
||||
<form><input type="text" id="d1"><textarea></textarea><input type="submit"></form>
|
||||
<form><input type="text" id="e1"><input type="number"><input type="submit"></form>
|
||||
<form><input type="text" id="f1"><input type="date"><input type="submit"></form>
|
||||
<form><input type="text" id="g1"><input type="radio"><input type="submit"></form>
|
||||
<form><input type="text" id="h1"><input type="text" readonly><input type="submit"></form>
|
||||
<form><input type="text" id="i1"><input type="text" disabled><input type="submit"></form>
|
||||
<input type="text" id="j1"><input type="text"><input type="button">
|
||||
<form><input type="text" id="k1"><a href="#foo">foo</a><input type="text"><input type="submit"></form>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class=testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SimpleTest.waitForFocus(() => {
|
||||
const tests = [
|
||||
{ id: "a1", hint: "next", desc: "next element is type=text" },
|
||||
{ id: "a2", hint: "go", desc: "next element is type=submit" },
|
||||
{ id: "b1", hint: "search", desc: "current is type=search" },
|
||||
{ id: "c1", hint: "go", desc: "only this element" },
|
||||
{ id: "d1", hint: "next", desc: "next element is textarea" },
|
||||
{ id: "e1", hint: "next", desc: "next element is type=number" },
|
||||
{ id: "h1", hint: "go", desc: "next element is readonly" },
|
||||
// XXX Feel free to change this result if you get some bugs reports
|
||||
{ id: "i1", hint: "go", desc: "next element is disabled" },
|
||||
{ id: "j1", hint: "", desc: "no form element" },
|
||||
];
|
||||
|
||||
const todo_tests = [
|
||||
{ id: "f1", hint: "next", desc: "next element is type=date" },
|
||||
{ id: "k1", hint: "", desc: "next is anchor link" },
|
||||
];
|
||||
|
||||
for (let test of tests) {
|
||||
document.getElementById(test.id).focus();
|
||||
is(SpecialPowers.DOMWindowUtils.focusedActionHint, test.hint, test.desc);
|
||||
}
|
||||
|
||||
for (let test of todo_tests) {
|
||||
document.getElementById(test.id).focus();
|
||||
todo_is(SpecialPowers.DOMWindowUtils.focusedActionHint, test.hint, test.desc);
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -495,7 +495,8 @@ nsAppShellService::CreateWindowlessBrowser(bool aIsChrome,
|
|||
* an associated doc shell, which is what we're interested in.
|
||||
*/
|
||||
nsCOMPtr<nsIWebBrowser> browser =
|
||||
nsWebBrowser::Create(stub, widget, OriginAttributes(), browsingContext);
|
||||
nsWebBrowser::Create(stub, widget, OriginAttributes(), browsingContext,
|
||||
true /* disable history */);
|
||||
|
||||
if (NS_WARN_IF(!browser)) {
|
||||
NS_ERROR("Couldn't create instance of nsWebBrowser!");
|
||||
|
|
Загрузка…
Ссылка в новой задаче