Commit 241e3ebd authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

-webkit-appearance: Implement element-type restriction for each of keywords

Implement element-type restriction for each of -webkit-appearance keywords.
ComputedStyle::Appearnace() returns a parsed -webkit-appearance keyword
as ever, and ComputedStyle::EffectiveAppearance() returns an appearance value
which is the result of AdjustAppearanceWithElementType().

This CL has no behavior changes at this moment because the new behavior
is behind the flag 'RestrictedWebkitAppearance'.

Bug: 965432, 981720
Change-Id: Idb43bb98a67d081c1e843ad4d6658a1f3cd495bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1735235Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#683919}
parent 19c93cb2
......@@ -50,7 +50,7 @@ input[type="month" i],
input[type="time" i],
input[type="week" i] {
align-items: center;
-webkit-appearance: menulist;
-webkit-appearance: menulist; /* AutoAppearanceFor() should match to this. */
background-color: ButtonFace;
border: 1px solid #a9a9a9;
display: -webkit-inline-flex;
......
......@@ -395,7 +395,7 @@ fieldset {
}
button {
-webkit-appearance: button;
-webkit-appearance: button; /* AutoAppearanceFor() should match to this. */
}
/* Form controls don't go vertical. */
......@@ -423,7 +423,7 @@ input[type="hidden" i] {
}
input {
-webkit-appearance: textfield;
-webkit-appearance: textfield; /* AutoAppearanceFor() should match to this. */
padding: 1px;
background-color: white;
border: 2px inset;
......@@ -432,7 +432,7 @@ input {
}
input[type="search" i] {
-webkit-appearance: searchfield;
-webkit-appearance: searchfield; /* AutoAppearanceFor() should match to this. */
box-sizing: border-box;
}
......@@ -444,7 +444,7 @@ input::-webkit-textfield-decoration-container {
}
input::-webkit-clear-button {
-webkit-appearance: searchfield-cancel-button;
-webkit-appearance: searchfield-cancel-button; /* AutoAppearanceFor() should match to this. */
display: inline-block;
cursor: default;
flex: none;
......@@ -460,7 +460,7 @@ input:enabled:read-write:-webkit-any(:focus,:hover)::-webkit-clear-button {
}
input[type="search" i]::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
-webkit-appearance: searchfield-cancel-button; /* AutoAppearanceFor() should match to this. */
display: block;
cursor: default;
flex: none;
......@@ -477,7 +477,7 @@ input[type="search" i]:enabled:read-write:-webkit-any(:focus,:hover)::-webkit-se
}
input::-webkit-inner-spin-button {
-webkit-appearance: inner-spin-button;
-webkit-appearance: inner-spin-button; /* AutoAppearanceFor() should match to this. */
display: inline-block;
cursor: default;
flex: none;
......@@ -497,7 +497,7 @@ select {
}
textarea {
-webkit-appearance: textarea;
-webkit-appearance: textarea; /* AutoAppearanceFor() should match to this. */
background-color: white;
border: 1px solid;
-webkit-rtl-ordering: logical;
......@@ -544,7 +544,7 @@ input[type="password" i]::-internal-input-suggested {
}
input[type="hidden" i], input[type="image" i], input[type="file" i] {
-webkit-appearance: initial;
-webkit-appearance: initial; /* AutoAppearanceFor() should match to this. */
padding: initial;
background-color: initial;
border: initial;
......@@ -588,13 +588,13 @@ input[type="radio" i], input[type="checkbox" i] {
}
input[type="button" i], input[type="submit" i], input[type="reset" i] {
-webkit-appearance: push-button;
-webkit-appearance: push-button; /* AutoAppearanceFor() should match to this. */
-webkit-user-select: none;
white-space: pre
}
input[type="file" i]::-webkit-file-upload-button {
-webkit-appearance: push-button;
-webkit-appearance: push-button; /* AutoAppearanceFor() should match to this. */
-webkit-user-modify: read-only !important;
white-space: nowrap;
margin: 0;
......@@ -613,7 +613,7 @@ input[type="button" i], input[type="submit" i], input[type="reset" i], input[typ
}
input[type="range" i] {
-webkit-appearance: slider-horizontal;
-webkit-appearance: slider-horizontal; /* AutoAppearanceFor() should match to this. */
padding: initial;
border: initial;
margin: 2px;
......@@ -622,7 +622,7 @@ input[type="range" i] {
}
input[type="range" i]::-webkit-slider-container, input[type="range" i]::-webkit-media-slider-container {
-webkit-appearance: inherit;
-webkit-appearance: inherit; /* AutoAppearanceFor() should match to this. */
flex: 1;
min-width: 0;
box-sizing: border-box;
......@@ -641,7 +641,7 @@ input[type="range" i]::-webkit-slider-runnable-track {
}
input[type="range" i]::-webkit-slider-thumb, input[type="range" i]::-webkit-media-slider-thumb {
-webkit-appearance: sliderthumb-horizontal;
-webkit-appearance: sliderthumb-horizontal; /* AutoAppearanceFor() should match to this. */
box-sizing: border-box;
-webkit-user-modify: read-only !important;
display: block;
......@@ -689,17 +689,17 @@ param {
}
input[type="checkbox" i] {
-webkit-appearance: checkbox;
-webkit-appearance: checkbox; /* AutoAppearanceFor() should match to this. */
box-sizing: border-box;
}
input[type="radio" i] {
-webkit-appearance: radio;
-webkit-appearance: radio; /* AutoAppearanceFor() should match to this. */
box-sizing: border-box;
}
input[type="color" i] {
-webkit-appearance: square-button;
-webkit-appearance: square-button; /* AutoAppearanceFor() should match to this. */
width: 44px;
height: 23px;
background-color: ButtonFace;
......@@ -727,7 +727,7 @@ input[type="color" i]::-webkit-color-swatch {
}
input[type="color" i][list] {
-webkit-appearance: menulist;
-webkit-appearance: menulist; /* AutoAppearanceFor() should match to this. */
width: 88px;
height: 23px
}
......@@ -784,7 +784,7 @@ input[readonly]::-webkit-calendar-picker-indicator {
}
select {
-webkit-appearance: menulist;
-webkit-appearance: menulist; /* AutoAppearanceFor() should match to this. */
box-sizing: border-box;
align-items: center;
border: 1px solid;
......@@ -800,7 +800,7 @@ select:not(:-internal-list-box) {
}
select:-internal-list-box {
-webkit-appearance: listbox;
-webkit-appearance: listbox; /* AutoAppearanceFor() should match to this. */
align-items: flex-start;
border: 1px inset gray;
border-radius: initial;
......@@ -864,7 +864,7 @@ output {
/* meter */
meter {
-webkit-appearance: meter;
-webkit-appearance: meter; /* AutoAppearanceFor() should match to this. */
box-sizing: border-box;
display: inline-block;
height: 1em;
......@@ -874,7 +874,7 @@ meter {
}
meter::-webkit-meter-inner-element {
-webkit-appearance: inherit;
-webkit-appearance: inherit; /* AutoAppearanceFor() should match to this. */
box-sizing: inherit;
display: none;
-webkit-user-modify: read-only !important;
......@@ -922,7 +922,7 @@ meter::-webkit-meter-even-less-good-value {
/* progress */
progress {
-webkit-appearance: progress-bar;
-webkit-appearance: progress-bar; /* AutoAppearanceFor() should match to this. */
box-sizing: border-box;
display: inline-block;
height: 1em;
......
......@@ -21,11 +21,13 @@
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/fileapi/file_list.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
......@@ -35,6 +37,7 @@
#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/html/forms/spin_button_element.h"
#include "third_party/blink/renderer/core/html/forms/text_control_inner_elements.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
......@@ -63,6 +66,80 @@
namespace blink {
namespace {
// This function should match to the user-agent stylesheet.
ControlPart AutoAppearanceFor(const Element& element) {
if (IsA<HTMLButtonElement>(element))
return kButtonPart;
if (IsA<HTMLMeterElement>(element))
return kMeterPart;
if (IsA<HTMLProgressElement>(element))
return kProgressBarPart;
if (IsA<HTMLTextAreaElement>(element))
return kTextAreaPart;
if (IsA<SpinButtonElement>(element))
return kInnerSpinButtonPart;
if (const auto* select = DynamicTo<HTMLSelectElement>(element))
return select->UsesMenuList() ? kMenulistPart : kListboxPart;
if (const auto* input = DynamicTo<HTMLInputElement>(element)) {
const AtomicString& type = input->type();
if (type == input_type_names::kCheckbox)
return kCheckboxPart;
if (type == input_type_names::kRadio)
return kRadioPart;
if (input->IsTextButton())
return kPushButtonPart;
if (type == input_type_names::kColor) {
return input->FastHasAttribute(html_names::kListAttr) ? kMenulistPart
: kSquareButtonPart;
}
if (type == input_type_names::kRange)
return kSliderHorizontalPart;
if (type == input_type_names::kSearch)
return kSearchFieldPart;
if (type == input_type_names::kDate ||
type == input_type_names::kDatetimeLocal ||
type == input_type_names::kMonth || type == input_type_names::kTime ||
type == input_type_names::kWeek) {
#if defined(OS_ANDROID)
return kMenulistPart;
#else
return kTextFieldPart;
#endif
}
if (type == input_type_names::kEmail || type == input_type_names::kNumber ||
type == input_type_names::kPassword || type == input_type_names::kTel ||
type == input_type_names::kText || type == input_type_names::kUrl)
return kTextFieldPart;
// Type=hidden/image/file.
return kNoControlPart;
}
if (element.IsInUserAgentShadowRoot()) {
const AtomicString& id_value =
element.FastGetAttribute(html_names::kIdAttr);
if (id_value == shadow_element_names::SliderThumb())
return kSliderThumbHorizontalPart;
if (id_value == shadow_element_names::SearchClearButton() ||
id_value == shadow_element_names::ClearButton())
return kSearchFieldCancelButtonPart;
// Slider container elements and -webkit-meter-inner-element don't have IDs.
const AtomicString& shadow_pseudo = element.ShadowPseudoId();
if (shadow_pseudo == "-webkit-media-slider-container" ||
shadow_pseudo == "-webkit-slider-container")
return kSliderHorizontalPart;
if (shadow_pseudo == "-webkit-meter-inner-element")
return kMeterPart;
}
return kNoControlPart;
}
} // namespace
// Wrapper function defined in WebKit.h
void SetMockThemeEnabledForTest(bool value) {
WebTestSupport::SetMockThemeEnabledForTest(value);
......@@ -92,11 +169,69 @@ ControlPart LayoutTheme::AdjustAppearanceWithElementType(
const ComputedStyle& style,
const Element* element) {
ControlPart part = style.EffectiveAppearance();
// TODO(crbug.com/981720): Implement element type restriction, and apply
// 'auto' if |part| doesn't support |element|.
// e.g. kSearchFieldPart for input[type=search] ==> kSearchFieldPart
// kSearchFieldPart for div ==> kNoControlPart
// kSearchFieldPart for button ==> kButtonPart
if (!RuntimeEnabledFeatures::RestrictedWebkitAppearanceEnabled())
return part;
if (!element)
return kNoControlPart;
ControlPart auto_appearance = AutoAppearanceFor(*element);
if (part == auto_appearance)
return part;
switch (part) {
// No restrictions.
case kNoControlPart:
case kMediaSliderPart:
case kMediaSliderThumbPart:
case kMediaVolumeSliderPart:
case kMediaVolumeSliderThumbPart:
case kMediaControlPart:
return part;
// Aliases of 'auto'.
// https://drafts.csswg.org/css-ui-4/#typedef-appearance-compat-auto
case kCheckboxPart:
case kRadioPart:
case kPushButtonPart:
case kSquareButtonPart:
case kInnerSpinButtonPart:
case kListboxPart:
case kMenulistPart:
case kMeterPart:
case kProgressBarPart:
case kSliderHorizontalPart:
case kSliderThumbHorizontalPart:
case kSearchFieldPart:
case kSearchFieldCancelButtonPart:
case kTextAreaPart:
return auto_appearance;
// The following keywords should work well for some element types
// even if their default appearances are different from the keywords.
case kButtonPart:
if (IsA<HTMLSelectElement>(*element) || IsA<HTMLAnchorElement>(*element))
return auto_appearance;
return part;
case kMenulistButtonPart:
return auto_appearance == kMenulistPart ? part : auto_appearance;
case kSliderVerticalPart:
return auto_appearance == kSliderHorizontalPart ? part : auto_appearance;
case kSliderThumbVerticalPart:
return auto_appearance == kSliderThumbHorizontalPart ? part
: auto_appearance;
case kTextFieldPart:
if (IsA<HTMLInputElement>(*element) &&
To<HTMLInputElement>(*element).type() == input_type_names::kSearch)
return part;
return auto_appearance;
}
return part;
}
......
......@@ -1338,6 +1338,9 @@
depends_on: ["AutomaticLazyImageLoading"],
status: "experimental",
},
{
name: "RestrictedWebkitAppearance",
},
{
name: "RtcAudioJitterBufferMaxPackets",
origin_trial_feature_name: "RtcAudioJitterBufferMaxPackets",
......
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