Changeset 204021 in webkit


Ignore:
Timestamp:
Aug 2, 2016 2:43:01 AM (8 years ago)
Author:
fred.wang@free.fr
Message:

Use Optional members to store parsed MathML attributes.
https://bugs.webkit.org/show_bug.cgi?id=160400

Patch by Frederic Wang <fwang.igalia.com> on 2016-08-02
Reviewed by Darin Adler.

Parsed MathML attributes are stored on the element classes using the memoize pattern to
minimize the number of parsing updates. Currently, a dirty flag for each member
indicate when it must be parsed again. We change this to wrap these members into an
Optional<T> container instead, where a null value indicates that the member is dirty.

No new tests, behavior is unchanged.

  • mathml/MathMLElement.cpp:

(WebCore::MathMLElement::cachedMathMLLength):
(WebCore::MathMLElement::cachedBooleanAttribute):
(WebCore::MathMLElement::parseMathVariantAttribute):
(WebCore::MathMLElement::specifiedDisplayStyle):
(WebCore::MathMLElement::specifiedMathVariant):

  • mathml/MathMLElement.h:
  • mathml/MathMLFractionElement.cpp:

(WebCore::MathMLFractionElement::lineThickness):
(WebCore::MathMLFractionElement::cachedFractionAlignment):
(WebCore::MathMLFractionElement::parseAttribute):

  • mathml/MathMLFractionElement.h:
  • mathml/MathMLInlineContainerElement.cpp:

(WebCore::MathMLInlineContainerElement::parseAttribute):

  • mathml/MathMLMathElement.cpp:

(WebCore::MathMLMathElement::specifiedDisplayStyle):
(WebCore::MathMLMathElement::parseAttribute):

  • mathml/MathMLOperatorElement.cpp:

(WebCore::MathMLOperatorElement::operatorText):

  • mathml/MathMLPaddedElement.cpp:

(WebCore::MathMLPaddedElement::parseAttribute):

  • mathml/MathMLPaddedElement.h:
  • mathml/MathMLScriptsElement.cpp:

(WebCore::MathMLScriptsElement::parseAttribute):

  • mathml/MathMLScriptsElement.h:
  • mathml/MathMLSpaceElement.cpp:

(WebCore::MathMLSpaceElement::parseAttribute):

  • mathml/MathMLSpaceElement.h:
  • mathml/MathMLTextElement.cpp:

(WebCore::MathMLTextElement::parseAttribute):

  • mathml/MathMLUnderOverElement.cpp:

(WebCore::MathMLUnderOverElement::parseAttribute):

  • mathml/MathMLUnderOverElement.h:
  • rendering/mathml/MathMLStyle.cpp:

(WebCore::MathMLStyle::resolveMathMLStyle):

  • rendering/mathml/MathMLStyle.h:
  • rendering/mathml/RenderMathMLToken.cpp:

(WebCore::mathVariant):
(WebCore::RenderMathMLToken::updateMathVariantGlyph):

