diff options
Diffstat (limited to 'Source/WebCore/html/HTMLMeterElement.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLMeterElement.cpp | 140 |
1 files changed, 75 insertions, 65 deletions
diff --git a/Source/WebCore/html/HTMLMeterElement.cpp b/Source/WebCore/html/HTMLMeterElement.cpp index f7a470a14..52c88e780 100644 --- a/Source/WebCore/html/HTMLMeterElement.cpp +++ b/Source/WebCore/html/HTMLMeterElement.cpp @@ -19,22 +19,23 @@ */ #include "config.h" -#if ENABLE(METER_ELEMENT) #include "HTMLMeterElement.h" +#if ENABLE(METER_ELEMENT) + #include "Attribute.h" #include "ElementIterator.h" -#include "EventNames.h" -#include "ExceptionCode.h" #include "FormDataList.h" +#include "HTMLDivElement.h" #include "HTMLFormElement.h" #include "HTMLNames.h" #include "HTMLParserIdioms.h" -#include "MeterShadowElement.h" +#include "HTMLStyleElement.h" #include "Page.h" #include "RenderMeter.h" #include "RenderTheme.h" #include "ShadowRoot.h" +#include "UserAgentStyleSheets.h" namespace WebCore { @@ -50,24 +51,24 @@ HTMLMeterElement::~HTMLMeterElement() { } -PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document& document) +Ref<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document& document) { - RefPtr<HTMLMeterElement> meter = adoptRef(new HTMLMeterElement(tagName, document)); + Ref<HTMLMeterElement> meter = adoptRef(*new HTMLMeterElement(tagName, document)); meter->ensureUserAgentShadowRoot(); return meter; } -RenderPtr<RenderElement> HTMLMeterElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> HTMLMeterElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - if (hasAuthorShadowRoot() || !document().page()->theme().supportsMeter(style.get().appearance())) - return RenderElement::createFor(*this, std::move(style)); + if (!document().page()->theme().supportsMeter(style.appearance())) + return RenderElement::createFor(*this, WTFMove(style)); - return createRenderer<RenderMeter>(*this, std::move(style)); + return createRenderer<RenderMeter>(*this, WTFMove(style)); } bool HTMLMeterElement::childShouldCreateRenderer(const Node& child) const { - return hasShadowRootParent(child) && HTMLElement::childShouldCreateRenderer(child); + return !is<RenderMeter>(renderer()) && HTMLElement::childShouldCreateRenderer(child); } void HTMLMeterElement::parseAttribute(const QualifiedName& name, const AtomicString& value) @@ -80,90 +81,66 @@ void HTMLMeterElement::parseAttribute(const QualifiedName& name, const AtomicStr double HTMLMeterElement::min() const { - return parseToDoubleForNumberType(getAttribute(minAttr), 0); + return parseToDoubleForNumberType(attributeWithoutSynchronization(minAttr), 0); } -void HTMLMeterElement::setMin(double min, ExceptionCode& ec) +void HTMLMeterElement::setMin(double min) { - if (!std::isfinite(min)) { - ec = NOT_SUPPORTED_ERR; - return; - } - setAttribute(minAttr, AtomicString::number(min)); + setAttributeWithoutSynchronization(minAttr, AtomicString::number(min)); } double HTMLMeterElement::max() const { - return std::max(parseToDoubleForNumberType(getAttribute(maxAttr), std::max(1.0, min())), min()); + return std::max(parseToDoubleForNumberType(attributeWithoutSynchronization(maxAttr), std::max(1.0, min())), min()); } -void HTMLMeterElement::setMax(double max, ExceptionCode& ec) +void HTMLMeterElement::setMax(double max) { - if (!std::isfinite(max)) { - ec = NOT_SUPPORTED_ERR; - return; - } - setAttribute(maxAttr, AtomicString::number(max)); + setAttributeWithoutSynchronization(maxAttr, AtomicString::number(max)); } double HTMLMeterElement::value() const { - double value = parseToDoubleForNumberType(getAttribute(valueAttr), 0); + double value = parseToDoubleForNumberType(attributeWithoutSynchronization(valueAttr), 0); return std::min(std::max(value, min()), max()); } -void HTMLMeterElement::setValue(double value, ExceptionCode& ec) +void HTMLMeterElement::setValue(double value) { - if (!std::isfinite(value)) { - ec = NOT_SUPPORTED_ERR; - return; - } - setAttribute(valueAttr, AtomicString::number(value)); + setAttributeWithoutSynchronization(valueAttr, AtomicString::number(value)); } double HTMLMeterElement::low() const { - double low = parseToDoubleForNumberType(getAttribute(lowAttr), min()); + double low = parseToDoubleForNumberType(attributeWithoutSynchronization(lowAttr), min()); return std::min(std::max(low, min()), max()); } -void HTMLMeterElement::setLow(double low, ExceptionCode& ec) +void HTMLMeterElement::setLow(double low) { - if (!std::isfinite(low)) { - ec = NOT_SUPPORTED_ERR; - return; - } - setAttribute(lowAttr, AtomicString::number(low)); + setAttributeWithoutSynchronization(lowAttr, AtomicString::number(low)); } double HTMLMeterElement::high() const { - double high = parseToDoubleForNumberType(getAttribute(highAttr), max()); + double high = parseToDoubleForNumberType(attributeWithoutSynchronization(highAttr), max()); return std::min(std::max(high, low()), max()); } -void HTMLMeterElement::setHigh(double high, ExceptionCode& ec) +void HTMLMeterElement::setHigh(double high) { - if (!std::isfinite(high)) { - ec = NOT_SUPPORTED_ERR; - return; - } - setAttribute(highAttr, AtomicString::number(high)); + setAttributeWithoutSynchronization(highAttr, AtomicString::number(high)); } double HTMLMeterElement::optimum() const { - double optimum = parseToDoubleForNumberType(getAttribute(optimumAttr), (max() + min()) / 2); + double optimum = parseToDoubleForNumberType(attributeWithoutSynchronization(optimumAttr), (max() + min()) / 2); return std::min(std::max(optimum, min()), max()); } -void HTMLMeterElement::setOptimum(double optimum, ExceptionCode& ec) +void HTMLMeterElement::setOptimum(double optimum) { - if (!std::isfinite(optimum)) { - ec = NOT_SUPPORTED_ERR; - return; - } - setAttribute(optimumAttr, AtomicString::number(optimum)); + setAttributeWithoutSynchronization(optimumAttr, AtomicString::number(optimum)); } HTMLMeterElement::GaugeRegion HTMLMeterElement::gaugeRegion() const @@ -210,35 +187,68 @@ double HTMLMeterElement::valueRatio() const return (value - min) / (max - min); } +static void setValueClass(HTMLElement& element, HTMLMeterElement::GaugeRegion gaugeRegion) +{ + switch (gaugeRegion) { + case HTMLMeterElement::GaugeRegionOptimum: + element.setAttribute(HTMLNames::classAttr, "optimum"); + element.setPseudo("-webkit-meter-optimum-value"); + return; + case HTMLMeterElement::GaugeRegionSuboptimal: + element.setAttribute(HTMLNames::classAttr, "suboptimum"); + element.setPseudo("-webkit-meter-suboptimum-value"); + return; + case HTMLMeterElement::GaugeRegionEvenLessGood: + element.setAttribute(HTMLNames::classAttr, "even-less-good"); + element.setPseudo("-webkit-meter-even-less-good-value"); + return; + default: + ASSERT_NOT_REACHED(); + } +} + void HTMLMeterElement::didElementStateChange() { - m_value->setWidthPercentage(valueRatio()*100); - m_value->updatePseudo(); + m_value->setInlineStyleProperty(CSSPropertyWidth, valueRatio()*100, CSSPrimitiveValue::CSS_PERCENTAGE); + setValueClass(*m_value, gaugeRegion()); + if (RenderMeter* render = renderMeter()) render->updateFromElement(); } RenderMeter* HTMLMeterElement::renderMeter() const { - if (renderer() && renderer()->isMeter()) - return toRenderMeter(renderer()); - return toRenderMeter(descendantsOfType<Element>(*userAgentShadowRoot()).first()->renderer()); + if (is<RenderMeter>(renderer())) + return downcast<RenderMeter>(renderer()); + return nullptr; } void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot* root) { ASSERT(!m_value); - RefPtr<MeterInnerElement> inner = MeterInnerElement::create(document()); + static NeverDestroyed<String> shadowStyle(meterElementShadowUserAgentStyleSheet, String::ConstructFromLiteral); + + auto style = HTMLStyleElement::create(HTMLNames::styleTag, document(), false); + style->setTextContent(shadowStyle); + root->appendChild(style); + + // Pseudos are set to allow author styling. + auto inner = HTMLDivElement::create(document()); + inner->setIdAttribute("inner"); + inner->setPseudo("-webkit-meter-inner-element"); root->appendChild(inner); - RefPtr<MeterBarElement> bar = MeterBarElement::create(document()); - m_value = MeterValueElement::create(document()); - m_value->setWidthPercentage(0); - m_value->updatePseudo(); - bar->appendChild(m_value, ASSERT_NO_EXCEPTION); + auto bar = HTMLDivElement::create(document()); + bar->setIdAttribute("bar"); + bar->setPseudo("-webkit-meter-bar"); + inner->appendChild(bar); + + m_value = HTMLDivElement::create(document()); + m_value->setIdAttribute("value"); + bar->appendChild(*m_value); - inner->appendChild(bar, ASSERT_NO_EXCEPTION); + didElementStateChange(); } } // namespace |