tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

HTMLMarkupMap.h (15153B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:expandtab:shiftwidth=2:tabstop=2:
      3 */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 MARKUPMAP(
      9    a,
     10    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
     11      // An anchor element without an href attribute and without a click
     12      // listener should be a generic.
     13      if (!aElement->HasAttr(nsGkAtoms::href) &&
     14          !nsCoreUtils::HasClickListener(aElement)) {
     15        return new HyperTextAccessible(aElement, aContext->Document());
     16      }
     17      // Only some roles truly enjoy life as HTMLLinkAccessibles, for
     18      // details see closed bug 494807.
     19      const nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aElement);
     20      if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
     21          roleMapEntry->role != roles::LINK) {
     22        return new HyperTextAccessible(aElement, aContext->Document());
     23      }
     24 
     25      return new HTMLLinkAccessible(aElement, aContext->Document());
     26    },
     27    0)
     28 
     29 MARKUPMAP(
     30    abbr,
     31    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
     32      return new HTMLAbbreviationAccessible(aElement, aContext->Document());
     33    },
     34    0)
     35 
     36 MARKUPMAP(
     37    acronym,
     38    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
     39      return new HTMLAbbreviationAccessible(aElement, aContext->Document());
     40    },
     41    0)
     42 
     43 MARKUPMAP(address, New_HyperText, roles::GROUPING)
     44 
     45 MARKUPMAP(article, New_HyperText, roles::ARTICLE, Attr(xmlroles, article))
     46 
     47 MARKUPMAP(
     48    aside,
     49    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
     50      return new HTMLAsideAccessible(aElement, aContext->Document());
     51    },
     52    0)
     53 
     54 MARKUPMAP(blockquote, New_HyperText, roles::BLOCKQUOTE)
     55 
     56 MARKUPMAP(
     57    button,
     58    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
     59      return new HTMLButtonAccessible(aElement, aContext->Document());
     60    },
     61    0)
     62 
     63 MARKUPMAP(
     64    caption,
     65    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
     66      if (aContext->IsTable()) {
     67        dom::HTMLTableElement* tableEl =
     68            dom::HTMLTableElement::FromNode(aContext->GetContent());
     69        if (tableEl && tableEl == aElement->GetParent() &&
     70            tableEl->GetCaption() == aElement) {
     71          return new HTMLCaptionAccessible(aElement, aContext->Document());
     72        }
     73      }
     74      return nullptr;
     75    },
     76    0)
     77 
     78 MARKUPMAP(code, New_HyperText, roles::CODE)
     79 
     80 MARKUPMAP(dd, New_HTMLDtOrDd<HyperTextAccessible>, roles::DEFINITION)
     81 
     82 MARKUPMAP(del, New_HyperText, roles::CONTENT_DELETION)
     83 
     84 MARKUPMAP(details, New_HyperText, roles::DETAILS)
     85 
     86 MARKUPMAP(dfn, New_HyperText, roles::TERM)
     87 
     88 MARKUPMAP(dialog, New_HyperText, roles::DIALOG)
     89 
     90 MARKUPMAP(
     91    div,
     92    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
     93      // Never create an accessible if we're part of an anonymous
     94      // subtree.
     95      if (aElement->IsInNativeAnonymousSubtree()) {
     96        return nullptr;
     97      }
     98      // Always create an accessible if the div has an id.
     99      if (aElement->HasAttr(nsGkAtoms::id)) {
    100        return new HyperTextAccessible(aElement, aContext->Document());
    101      }
    102      // Never create an accessible if the div is not display:block; or
    103      // display:inline-block or the like.
    104      nsIFrame* f = aElement->GetPrimaryFrame();
    105      if (!f || !f->IsBlockFrameOrSubclass()) {
    106        return nullptr;
    107      }
    108      // Check for various conditions to determine if this is a block
    109      // break and needs to be rendered.
    110      // If its previous sibling is an inline element, we probably want
    111      // to break, so render.
    112      // FIXME: This looks extremely incorrect in presence of shadow DOM,
    113      // display: contents, and what not.
    114      nsIContent* prevSibling = aElement->GetPreviousSibling();
    115      if (prevSibling) {
    116        nsIFrame* prevSiblingFrame = prevSibling->GetPrimaryFrame();
    117        if (prevSiblingFrame && prevSiblingFrame->IsInlineOutside()) {
    118          return new HyperTextAccessible(aElement, aContext->Document());
    119        }
    120      }
    121      // Now, check the children.
    122      nsIContent* firstChild = aElement->GetFirstChild();
    123      if (firstChild) {
    124        nsIFrame* firstChildFrame = firstChild->GetPrimaryFrame();
    125        if (!firstChildFrame) {
    126          // The first child is invisible, but this might be due to an
    127          // invisible text node. Try the next.
    128          firstChild = firstChild->GetNextSibling();
    129          if (!firstChild) {
    130            // If there's no next sibling, there's only one child, so there's
    131            // nothing more we can do.
    132            return nullptr;
    133          }
    134          firstChildFrame = firstChild->GetPrimaryFrame();
    135        }
    136        // Check to see if first child has an inline frame.
    137        if (firstChildFrame && firstChildFrame->IsInlineOutside()) {
    138          return new HyperTextAccessible(aElement, aContext->Document());
    139        }
    140        nsIContent* lastChild = aElement->GetLastChild();
    141        MOZ_ASSERT(lastChild);
    142        if (lastChild != firstChild) {
    143          nsIFrame* lastChildFrame = lastChild->GetPrimaryFrame();
    144          if (!lastChildFrame) {
    145            // The last child is invisible, but this might be due to an
    146            // invisible text node. Try the next.
    147            lastChild = lastChild->GetPreviousSibling();
    148            MOZ_ASSERT(lastChild);
    149            if (lastChild == firstChild) {
    150              return nullptr;
    151            }
    152            lastChildFrame = lastChild->GetPrimaryFrame();
    153          }
    154          // Check to see if last child has an inline frame.
    155          if (lastChildFrame && lastChildFrame->IsInlineOutside()) {
    156            return new HyperTextAccessible(aElement, aContext->Document());
    157          }
    158        }
    159      }
    160      return nullptr;
    161    },
    162    roles::SECTION)
    163 
    164 MARKUPMAP(
    165    dl,
    166    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    167      return new HTMLListAccessible(aElement, aContext->Document());
    168    },
    169    roles::DEFINITION_LIST)
    170 
    171 MARKUPMAP(dt, New_HTMLDtOrDd<HTMLLIAccessible>, roles::TERM)
    172 
    173 MARKUPMAP(em, New_HyperText, roles::EMPHASIS)
    174 
    175 MARKUPMAP(
    176    figcaption,
    177    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    178      return new HTMLFigcaptionAccessible(aElement, aContext->Document());
    179    },
    180    roles::CAPTION)
    181 
    182 MARKUPMAP(
    183    figure,
    184    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    185      return new HTMLFigureAccessible(aElement, aContext->Document());
    186    },
    187    roles::FIGURE, Attr(xmlroles, figure))
    188 
    189 MARKUPMAP(
    190    fieldset,
    191    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    192      return new HTMLGroupboxAccessible(aElement, aContext->Document());
    193    },
    194    0)
    195 
    196 MARKUPMAP(
    197    form,
    198    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    199      return new HTMLFormAccessible(aElement, aContext->Document());
    200    },
    201    0)
    202 
    203 MARKUPMAP(
    204    footer,
    205    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    206      return new HTMLHeaderOrFooterAccessible(aElement, aContext->Document());
    207    },
    208    0)
    209 
    210 MARKUPMAP(
    211    header,
    212    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    213      return new HTMLHeaderOrFooterAccessible(aElement, aContext->Document());
    214    },
    215    0)
    216 
    217 MARKUPMAP(h1, New_HyperText, roles::HEADING)
    218 
    219 MARKUPMAP(h2, New_HyperText, roles::HEADING)
    220 
    221 MARKUPMAP(h3, New_HyperText, roles::HEADING)
    222 
    223 MARKUPMAP(h4, New_HyperText, roles::HEADING)
    224 
    225 MARKUPMAP(h5, New_HyperText, roles::HEADING)
    226 
    227 MARKUPMAP(h6, New_HyperText, roles::HEADING)
    228 
    229 MARKUPMAP(hgroup, New_HyperText, roles::GROUPING)
    230 
    231 MARKUPMAP(
    232    hr,
    233    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    234      return new HTMLHRAccessible(aElement, aContext->Document());
    235    },
    236    0)
    237 
    238 MARKUPMAP(
    239    input,
    240    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    241      // TODO(emilio): This would be faster if it used
    242      // HTMLInputElement's already-parsed representation.
    243      if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
    244                                nsGkAtoms::checkbox, eIgnoreCase)) {
    245        return new CheckboxAccessible(aElement, aContext->Document());
    246      }
    247      if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
    248                                nsGkAtoms::image, eIgnoreCase)) {
    249        return new HTMLButtonAccessible(aElement, aContext->Document());
    250      }
    251      if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
    252                                nsGkAtoms::radio, eIgnoreCase)) {
    253        return new HTMLRadioButtonAccessible(aElement, aContext->Document());
    254      }
    255      if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
    256                                nsGkAtoms::time, eIgnoreCase)) {
    257        return new HTMLDateTimeAccessible<roles::TIME_EDITOR>(
    258            aElement, aContext->Document());
    259      }
    260      if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
    261                                nsGkAtoms::date, eIgnoreCase) ||
    262          aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
    263                                nsGkAtoms::datetime_local, eIgnoreCase)) {
    264        return new HTMLDateTimeAccessible<roles::DATE_EDITOR>(
    265            aElement, aContext->Document());
    266      }
    267      return nullptr;
    268    },
    269    0)
    270 
    271 MARKUPMAP(ins, New_HyperText, roles::CONTENT_INSERTION)
    272 
    273 MARKUPMAP(
    274    label,
    275    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    276      return new HTMLLabelAccessible(aElement, aContext->Document());
    277    },
    278    roles::LABEL)
    279 
    280 MARKUPMAP(
    281    legend,
    282    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    283      return new HTMLLegendAccessible(aElement, aContext->Document());
    284    },
    285    roles::LABEL)
    286 
    287 MARKUPMAP(
    288    li,
    289    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    290      // If list item is a child of accessible list then create an
    291      // accessible for it unconditionally by tag name. nsBlockFrame
    292      // creates the list item accessible for other elements styled as
    293      // list items.
    294      if (aContext->IsList() &&
    295          aContext->GetContent() == aElement->GetParent()) {
    296        return new HTMLLIAccessible(aElement, aContext->Document());
    297      }
    298 
    299      return nullptr;
    300    },
    301    0)
    302 
    303 MARKUPMAP(main, New_HyperText, roles::LANDMARK)
    304 
    305 MARKUPMAP(map, nullptr, roles::TEXT_CONTAINER)
    306 
    307 MARKUPMAP(mark, New_HyperText, roles::MARK, Attr(xmlroles, mark))
    308 
    309 MARKUPMAP(
    310    menu,
    311    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    312      return new HTMLListAccessible(aElement, aContext->Document());
    313    },
    314    roles::LIST)
    315 
    316 MARKUPMAP(nav, New_HyperText, roles::LANDMARK)
    317 
    318 MARKUPMAP(
    319    ol,
    320    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    321      return new HTMLListAccessible(aElement, aContext->Document());
    322    },
    323    roles::LIST)
    324 
    325 MARKUPMAP(
    326    option,
    327    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    328      return new HTMLSelectOptionAccessible(aElement, aContext->Document());
    329    },
    330    0)
    331 
    332 MARKUPMAP(
    333    optgroup,
    334    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    335      return new HTMLSelectOptGroupAccessible(aElement, aContext->Document());
    336    },
    337    0)
    338 
    339 MARKUPMAP(
    340    output,
    341    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    342      return new HTMLOutputAccessible(aElement, aContext->Document());
    343    },
    344    roles::STATUSBAR, Attr(aria_live, polite))
    345 
    346 MARKUPMAP(p, nullptr, roles::PARAGRAPH)
    347 
    348 MARKUPMAP(
    349    progress,
    350    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    351      return new HTMLProgressAccessible(aElement, aContext->Document());
    352    },
    353    0)
    354 
    355 MARKUPMAP(q, New_HyperText, 0)
    356 
    357 MARKUPMAP(s, New_HyperText, roles::CONTENT_DELETION)
    358 
    359 MARKUPMAP(
    360    section,
    361    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    362      return new HTMLSectionAccessible(aElement, aContext->Document());
    363    },
    364    0)
    365 
    366 MARKUPMAP(strong, New_HyperText, roles::STRONG)
    367 
    368 MARKUPMAP(sub, New_HyperText, roles::SUBSCRIPT)
    369 
    370 MARKUPMAP(
    371    summary,
    372    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    373      return new HTMLSummaryAccessible(aElement, aContext->Document());
    374    },
    375    roles::SUMMARY)
    376 
    377 MARKUPMAP(sup, New_HyperText, roles::SUPERSCRIPT)
    378 
    379 MARKUPMAP(
    380    table,
    381    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    382      return new HTMLTableAccessible(aElement, aContext->Document());
    383    },
    384    roles::TABLE)
    385 
    386 MARKUPMAP(time, New_HyperText, roles::TIME, Attr(xmlroles, time),
    387          AttrFromDOM(datetime, datetime))
    388 
    389 MARKUPMAP(tbody, nullptr, roles::ROWGROUP)
    390 
    391 MARKUPMAP(
    392    td,
    393    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    394      if (!aContext->IsHTMLTableRow()) {
    395        return nullptr;
    396      }
    397      if (aElement->HasAttr(nsGkAtoms::scope)) {
    398        return new HTMLTableHeaderCellAccessible(aElement,
    399                                                 aContext->Document());
    400      }
    401      return new HTMLTableCellAccessible(aElement, aContext->Document());
    402    },
    403    0)
    404 
    405 MARKUPMAP(tfoot, nullptr, roles::ROWGROUP)
    406 
    407 MARKUPMAP(
    408    th,
    409    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    410      if (!aContext->IsHTMLTableRow()) {
    411        return nullptr;
    412      }
    413      return new HTMLTableHeaderCellAccessible(aElement, aContext->Document());
    414    },
    415    0)
    416 
    417 MARKUPMAP(thead, nullptr, roles::ROWGROUP)
    418 
    419 MARKUPMAP(
    420    tr,
    421    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    422      if (aContext->IsTableRow()) {
    423        // A <tr> within a row isn't valid.
    424        return nullptr;
    425      }
    426      const nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aElement);
    427      if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
    428          roleMapEntry->role != roles::ROW) {
    429        // There is a valid ARIA role which isn't "row". Don't treat this as an
    430        // HTML table row.
    431        return nullptr;
    432      }
    433      // Check if this <tr> is within a table. We check the grandparent because
    434      // it might be inside a rowgroup. We don't specifically check for an HTML
    435      // table because there are cases where there is a <tr> inside a
    436      // <div role="table"> such as Monorail.
    437      if (aContext->IsTable() ||
    438          (aContext->LocalParent() && aContext->LocalParent()->IsTable())) {
    439        return new HTMLTableRowAccessible(aElement, aContext->Document());
    440      }
    441      return nullptr;
    442    },
    443    roles::ROW)
    444 
    445 MARKUPMAP(
    446    ul,
    447    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    448      return new HTMLListAccessible(aElement, aContext->Document());
    449    },
    450    roles::LIST)
    451 
    452 MARKUPMAP(
    453    meter,
    454    [](Element* aElement, LocalAccessible* aContext) -> LocalAccessible* {
    455      return new HTMLMeterAccessible(aElement, aContext->Document());
    456    },
    457    roles::METER)
    458 
    459 MARKUPMAP(search, New_HyperText, roles::LANDMARK)