Location:
trunk/Source/WebCore
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r204020 r204021  
     12016-08-02  Frederic Wang  <fwang.igalia.com>
     2
     3        Use Optional members to store parsed MathML attributes.
     4        https://bugs.webkit.org/show_bug.cgi?id=160400
     5
     6        Reviewed by Darin Adler.
     7
     8        Parsed MathML attributes are stored on the element classes using the memoize pattern to
     9        minimize the number of parsing updates. Currently, a dirty flag for each member
     10        indicate when it must be parsed again. We change this to wrap these members into an
     11        Optional<T> container instead, where a null value indicates that the member is dirty.
     12
     13        No new tests, behavior is unchanged.
     14
     15        * mathml/MathMLElement.cpp:
     16        (WebCore::MathMLElement::cachedMathMLLength):
     17        (WebCore::MathMLElement::cachedBooleanAttribute):
     18        (WebCore::MathMLElement::parseMathVariantAttribute):
     19        (WebCore::MathMLElement::specifiedDisplayStyle):
     20        (WebCore::MathMLElement::specifiedMathVariant):
     21        * mathml/MathMLElement.h:
     22        * mathml/MathMLFractionElement.cpp:
     23        (WebCore::MathMLFractionElement::lineThickness):
     24        (WebCore::MathMLFractionElement::cachedFractionAlignment):
     25        (WebCore::MathMLFractionElement::parseAttribute):
     26        * mathml/MathMLFractionElement.h:
     27        * mathml/MathMLInlineContainerElement.cpp:
     28        (WebCore::MathMLInlineContainerElement::parseAttribute):
     29        * mathml/MathMLMathElement.cpp:
     30        (WebCore::MathMLMathElement::specifiedDisplayStyle):
     31        (WebCore::MathMLMathElement::parseAttribute):
     32        * mathml/MathMLOperatorElement.cpp:
     33        (WebCore::MathMLOperatorElement::operatorText):
     34        * mathml/MathMLPaddedElement.cpp:
     35        (WebCore::MathMLPaddedElement::parseAttribute):
     36        * mathml/MathMLPaddedElement.h:
     37        * mathml/MathMLScriptsElement.cpp:
     38        (WebCore::MathMLScriptsElement::parseAttribute):
     39        * mathml/MathMLScriptsElement.h:
     40        * mathml/MathMLSpaceElement.cpp:
     41        (WebCore::MathMLSpaceElement::parseAttribute):
     42        * mathml/MathMLSpaceElement.h:
     43        * mathml/MathMLTextElement.cpp:
     44        (WebCore::MathMLTextElement::parseAttribute):
     45        * mathml/MathMLUnderOverElement.cpp:
     46        (WebCore::MathMLUnderOverElement::parseAttribute):
     47        * mathml/MathMLUnderOverElement.h:
     48        * rendering/mathml/MathMLStyle.cpp:
     49        (WebCore::MathMLStyle::resolveMathMLStyle):
     50        * rendering/mathml/MathMLStyle.h:
     51        * rendering/mathml/RenderMathMLToken.cpp:
     52        (WebCore::mathVariant):
     53        (WebCore::RenderMathMLToken::updateMathVariantGlyph):
     54
    1552016-08-02  Youenn Fablet  <youenn@apple.com>
    256
  • trunk/Source/WebCore/mathml/MathMLElement.cpp

    r203679 r204021  
    518518}
    519519
    520 const MathMLElement::Length& MathMLElement::cachedMathMLLength(const QualifiedName& name, Length& length)
    521 {
    522     if (length.dirty) {
    523         length = parseMathMLLength(attributeWithoutSynchronization(name));
    524         length.dirty = false;
    525     }
    526     return length;
    527 }
    528 
    529 const MathMLElement::BooleanValue& MathMLElement::cachedBooleanAttribute(const QualifiedName& name, BooleanAttribute& attribute)
    530 {
    531     if (!attribute.dirty)
    532         return attribute.value;
     520const MathMLElement::Length& MathMLElement::cachedMathMLLength(const QualifiedName& name, Optional<Length>& length)
     521{
     522    if (length)
     523        return length.value();
     524    length = parseMathMLLength(attributeWithoutSynchronization(name));
     525    return length.value();
     526}
     527
     528const MathMLElement::BooleanValue& MathMLElement::cachedBooleanAttribute(const QualifiedName& name, Optional<BooleanValue>& attribute)
     529{
     530    if (attribute)
     531        return attribute.value();
    533532
    534533    // In MathML, attribute values are case-sensitive.
    535534    const AtomicString& value = attributeWithoutSynchronization(name);
    536535    if (value == "true")
    537         attribute.value = BooleanValue::True;
     536        attribute = BooleanValue::True;
    538537    else if (value == "false")
    539         attribute.value = BooleanValue::False;
     538        attribute = BooleanValue::False;
    540539    else
    541         attribute.value = BooleanValue::Default;
    542     attribute.dirty = false;
    543 
    544     return attribute.value;
     540        attribute = BooleanValue::Default;
     541
     542    return attribute.value();
    545543}
    546544
     
    590588{
    591589    if (!acceptsDisplayStyleAttribute())
    592         return Optional<bool>();
     590        return Nullopt;
    593591    const MathMLElement::BooleanValue& specifiedDisplayStyle = cachedBooleanAttribute(displaystyleAttr, m_displayStyle);
    594     return specifiedDisplayStyle == BooleanValue::Default ? Optional<bool>() : Optional<bool>(specifiedDisplayStyle == BooleanValue::True);
     592    return toOptionalBool(specifiedDisplayStyle);
    595593}
    596594
     
    598596{
    599597    if (!acceptsMathVariantAttribute())
    600         return Optional<MathVariant>();
    601     if (m_mathVariant.dirty) {
    602         m_mathVariant.value = parseMathVariantAttribute(attributeWithoutSynchronization(mathvariantAttr));
    603         m_mathVariant.dirty = false;
    604     }
    605     return m_mathVariant.value == MathVariant::None ? Optional<MathVariant>() : Optional<MathVariant>(m_mathVariant.value);
     598        return Nullopt;
     599    if (!m_mathVariant)
     600        m_mathVariant = parseMathVariantAttribute(attributeWithoutSynchronization(mathvariantAttr));
     601    return m_mathVariant.value() == MathVariant::None ? Nullopt : m_mathVariant;
    606602}
    607603
  • trunk/Source/WebCore/mathml/MathMLElement.h

    r203679 r204021  
    6464        LengthType type { LengthType::ParsingFailed };
    6565        float value { 0 };
    66         bool dirty { true };
    6766    };
    6867    static Length parseMathMLLength(const String&);
    6968
    7069    enum class BooleanValue { True, False, Default };
    71     struct BooleanAttribute {
    72         BooleanValue value { BooleanValue::Default };
    73         bool dirty { true };
    74     };
    7570
    7671    // These are the mathvariant values from the MathML recommendation.
     
    9893        Stretched = 18
    9994    };
    100     struct MathVariantAttribute {
    101         MathVariant value { MathVariant::None };
    102         bool dirty { true };
    103     };
    10495
    10596    virtual Optional<bool> specifiedDisplayStyle();
    106     Optional<MathMLElement::MathVariant> specifiedMathVariant();
     97    Optional<MathVariant> specifiedMathVariant();
    10798
    10899protected:
     
    122113    void defaultEventHandler(Event*) override;
    123114
    124     const Length& cachedMathMLLength(const QualifiedName&, Length&);
    125     const BooleanValue& cachedBooleanAttribute(const QualifiedName&, BooleanAttribute&);
     115    const Length& cachedMathMLLength(const QualifiedName&, Optional<Length>&);
     116    const BooleanValue& cachedBooleanAttribute(const QualifiedName&, Optional<BooleanValue>&);
    126117
    127118    virtual bool acceptsDisplayStyleAttribute() { return false; }
    128119    virtual bool acceptsMathVariantAttribute() { return false; }
    129120
    130     BooleanAttribute m_displayStyle;
    131     MathVariantAttribute m_mathVariant;
     121    static Optional<bool> toOptionalBool(const BooleanValue& value) { return value == BooleanValue::Default ? Nullopt : Optional<bool>(value == BooleanValue::True); }
     122    Optional<BooleanValue> m_displayStyle;
     123    Optional<MathVariant> m_mathVariant;
    132124
    133125private:
  • trunk/Source/WebCore/mathml/MathMLFractionElement.cpp

    r203324 r204021  
    4848const MathMLElement::Length& MathMLFractionElement::lineThickness()
    4949{
    50     if (!m_lineThickness.dirty)
    51         return m_lineThickness;
     50    if (m_lineThickness)
     51        return m_lineThickness.value();
    5252
    5353    // The MathML3 recommendation states that "medium" is the default thickness.
    5454    // However, it only states that "thin" and "thick" are respectively thiner and thicker.
    5555    // The MathML in HTML5 implementation note suggests 50% and 200% and these values are also used in Gecko.
    56     String thickness = attributeWithoutSynchronization(linethicknessAttr);
     56    auto& thickness = attributeWithoutSynchronization(linethicknessAttr);
     57    m_lineThickness = Length();
    5758    if (equalLettersIgnoringASCIICase(thickness, "thin")) {
    58         m_lineThickness.type = LengthType::UnitLess;
    59         m_lineThickness.value = .5;
     59        m_lineThickness.value().type = LengthType::UnitLess;
     60        m_lineThickness.value().value = .5;
    6061    } else if (equalLettersIgnoringASCIICase(thickness, "medium")) {
    61         m_lineThickness.type = LengthType::UnitLess;
    62         m_lineThickness.value = 1;
     62        m_lineThickness.value().type = LengthType::UnitLess;
     63        m_lineThickness.value().value = 1;
    6364    } else if (equalLettersIgnoringASCIICase(thickness, "thick")) {
    64         m_lineThickness.type = LengthType::UnitLess;
    65         m_lineThickness.value = 2;
     65        m_lineThickness.value().type = LengthType::UnitLess;
     66        m_lineThickness.value().value = 2;
    6667    } else
    6768        m_lineThickness = parseMathMLLength(thickness);
    68     m_lineThickness.dirty = false;
    69     return m_lineThickness;
     69    return m_lineThickness.value();
    7070}
    7171
    72 MathMLFractionElement::FractionAlignment MathMLFractionElement::cachedFractionAlignment(const QualifiedName& name, FractionAlignmentAttribute& alignment)
     72MathMLFractionElement::FractionAlignment MathMLFractionElement::cachedFractionAlignment(const QualifiedName& name, Optional<FractionAlignment>& alignment)
    7373{
    74     if (!alignment.dirty)
    75         return alignment.value;
     74    if (alignment)
     75        return alignment.value();
    7676
    77     String value = attributeWithoutSynchronization(name);
     77    auto& value = attributeWithoutSynchronization(name);
    7878    if (equalLettersIgnoringASCIICase(value, "left"))
    79         alignment.value = FractionAlignmentLeft;
     79        alignment = FractionAlignmentLeft;
    8080    else if (equalLettersIgnoringASCIICase(value, "right"))
    81         alignment.value = FractionAlignmentRight;
     81        alignment = FractionAlignmentRight;
    8282    else
    83         alignment.value = FractionAlignmentCenter;
    84     alignment.dirty = false;
    85     return alignment.value;
     83        alignment = FractionAlignmentCenter;
     84    return alignment.value();
    8685}
    8786
     
    9998{
    10099    if (name == linethicknessAttr)
    101         m_lineThickness.dirty = true;
     100        m_lineThickness = Nullopt;
    102101    else if (name == numalignAttr)
    103         m_numeratorAlignment.dirty = true;
     102        m_numeratorAlignment = Nullopt;
    104103    else if (name == denomalignAttr)
    105         m_denominatorAlignment.dirty = true;
     104        m_denominatorAlignment = Nullopt;
    106105
    107106    MathMLElement::parseAttribute(name, value);
  • trunk/Source/WebCore/mathml/MathMLFractionElement.h

    r203285 r204021  
    4848    void parseAttribute(const QualifiedName&, const AtomicString&) final;
    4949
    50     struct FractionAlignmentAttribute {
    51         FractionAlignment value { FractionAlignmentCenter };
    52         bool dirty { true };
    53     };
    54     FractionAlignment cachedFractionAlignment(const QualifiedName&, FractionAlignmentAttribute&);
     50    FractionAlignment cachedFractionAlignment(const QualifiedName&, Optional<FractionAlignment>&);
    5551
    56     Length m_lineThickness;
    57     FractionAlignmentAttribute m_numeratorAlignment;
    58     FractionAlignmentAttribute m_denominatorAlignment;
     52    Optional<Length> m_lineThickness;
     53    Optional<FractionAlignment> m_numeratorAlignment;
     54    Optional<FractionAlignment> m_denominatorAlignment;
    5955};
    6056
  • trunk/Source/WebCore/mathml/MathMLInlineContainerElement.cpp

    r203679 r204021  
    9191    bool mathVariantAttribute = name == mathvariantAttr && acceptsMathVariantAttribute();
    9292    if (displayStyleAttribute)
    93         m_displayStyle.dirty = true;
     93        m_displayStyle = Nullopt;
    9494    if (mathVariantAttribute)
    95         m_mathVariant.dirty = true;
     95        m_mathVariant = Nullopt;
    9696    if ((displayStyleAttribute || mathVariantAttribute) && renderer())
    9797        MathMLStyle::resolveMathMLStyleTree(renderer());
  • trunk/Source/WebCore/mathml/MathMLMathElement.cpp

    r203679 r204021  
    5959    if (cachedBooleanAttribute(displaystyleAttr, m_displayStyle) == BooleanValue::Default) {
    6060        // The default displaystyle value of the <math> depends on the display attribute, so we parse it here.
    61         const AtomicString& value = attributeWithoutSynchronization(displayAttr);
     61        auto& value = attributeWithoutSynchronization(displayAttr);
    6262        if (value == "block")
    63             m_displayStyle.value = BooleanValue::True;
     63            m_displayStyle = BooleanValue::True;
    6464        else if (value == "inline")
    65             m_displayStyle.value = BooleanValue::False;
     65            m_displayStyle = BooleanValue::False;
    6666    }
    67     return m_displayStyle.value == BooleanValue::Default ? Optional<bool>() : Optional<bool>(m_displayStyle.value == BooleanValue::True);
     67    return toOptionalBool(m_displayStyle.value());
    6868}
    6969
     
    7373    bool mathVariantAttribute = name == mathvariantAttr;
    7474    if (displayStyleAttribute)
    75         m_displayStyle.dirty = true;
     75        m_displayStyle = Nullopt;
    7676    if (mathVariantAttribute)
    77         m_mathVariant.dirty = true;
     77        m_mathVariant = Nullopt;
    7878    if ((displayStyleAttribute || mathVariantAttribute) && renderer())
    7979        MathMLStyle::resolveMathMLStyleTree(renderer());
  • trunk/Source/WebCore/mathml/MathMLOperatorElement.cpp

    r203896 r204021  
    6464        return m_operatorText.value();
    6565
    66     m_operatorText = Optional<UChar>(parseOperatorText(textContent()));
     66    m_operatorText = parseOperatorText(textContent());
    6767    return m_operatorText.value();
    6868}
     
    7070void MathMLOperatorElement::childrenChanged(const ChildChange& change)
    7171{
    72     m_operatorText = Optional<UChar>();
     72    m_operatorText = Nullopt;
    7373    MathMLTextElement::childrenChanged(change);
    7474}
  • trunk/Source/WebCore/mathml/MathMLPaddedElement.cpp

    r203150 r204021  
    7474{
    7575    if (name == widthAttr)
    76         m_width.dirty = true;
     76        m_width = Nullopt;
    7777    else if (name == heightAttr)
    78         m_height.dirty = true;
     78        m_height = Nullopt;
    7979    else if (name == depthAttr)
    80         m_depth.dirty = true;
     80        m_depth = Nullopt;
    8181    else if (name == lspaceAttr)
    82         m_lspace.dirty = true;
     82        m_lspace = Nullopt;
    8383    else if (name == voffsetAttr)
    84         m_voffset.dirty = true;
     84        m_voffset = Nullopt;
    8585
    8686    MathMLElement::parseAttribute(name, value);
  • trunk/Source/WebCore/mathml/MathMLPaddedElement.h

    r203228 r204021  
    4545    void parseAttribute(const QualifiedName&, const AtomicString&) final;
    4646
    47     Length m_width;
    48     Length m_height;
    49     Length m_depth;
    50     Length m_lspace;
    51     Length m_voffset;
     47    Optional<Length> m_width;
     48    Optional<Length> m_height;
     49    Optional<Length> m_depth;
     50    Optional<Length> m_lspace;
     51    Optional<Length> m_voffset;
    5252};
    5353
  • trunk/Source/WebCore/mathml/MathMLScriptsElement.cpp

    r203553 r204021  
    5959{
    6060    if (name == subscriptshiftAttr)
    61         m_subscriptShift.dirty = true;
     61        m_subscriptShift = Nullopt;
    6262    else if (name == superscriptshiftAttr)
    63         m_superscriptShift.dirty = true;
     63        m_superscriptShift = Nullopt;
    6464
    6565    MathMLElement::parseAttribute(name, value);
  • trunk/Source/WebCore/mathml/MathMLScriptsElement.h

    r203553 r204021  
    4444    void parseAttribute(const QualifiedName&, const AtomicString&) override;
    4545
    46     Length m_subscriptShift;
    47     Length m_superscriptShift;
     46    Optional<Length> m_subscriptShift;
     47    Optional<Length> m_superscriptShift;
    4848};
    4949
  • trunk/Source/WebCore/mathml/MathMLSpaceElement.cpp

    r203108 r204021  
    6464{
    6565    if (name == widthAttr)
    66         m_width.dirty = true;
     66        m_width = Nullopt;
    6767    else if (name == heightAttr)
    68         m_height.dirty = true;
     68        m_height = Nullopt;
    6969    else if (name == depthAttr)
    70         m_depth.dirty = true;
     70        m_depth = Nullopt;
    7171
    7272    MathMLElement::parseAttribute(name, value);
  • trunk/Source/WebCore/mathml/MathMLSpaceElement.h

    r203228 r204021  
    4343    void parseAttribute(const QualifiedName&, const AtomicString&) final;
    4444
    45     Length m_width;
    46     Length m_height;
    47     Length m_depth;
     45    Optional<Length> m_width;
     46    Optional<Length> m_height;
     47    Optional<Length> m_depth;
    4848};
    4949
  • trunk/Source/WebCore/mathml/MathMLTextElement.cpp

    r203688 r204021  
    6666{
    6767    if (name == mathvariantAttr) {
    68         m_mathVariant.dirty = true;
     68        m_mathVariant = Nullopt;
    6969        if (renderer())
    7070            MathMLStyle::resolveMathMLStyleTree(renderer());
  • trunk/Source/WebCore/mathml/MathMLUnderOverElement.cpp

    r203553 r204021  
    5959{
    6060    if (name == accentAttr)
    61         m_accent.dirty = true;
     61        m_accent = Nullopt;
    6262    else if (name == accentunderAttr)
    63         m_accentUnder.dirty = true;
     63        m_accentUnder = Nullopt;
    6464
    6565    MathMLElement::parseAttribute(name, value);
  • trunk/Source/WebCore/mathml/MathMLUnderOverElement.h

    r203553 r204021  
    4242    void parseAttribute(const QualifiedName&, const AtomicString&) final;
    4343
    44     BooleanAttribute m_accent;
    45     BooleanAttribute m_accentUnder;
     44    Optional<BooleanValue> m_accent;
     45    Optional<BooleanValue> m_accentUnder;
    4646};
    4747
Note: See TracChangeset for help on using the changeset viewer.