Commit 39537d31 authored by Vadym Doroshenko's avatar Vadym Doroshenko Committed by Commit Bot

Blink stable ids for forms and form control elements.

This CL implements UniqueRendererFormId and UniqueRendererFormControlId
methods in forms and form control elements correspondingly, which
return consecutive numbers of the current form and the form control
element in the current renderer process. Hence these ids are unique in
the same Renderer process modulo unsigned int overflow (which is not
the problem for Password Manager and Autofill).

Details go/blink-form-stable-ids

Bug:831119

Change-Id: Ie0c54363bc069b0f8953a3238ccd08262c7efd3c
Reviewed-on: https://chromium-review.googlesource.com/1002847
Commit-Queue: Vadym Doroshenko <dvadym@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557141}
parent 1c67dcbe
......@@ -119,6 +119,12 @@ class BLINK_EXPORT WebFormControlElement : public WebElement {
WebFormElement Form() const;
// Returns the identifier which is unique among all form control elements in
// the current renderer process. In the current implementation ids are
// consecutive numbers so their uniqueness might be broken in case of
// overflow.
unsigned UniqueRendererFormControlId() const;
#if INSIDE_BLINK
WebFormControlElement(HTMLFormControlElement*);
WebFormControlElement& operator=(HTMLFormControlElement*);
......
......@@ -59,6 +59,12 @@ class BLINK_EXPORT WebFormElement final : public WebElement {
WebString GetName() const;
WebString Method() const;
// Returns the identifier which is unique among all form elements in the
// current renderer process. In the current implementation ids are
// consecutive numbers so their uniqueness might be broken in case of
// overflow.
unsigned UniqueRendererFormId() const;
void GetFormControlElements(WebVector<WebFormControlElement>&) const;
#if INSIDE_BLINK
......
......@@ -1819,6 +1819,7 @@ jumbo_source_set("unit_tests") {
"html/forms/file_input_type_test.cc",
"html/forms/form_data_test.cc",
"html/forms/html_form_control_element_test.cc",
"html/forms/html_form_element_test.cc",
"html/forms/html_input_element_test.cc",
"html/forms/html_output_element_test.cc",
"html/forms/html_select_element_test.cc",
......
......@@ -215,6 +215,10 @@ WebFormElement WebFormControlElement::Form() const {
return WebFormElement(ConstUnwrap<HTMLFormControlElement>()->Form());
}
unsigned WebFormControlElement::UniqueRendererFormControlId() const {
return ConstUnwrap<HTMLFormControlElement>()->UniqueRendererFormControlId();
}
WebFormControlElement::WebFormControlElement(HTMLFormControlElement* elem)
: WebElement(elem) {}
......
......@@ -58,6 +58,10 @@ WebString WebFormElement::Method() const {
return ConstUnwrap<HTMLFormElement>()->method();
}
unsigned WebFormElement::UniqueRendererFormId() const {
return ConstUnwrap<HTMLFormElement>()->UniqueRendererFormId();
}
void WebFormElement::GetFormControlElements(
WebVector<WebFormControlElement>& result) const {
const HTMLFormElement* form = ConstUnwrap<HTMLFormElement>();
......
......@@ -63,6 +63,8 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tag_name,
validity_is_dirty_(false),
blocks_form_submission_(false) {
SetHasCustomStyleCallbacks();
static unsigned next_free_unique_id = 0;
unique_renderer_form_control_id_ = next_free_unique_id++;
}
HTMLFormControlElement::~HTMLFormControlElement() = default;
......
......@@ -142,6 +142,10 @@ class CORE_EXPORT HTMLFormControlElement : public LabelableElement,
bool BlocksFormSubmission() const { return blocks_form_submission_; }
void SetBlocksFormSubmission(bool value) { blocks_form_submission_ = value; }
unsigned UniqueRendererFormControlId() const {
return unique_renderer_form_control_id_;
}
protected:
HTMLFormControlElement(const QualifiedName& tag_name, Document&);
......@@ -190,6 +194,8 @@ class CORE_EXPORT HTMLFormControlElement : public LabelableElement,
// Requests validity recalc for all ancestor fieldsets, if exist.
void FieldSetAncestorsSetNeedsValidityCheck(Node*);
unsigned unique_renderer_form_control_id_;
enum AncestorDisabledState {
kAncestorDisabledStateUnknown,
kAncestorDisabledStateEnabled,
......
......@@ -147,4 +147,15 @@ TEST_F(HTMLFormControlElementTest, DoNotUpdateLayoutDuringDOMMutation) {
<< "DOM mutation should not handle validation message UI in it.";
}
TEST_F(HTMLFormControlElementTest, UniqueRendererFormControlId) {
SetHtmlInnerHTML("<body><input id=input1><input id=input2></body>");
auto* form_control1 = ToHTMLFormControlElement(GetElementById("input1"));
unsigned first_id = form_control1->UniqueRendererFormControlId();
auto* form_control2 = ToHTMLFormControlElement(GetElementById("input2"));
EXPECT_EQ(first_id + 1, form_control2->UniqueRendererFormControlId());
SetHtmlInnerHTML("<body><select id=select1></body>");
auto* form_control3 = ToHTMLFormControlElement(GetElementById("select1"));
EXPECT_EQ(first_id + 2, form_control3->UniqueRendererFormControlId());
}
} // namespace blink
......@@ -75,7 +75,10 @@ HTMLFormElement::HTMLFormElement(Document& document)
has_elements_associated_by_form_attribute_(false),
did_finish_parsing_children_(false),
is_in_reset_function_(false),
was_demoted_(false) {}
was_demoted_(false) {
static unsigned next_nique_renderer_form_id = 0;
unique_renderer_form_id_ = next_nique_renderer_form_id++;
}
HTMLFormElement* HTMLFormElement::Create(Document& document) {
UseCounter::Count(document, WebFeature::kFormElement);
......
......@@ -112,6 +112,8 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
void ConstructFormDataSet(HTMLFormControlElement* submit_button,
FormData& form_data);
unsigned UniqueRendererFormId() const { return unique_renderer_form_id_; }
private:
explicit HTMLFormElement(Document&);
......@@ -173,6 +175,8 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
// function in 'submit' event handler.
Member<FormSubmission> planned_navigation_;
unsigned unique_renderer_form_id_;
bool is_submitting_ = false;
bool in_user_js_submit_event_ = false;
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
namespace blink {
class HTMLFormElementTest : public PageTestBase {
protected:
void SetUp() override;
};
void HTMLFormElementTest::SetUp() {
PageTestBase::SetUp();
GetDocument().SetMimeType("text/html");
}
TEST_F(HTMLFormElementTest, UniqueRendererFormId) {
SetHtmlInnerHTML(
"<body><form id='form1'></form><form id='form2'></form></body>");
auto* form1 = ToHTMLFormElement(GetElementById("form1"));
unsigned first_id = form1->UniqueRendererFormId();
auto* form2 = ToHTMLFormElement(GetElementById("form2"));
EXPECT_EQ(first_id + 1, form2->UniqueRendererFormId());
SetHtmlInnerHTML("<body><form id='form3'></form></body>");
auto* form3 = ToHTMLFormElement(GetElementById("form3"));
EXPECT_EQ(first_id + 2, form3->UniqueRendererFormId());
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment