void TextFieldInputType::listAttributeTargetChanged()
{
    if (ChromeClient* chromeClient = this->chromeClient())
        chromeClient->textFieldDataListChanged(element());
    Element* picker = element().userAgentShadowRoot()->getElementById(ShadowElementNames::pickerIndicator());
    bool didHavePickerIndicator = picker;
    bool willHavePickerIndicator = element().hasValidDataListOptions();
    if (didHavePickerIndicator == willHavePickerIndicator)
        return;
    EventDispatchForbiddenScope::AllowUserAgentEvents allowEvents;
    if (willHavePickerIndicator) {
        Document& document = element().document();
        if (Element* container = containerElement()) {
            container->insertBefore(DataListIndicatorElement::create(document), spinButtonElement());
        } else {
            // FIXME: The following code is similar to createShadowSubtree(),
            // but they are different. We should simplify the code by making
            // containerElement mandatory.
            RefPtrWillBeRawPtr<Element> rpContainer = TextControlInnerContainer::create(document);
            rpContainer->setShadowPseudoId(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
            RefPtrWillBeRawPtr<Element> innerEditor = element().innerEditorElement();
            innerEditor->parentNode()->replaceChild(rpContainer.get(), innerEditor.get());
            RefPtrWillBeRawPtr<Element> editingViewPort = EditingViewPortElement::create(document);
            editingViewPort->appendChild(innerEditor.release());
            rpContainer->appendChild(editingViewPort.release());
            rpContainer->appendChild(DataListIndicatorElement::create(document));
            if (element().document().focusedElement() == element())
                element().updateFocusAppearance(true /* restore selection */);
        }
    } else {
        picker->remove(ASSERT_NO_EXCEPTION);
    }
}
void TextFieldInputType::createShadowSubtree()
{
    ASSERT(element().shadow());
    ShadowRoot* shadowRoot = element().userAgentShadowRoot();
    ASSERT(!shadowRoot->hasChildren());

    Document& document = element().document();
    bool shouldHaveSpinButton = this->shouldHaveSpinButton();
    bool shouldHaveDataListIndicator = element().hasValidDataListOptions();
    bool createsContainer = shouldHaveSpinButton || shouldHaveDataListIndicator || needsContainer();

    RefPtrWillBeRawPtr<TextControlInnerEditorElement> innerEditor = TextControlInnerEditorElement::create(document);
    if (!createsContainer) {
        shadowRoot->appendChild(innerEditor.release());
        return;
    }

    RefPtrWillBeRawPtr<TextControlInnerContainer> container = TextControlInnerContainer::create(document);
    container->setShadowPseudoId(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
    shadowRoot->appendChild(container);

    RefPtrWillBeRawPtr<EditingViewPortElement> editingViewPort = EditingViewPortElement::create(document);
    editingViewPort->appendChild(innerEditor.release());
    container->appendChild(editingViewPort.release());

    if (shouldHaveDataListIndicator)
        container->appendChild(DataListIndicatorElement::create(document));
    // FIXME: Because of a special handling for a spin button in
    // LayoutTextControlSingleLine, we need to put it to the last position. It's
    // inconsistent with multiple-fields date/time types.
    if (shouldHaveSpinButton)
        container->appendChild(SpinButtonElement::create(document, *this));

    // See listAttributeTargetChanged too.
}
Example #3
0
PassRefPtrWillBeRawPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionState& exceptionState)
{
    RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document());
    unsigned i, length = text.length();
    UChar c = 0;
    for (unsigned start = 0; start < length; ) {

        // Find next line break.
        for (i = start; i < length; i++) {
          c = text[i];
          if (c == '\r' || c == '\n')
              break;
        }

        fragment->appendChild(Text::create(document(), text.substring(start, i - start)), exceptionState);
        if (exceptionState.hadException())
            return nullptr;

        if (c == '\r' || c == '\n') {
            fragment->appendChild(HTMLBRElement::create(document()), exceptionState);
            if (exceptionState.hadException())
                return nullptr;
            // Make sure \r\n doesn't result in two line breaks.
            if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
                i++;
        }

        start = i + 1; // Character after line break.
    }

    return fragment;
}
PassRefPtrWillBeRawPtr<XMLDocument> DOMImplementation::createDocument(const AtomicString& namespaceURI,
    const AtomicString& qualifiedName, DocumentType* doctype, ExceptionState& exceptionState)
{
    RefPtrWillBeRawPtr<XMLDocument> doc = nullptr;
    DocumentInit init = DocumentInit::fromContext(document().contextDocument());
    if (namespaceURI == SVGNames::svgNamespaceURI) {
        doc = XMLDocument::createSVG(init);
    } else if (namespaceURI == HTMLNames::xhtmlNamespaceURI) {
        doc = XMLDocument::createXHTML(init.withRegistrationContext(document().registrationContext()));
    } else {
        doc = XMLDocument::create(init);
    }

    doc->setSecurityOrigin(document().securityOrigin()->isolatedCopy());
    doc->setContextFeatures(document().contextFeatures());

    RefPtrWillBeRawPtr<Node> documentElement = nullptr;
    if (!qualifiedName.isEmpty()) {
        documentElement = doc->createElementNS(namespaceURI, qualifiedName, exceptionState);
        if (exceptionState.hadException())
            return nullptr;
    }

    if (doctype)
        doc->appendChild(doctype);
    if (documentElement)
        doc->appendChild(documentElement.release());

    return doc.release();
}
void HTMLImageFallbackHelper::createAltTextShadowTree(Element& element)
{
    ShadowRoot& root = element.ensureUserAgentShadowRoot();

    RefPtrWillBeRawPtr<HTMLDivElement> container = HTMLDivElement::create(element.document());
    root.appendChild(container);
    container->setAttribute(idAttr, AtomicString("alttext-container", AtomicString::ConstructFromLiteral));
    container->setInlineStyleProperty(CSSPropertyOverflow, CSSValueHidden);
    container->setInlineStyleProperty(CSSPropertyBorderWidth, 1, CSSPrimitiveValue::UnitType::Pixels);
    container->setInlineStyleProperty(CSSPropertyBorderStyle, CSSValueSolid);
    container->setInlineStyleProperty(CSSPropertyBorderColor, CSSValueSilver);
    container->setInlineStyleProperty(CSSPropertyDisplay, CSSValueInlineBlock);
    container->setInlineStyleProperty(CSSPropertyBoxSizing, CSSValueBorderBox);
    container->setInlineStyleProperty(CSSPropertyPadding, 1, CSSPrimitiveValue::UnitType::Pixels);

    RefPtrWillBeRawPtr<HTMLImageElement> brokenImage = HTMLImageElement::create(element.document());
    container->appendChild(brokenImage);
    brokenImage->setIsFallbackImage();
    brokenImage->setAttribute(idAttr, AtomicString("alttext-image", AtomicString::ConstructFromLiteral));
    brokenImage->setAttribute(widthAttr, AtomicString("16", AtomicString::ConstructFromLiteral));
    brokenImage->setAttribute(heightAttr, AtomicString("16", AtomicString::ConstructFromLiteral));
    brokenImage->setAttribute(alignAttr, AtomicString("left", AtomicString::ConstructFromLiteral));
    brokenImage->setInlineStyleProperty(CSSPropertyMargin, 0, CSSPrimitiveValue::UnitType::Pixels);

    RefPtrWillBeRawPtr<HTMLDivElement> altText = HTMLDivElement::create(element.document());
    container->appendChild(altText);
    altText->setAttribute(idAttr, AtomicString("alttext", AtomicString::ConstructFromLiteral));
    altText->setInlineStyleProperty(CSSPropertyOverflow, CSSValueHidden);
    altText->setInlineStyleProperty(CSSPropertyDisplay, CSSValueBlock);

    RefPtrWillBeRawPtr<Text> text = Text::create(element.document(), toHTMLElement(element).altText());
    altText->appendChild(text);
}
TEST(HTMLInputElementTest, DefaultToolTip)
{
    RefPtrWillBeRawPtr<Document> document = Document::create();
    RefPtrWillBeRawPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*document);
    html->appendChild(HTMLBodyElement::create(*document));
    RefPtrWillBeRawPtr<HTMLInputElement> input = HTMLInputElement::create(*document, nullptr, false);
    input->setBooleanAttribute(HTMLNames::requiredAttr, true);
    toHTMLBodyElement(html->firstChild())->appendChild(input.get());
    document->appendChild(html.release());
    EXPECT_EQ("<<ValidationValueMissing>>", input->defaultToolTip());
}
void ImageDocument::createDocumentStructure(bool loadingMultipartContent)
{
    RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*this);
    appendChild(rootElement);
    rootElement->insertedByParser();

    if (frame())
        frame()->loader().dispatchDocumentElementAvailable();
    // Normally, ImageDocument creates an HTMLImageElement that doesn't actually load
    // anything, and the ImageDocument routes the main resource data into the HTMLImageElement's
    // ImageResource. However, the main resource pipeline doesn't know how to handle multipart content.
    // For multipart content, we instead stop streaming data through the main resource and re-request
    // the data directly.
    if (loadingMultipartContent)
        loader()->stopLoading();

    RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
    RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this);
    meta->setAttribute(nameAttr, "viewport");
    meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1");
    head->appendChild(meta);

    RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
    body->setAttribute(styleAttr, "margin: 0px;");

    if (frame())
        frame()->loader().client()->dispatchWillInsertBody();

    m_imageElement = HTMLImageElement::create(*this);
    m_imageElement->setAttribute(styleAttr, "-webkit-user-select: none");
    // If the image is multipart, we neglect to mention to the HTMLImageElement that it's in an
    // ImageDocument, so that it requests the image normally.
    if (!loadingMultipartContent)
        m_imageElement->setLoadingImageDocument();
    m_imageElement->setSrc(url().string());
    body->appendChild(m_imageElement.get());

    if (shouldShrinkToFit()) {
        // Add event listeners
        RefPtrWillBeRawPtr<EventListener> listener = ImageEventListener::create(this);
        if (LocalDOMWindow* domWindow = this->domWindow())
            domWindow->addEventListener("resize", listener, false);
        if (m_shrinkToFitMode == Desktop)
            m_imageElement->addEventListener("click", listener.release(), false);
    }

    rootElement->appendChild(head);
    rootElement->appendChild(body);
    if (loadingMultipartContent)
        finishedParsing();
}
void DateTimeEditBuilder::visitLiteral(const String& text)
{
    DEFINE_STATIC_LOCAL(AtomicString, textPseudoId, ("-webkit-datetime-edit-text", AtomicString::ConstructFromLiteral));
    ASSERT(text.length());
    RefPtrWillBeRawPtr<HTMLDivElement> element = HTMLDivElement::create(m_editElement.document());
    element->setShadowPseudoId(textPseudoId);
    if (m_parameters.locale.isRTL() && text.length()) {
        Direction dir = direction(text[0]);
        if (dir == SegmentSeparator || dir == WhiteSpaceNeutral || dir == OtherNeutral)
            element->appendChild(Text::create(m_editElement.document(), String(&rightToLeftMark, 1)));
    }
    element->appendChild(Text::create(m_editElement.document(), text));
    m_editElement.fieldsWrapperElement()->appendChild(element);
}
void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
    ASSERT(!m_value);

    RefPtrWillBeRawPtr<MeterInnerElement> inner = MeterInnerElement::create(document());
    root.appendChild(inner);

    RefPtrWillBeRawPtr<MeterBarElement> bar = MeterBarElement::create(document());
    m_value = MeterValueElement::create(document());
    m_value->setWidthPercentage(0);
    m_value->updatePseudo();
    bar->appendChild(m_value);

    inner->appendChild(bar);
}
Example #10
0
void RangeTest::SetUp()
{
    m_document = HTMLDocument::create();
    RefPtrWillBeRawPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*m_document);
    html->appendChild(HTMLBodyElement::create(*m_document));
    m_document->appendChild(html.release());
}
Example #11
0
void PluginDocumentParser::createDocumentStructure()
{
    // FIXME: Assert we have a loader to figure out why the original null checks
    // and assert were added for the security bug in http://trac.webkit.org/changeset/87566
    ASSERT(document());
    RELEASE_ASSERT(document()->loader());

    LocalFrame* frame = document()->frame();
    if (!frame)
        return;

    // FIXME: Why does this check settings?
    if (!frame->settings() || !frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
        return;

    RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
    rootElement->insertedByParser();
    document()->appendChild(rootElement);
    frame->loader().dispatchDocumentElementAvailable();

    RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
    body->setAttribute(styleAttr, "background-color: rgb(38,38,38); height: 100%; width: 100%; overflow: hidden; margin: 0");
    rootElement->appendChild(body);

    m_embedElement = HTMLEmbedElement::create(*document());
    m_embedElement->setAttribute(widthAttr, "100%");
    m_embedElement->setAttribute(heightAttr, "100%");
    m_embedElement->setAttribute(nameAttr, "plugin");
    m_embedElement->setAttribute(idAttr, "plugin");
    m_embedElement->setAttribute(srcAttr, AtomicString(document()->url().string()));
    m_embedElement->setAttribute(typeAttr, document()->loader()->mimeType());
    body->appendChild(m_embedElement);

    toPluginDocument(document())->setPluginNode(m_embedElement.get());
    m_embedElement->focus();

    document()->updateLayout();

    // We need the plugin to load synchronously so we can get the PluginView
    // below so flush the layout tasks now instead of waiting on the timer.
    frame->view()->flushAnyPendingPostLayoutTasks();

    if (PluginView* view = pluginView())
        view->didReceiveResponse(document()->loader()->response());
}
void HTMLKeygenElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
    DEFINE_STATIC_LOCAL(AtomicString, keygenSelectPseudoId, ("-webkit-keygen-select", AtomicString::ConstructFromLiteral));

    Vector<String> keys;
    getSupportedKeySizes(locale(), keys);

    // Create a select element with one option element for each key size.
    RefPtrWillBeRawPtr<HTMLSelectElement> select = HTMLSelectElement::create(document());
    select->setShadowPseudoId(keygenSelectPseudoId);
    for (size_t i = 0; i < keys.size(); ++i) {
        RefPtrWillBeRawPtr<HTMLOptionElement> option = HTMLOptionElement::create(document());
        option->appendChild(Text::create(document(), keys[i]));
        select->appendChild(option);
    }

    root.appendChild(select);
}
TEST_F(FrameSelectionTest, SetInvalidSelection)
{
    // Create a new document without frame by using DOMImplementation.
    DocumentInit dummy;
    RefPtrWillBeRawPtr<Document> documentWithoutFrame = Document::create();
    RefPtrWillBeRawPtr<Element> body = documentWithoutFrame->createElement(HTMLNames::bodyTag, false);
    documentWithoutFrame->appendChild(body);
    RefPtrWillBeRawPtr<Text> anotherText = documentWithoutFrame->createTextNode("Hello, another world");
    body->appendChild(anotherText);

    // Create a new VisibleSelection for the new document without frame and
    // update FrameSelection with the selection.
    VisibleSelection invalidSelection;
    invalidSelection.setWithoutValidation(Position(anotherText, 0), Position(anotherText, 5));
    setSelection(invalidSelection);

    EXPECT_TRUE(selection().isNone());
}
    void SetUp()
    {
        m_document = HTMLDocument::create();
        RefPtrWillBeRawPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*m_document);
        html->appendChild(HTMLBodyElement::create(*m_document));
        m_document->appendChild(html.release());

        m_document->body()->setInnerHTML("<b><i></i></b>", ASSERT_NO_EXCEPTION);
    }
void HTMLDetailsElement::didAddClosedShadowRoot(ShadowRoot& root)
{
    DEFINE_STATIC_LOCAL(const AtomicString, summarySelector, ("summary:first-of-type", AtomicString::ConstructFromLiteral));

    RefPtrWillBeRawPtr<HTMLSummaryElement> defaultSummary = HTMLSummaryElement::create(document());
    defaultSummary->appendChild(Text::create(document(), locale().queryString(blink::WebLocalizedString::DetailsLabel)));

    RefPtrWillBeRawPtr<HTMLContentElement> summary = HTMLContentElement::create(document());
    summary->setIdAttribute(ShadowElementNames::detailsSummary());
    summary->setAttribute(selectAttr, summarySelector);
    summary->appendChild(defaultSummary);
    root.appendChild(summary.release());

    RefPtrWillBeRawPtr<HTMLDivElement> content = HTMLDivElement::create(document());
    content->setIdAttribute(ShadowElementNames::detailsContent());
    content->appendChild(HTMLContentElement::create(document()));
    content->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
    root.appendChild(content.release());
}
TEST(HTMLInputElementTest, NoAssertWhenMovedInNewDocument)
{
    const RefPtrWillBeRawPtr<Document> documentWithoutFrame = Document::create();
    EXPECT_EQ(nullptr, documentWithoutFrame->frameHost());
    RefPtrWillBeRawPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*documentWithoutFrame);
    html->appendChild(HTMLBodyElement::create(*documentWithoutFrame));

    // Create an input element with type "range" inside a document without frame.
    toHTMLBodyElement(html->firstChild())->setInnerHTML("<input type='range' />", ASSERT_NO_EXCEPTION);
    documentWithoutFrame->appendChild(html.release());

    OwnPtr<DummyPageHolder> pageHolder = DummyPageHolder::create();
    auto& document = pageHolder->document();
    EXPECT_NE(nullptr, document.frameHost());

    // Put the input element inside a document with frame.
    document.body()->appendChild(documentWithoutFrame->body()->firstChild());

    // Remove the input element and all refs to it so it gets deleted before the document.
    // The assert in |EventHandlerRegistry::updateEventHandlerTargets()| should not be triggered.
    document.body()->removeChild(document.body()->firstChild());
}
TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByNormalize)
{
    setBodyInnerHTML("<b><i>foo</i></b>");
    {
        RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
        parent->appendChild(createTextNode("bar").get());
        markNodeContents(parent.get());
        EXPECT_EQ(2u, markerController().markers().size());
        parent->normalize();
    }
    // No more reference to marked node.
    Heap::collectAllGarbage();
    EXPECT_EQ(1u, markerController().markers().size());
}
void ColorInputType::createShadowSubtree()
{
    ASSERT(element().shadow());

    Document& document = element().document();
    RefPtrWillBeRawPtr<HTMLDivElement> wrapperElement = HTMLDivElement::create(document);
    wrapperElement->setShadowPseudoId(AtomicString("-webkit-color-swatch-wrapper", AtomicString::ConstructFromLiteral));
    RefPtrWillBeRawPtr<HTMLDivElement> colorSwatch = HTMLDivElement::create(document);
    colorSwatch->setShadowPseudoId(AtomicString("-webkit-color-swatch", AtomicString::ConstructFromLiteral));
    wrapperElement->appendChild(colorSwatch.release());
    element().userAgentShadowRoot()->appendChild(wrapperElement.release());

    element().updateView();
}
static PassRefPtrWillBeRawPtr<Node> cloneNodeAndAssociate(Node& toClone)
{
    RefPtrWillBeRawPtr<Node> clone = toClone.cloneNode(false);
    if (!clone->isSVGElement())
        return clone.release();

    SVGElement& svgElement = toSVGElement(toClone);
    ASSERT(!svgElement.correspondingElement());
    toSVGElement(clone.get())->setCorrespondingElement(&svgElement);
    if (EventTargetData* data = toClone.eventTargetData())
        data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(clone.get());
    TrackExceptionState exceptionState;
    for (RefPtrWillBeRawPtr<Node> node = toClone.firstChild(); node && !exceptionState.hadException(); node = node->nextSibling())
        clone->appendChild(cloneNodeAndAssociate(*node), exceptionState);
    return clone.release();
}
PassRefPtrWillBeRawPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document& document, const String& data, const AtomicString& value,
    bool defaultSelected, bool selected, ExceptionState& exceptionState)
{
    RefPtrWillBeRawPtr<HTMLOptionElement> element = adoptRefWillBeNoop(new HTMLOptionElement(document));
    element->appendChild(Text::create(document, data.isNull() ? "" : data), exceptionState);
    if (exceptionState.hadException())
        return nullptr;

    if (!value.isNull())
        element->setValue(value);
    if (defaultSelected)
        element->setAttribute(selectedAttr, emptyAtom);
    element->setSelected(selected);

    return element.release();
}
void SVGUseElement::expandSymbolElementsInShadowTree(SVGElement* element)
{
    ASSERT(element);
    if (isSVGSymbolElement(*element)) {
        // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree,
        // with the exception that the 'symbol' is replaced by an 'svg'. This generated 'svg' will
        // always have explicit values for attributes width and height. If attributes width and/or
        // height are provided on the 'use' element, then these attributes will be transferred to
        // the generated 'svg'. If attributes width and/or height are not specified, the generated
        // 'svg' element will use values of 100% for these attributes.
        ASSERT(referencedScope());
        RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(referencedScope()->document());
        // Transfer all data (attributes, etc.) from <symbol> to the new <svg> element.
        svgElement->cloneDataFromElement(*element);
        svgElement->setCorrespondingElement(element->correspondingElement());

        // Move already cloned elements to the new <svg> element
        for (RefPtrWillBeRawPtr<Node> child = element->firstChild(); child; ) {
            RefPtrWillBeRawPtr<Node> nextChild = child->nextSibling();
            svgElement->appendChild(child);
            child = nextChild.release();
        }

        // We don't walk the target tree element-by-element, and clone each element,
        // but instead use cloneNode(deep=true). This is an optimization for the common
        // case where <use> doesn't contain disallowed elements (ie. <foreignObject>).
        // Though if there are disallowed elements in the subtree, we have to remove them.
        // For instance: <use> on <g> containing <foreignObject> (indirect case).
        if (subtreeContainsDisallowedElement(svgElement.get()))
            removeDisallowedElementsFromSubtree(*svgElement);

        RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get());

        // Replace <symbol> with <svg>.
        ASSERT(element->parentNode());
        element->parentNode()->replaceChild(svgElement.release(), element);

        // Expand the siblings because the *element* is replaced and we will
        // lose the sibling chain when we are back from recursion.
        element = replacingElement.get();
        for (RefPtrWillBeRawPtr<SVGElement> sibling = Traversal<SVGElement>::nextSibling(*element); sibling; sibling = Traversal<SVGElement>::nextSibling(*sibling))
            expandSymbolElementsInShadowTree(sibling.get());
    }

    for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChild(*element); child; child = Traversal<SVGElement>::nextSibling(*child))
        expandSymbolElementsInShadowTree(child.get());
}
PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionState& exceptionState)
{
    if (index < -1) {
        exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is less than -1.");
        return nullptr;
    }

    RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);

    RefPtrWillBeRawPtr<HTMLTableRowElement> lastRow = nullptr;
    RefPtrWillBeRawPtr<HTMLTableRowElement> row = nullptr;
    if (index == -1)
        lastRow = HTMLTableRowsCollection::lastRow(*this);
    else {
        for (int i = 0; i <= index; ++i) {
            row = HTMLTableRowsCollection::rowAfter(*this, lastRow.get());
            if (!row) {
                if (i != index) {
                    exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is greater than the number of rows in the table (" + String::number(i) + ").");
                    return nullptr;
                }
                break;
            }
            lastRow = row;
        }
    }

    RefPtrWillBeRawPtr<ContainerNode> parent;
    if (lastRow)
        parent = row ? row->parentNode() : lastRow->parentNode();
    else {
        parent = lastBody();
        if (!parent) {
            RefPtrWillBeRawPtr<HTMLTableSectionElement> newBody = HTMLTableSectionElement::create(tbodyTag, document());
            RefPtrWillBeRawPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
            newBody->appendChild(newRow, exceptionState);
            appendChild(newBody.release(), exceptionState);
            return newRow.release();
        }
    }

    RefPtrWillBeRawPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
    parent->insertBefore(newRow, row.get(), exceptionState);
    return newRow.release();
}
Example #23
0
PassRefPtrWillBeRawPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title)
{
    DocumentInit init = DocumentInit::fromContext(document().contextDocument())
        .withRegistrationContext(document().registrationContext());
    RefPtrWillBeRawPtr<HTMLDocument> d = HTMLDocument::create(init);
    d->open();
    d->write("<!doctype html><html><head></head><body></body></html>");
    if (!title.isNull()) {
        HTMLHeadElement* headElement = d->head();
        ASSERT(headElement);
        RefPtrWillBeRawPtr<HTMLTitleElement> titleElement = HTMLTitleElement::create(*d);
        headElement->appendChild(titleElement);
        titleElement->appendChild(d->createTextNode(title), ASSERT_NO_EXCEPTION);
    }
    d->setSecurityOrigin(document().securityOrigin()->isolatedCopy());
    d->setContextFeatures(document().contextFeatures());
    return d.release();
}
void GranularityStrategyTest::setupTextSpan(String str1, String str2, String str3, size_t selBegin, size_t selEnd)
{
    RefPtrWillBeRawPtr<Text> text1 = document().createTextNode(str1);
    RefPtrWillBeRawPtr<Text> text2 = document().createTextNode(str2);
    RefPtrWillBeRawPtr<Text> text3 = document().createTextNode(str3);
    RefPtrWillBeRawPtr<Element> span = HTMLSpanElement::create(document());
    Element* div = document().getElementById("mytext");
    div->appendChild(text1);
    div->appendChild(span);
    span->appendChild(text2);
    div->appendChild(text3);

    document().view()->updateAllLifecyclePhases();

    Vector<IntPoint> letterPos;
    Vector<IntPoint> wordMiddlePos;

    TextNodeVector textNodes;
    textNodes.append(text1);
    textNodes.append(text2);
    textNodes.append(text3);
    parseText(textNodes);

    Position p1;
    Position p2;
    if (selBegin < str1.length())
        p1 = Position(text1, selBegin);
    else if (selBegin < str1.length() + str2.length())
        p1 = Position(text2, selBegin - str1.length());
    else
        p1 = Position(text3, selBegin - str1.length() - str2.length());
    if (selEnd < str1.length())
        p2 = Position(text1, selEnd);
    else if (selEnd < str1.length() + str2.length())
        p2 = Position(text2, selEnd - str1.length());
    else
        p2 = Position(text3, selEnd - str1.length() - str2.length());

    selection().setSelection(VisibleSelection(p1, p2));
}
// The media controls DOM structure looks like:
//
// MediaControls                                       (-webkit-media-controls)
// +-MediaControlOverlayEnclosureElement               (-webkit-media-controls-overlay-enclosure)
// | +-MediaControlOverlayPlayButtonElement            (-webkit-media-controls-overlay-play-button)
// | | {if mediaControlsOverlayPlayButtonEnabled}
// | \-MediaControlCastButtonElement                   (-internal-media-controls-overlay-cast-button)
// \-MediaControlPanelEnclosureElement                 (-webkit-media-controls-enclosure)
//   \-MediaControlPanelElement                        (-webkit-media-controls-panel)
//     +-MediaControlPlayButtonElement                 (-webkit-media-controls-play-button)
//     | {if !RTE::newMediaPlaybackUi()}
//     +-MediaControlTimelineElement                   (-webkit-media-controls-timeline)
//     +-MediaControlCurrentTimeDisplayElement         (-webkit-media-controls-current-time-display)
//     +-MediaControlTimeRemainingDisplayElement       (-webkit-media-controls-time-remaining-display)
//     | {if RTE::newMediaPlaybackUi()}
//     +-MediaControlTimelineElement                   (-webkit-media-controls-timeline)
//     +-MediaControlMuteButtonElement                 (-webkit-media-controls-mute-button)
//     +-MediaControlVolumeSliderElement               (-webkit-media-controls-volume-slider)
//     +-MediaControlToggleClosedCaptionsButtonElement (-webkit-media-controls-toggle-closed-captions-button)
//     +-MediaControlCastButtonElement                 (-internal-media-controls-cast-button)
//     \-MediaControlFullscreenButtonElement           (-webkit-media-controls-fullscreen-button)
void MediaControls::initializeControls()
{
    const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled();
    RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(*this);

    if (document().settings() && document().settings()->mediaControlsOverlayPlayButtonEnabled()) {
        RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(*this);
        m_overlayPlayButton = overlayPlayButton.get();
        overlayEnclosure->appendChild(overlayPlayButton.release());
    }

    RefPtrWillBeRawPtr<MediaControlCastButtonElement> overlayCastButton = MediaControlCastButtonElement::create(*this, true);
    m_overlayCastButton = overlayCastButton.get();
    overlayEnclosure->appendChild(overlayCastButton.release());

    m_overlayEnclosure = overlayEnclosure.get();
    appendChild(overlayEnclosure.release());

    // Create an enclosing element for the panel so we can visually offset the controls correctly.
    RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(*this);

    RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(*this);

    RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(*this);
    m_playButton = playButton.get();
    panel->appendChild(playButton.release());

    RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(*this);
    m_timeline = timeline.get();
    // In old UX, timeline is before the time / duration text.
    if (!useNewUi)
        panel->appendChild(timeline.release());
    // else we will attach it later.

    RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this);
    m_currentTimeDisplay = currentTimeDisplay.get();
    m_currentTimeDisplay->setIsWanted(useNewUi);
    panel->appendChild(currentTimeDisplay.release());

    RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this);
    m_durationDisplay = durationDisplay.get();
    panel->appendChild(durationDisplay.release());

    // Timeline is after the time / duration text if newMediaPlaybackUiEnabled.
    if (useNewUi)
        panel->appendChild(timeline.release());

    RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlMuteButtonElement::create(*this);
    m_muteButton = muteButton.get();
    panel->appendChild(muteButton.release());
    if (m_allowHiddenVolumeControls && preferHiddenVolumeControls(document()))
        m_muteButton->setIsWanted(false);

    RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(*this);
    m_volumeSlider = slider.get();
    panel->appendChild(slider.release());
    if (m_allowHiddenVolumeControls && preferHiddenVolumeControls(document()))
        m_volumeSlider->setIsWanted(false);

    RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this);
    m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
    panel->appendChild(toggleClosedCaptionsButton.release());

    RefPtrWillBeRawPtr<MediaControlCastButtonElement> castButton = MediaControlCastButtonElement::create(*this, false);
    m_castButton = castButton.get();
    panel->appendChild(castButton.release());

    RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(*this);
    m_fullScreenButton = fullscreenButton.get();
    panel->appendChild(fullscreenButton.release());

    m_panel = panel.get();
    enclosure->appendChild(panel.release());

    m_enclosure = enclosure.get();
    appendChild(enclosure.release());
}
bool SVGUseElement::expandUseElementsInShadowTree(SVGElement* element)
{
    ASSERT(element);
    // Why expand the <use> elements in the shadow tree here, and not just
    // do this directly in buildShadowTree, if we encounter a <use> element?
    //
    // Short answer: Because we may miss to expand some elements. For example, if a <symbol>
    // contains <use> tags, we'd miss them. So once we're done with setting up the
    // actual shadow tree (after the special case modification for svg/symbol) we have
    // to walk it completely and expand all <use> elements.
    if (isSVGUseElement(*element)) {
        SVGUseElement* use = toSVGUseElement(element);
        ASSERT(!use->resourceIsStillLoading());

        SVGElement* target = 0;
        if (hasCycleUseReferencing(toSVGUseElement(use->correspondingElement()), use, target))
            return false;

        if (target && isDisallowedElement(target))
            return false;
        // Don't ASSERT(target) here, it may be "pending", too.
        // Setup sub-shadow tree root node
        RefPtrWillBeRawPtr<SVGGElement> cloneParent = SVGGElement::create(referencedScope()->document());
        cloneParent->setCorrespondingElement(use->correspondingElement());

        // Move already cloned elements to the new <g> element
        for (RefPtrWillBeRawPtr<Node> child = use->firstChild(); child; ) {
            RefPtrWillBeRawPtr<Node> nextChild = child->nextSibling();
            cloneParent->appendChild(child);
            child = nextChild.release();
        }

        // Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the
        // 'use' element except for x, y, width, height and xlink:href are transferred to the generated 'g' element.
        transferUseAttributesToReplacedElement(use, cloneParent.get());

        if (target) {
            RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target);
            ASSERT(newChild->isSVGElement());
            transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get()), *target);
            cloneParent->appendChild(newChild.release());
        }

        // We don't walk the target tree element-by-element, and clone each element,
        // but instead use cloneElementWithChildren(). This is an optimization for the common
        // case where <use> doesn't contain disallowed elements (ie. <foreignObject>).
        // Though if there are disallowed elements in the subtree, we have to remove them.
        // For instance: <use> on <g> containing <foreignObject> (indirect case).
        if (subtreeContainsDisallowedElement(cloneParent.get()))
            removeDisallowedElementsFromSubtree(*cloneParent);

        RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get());

        // Replace <use> with referenced content.
        ASSERT(use->parentNode());
        use->parentNode()->replaceChild(cloneParent.release(), use);

        // Expand the siblings because the *element* is replaced and we will
        // lose the sibling chain when we are back from recursion.
        element = replacingElement.get();
        for (RefPtrWillBeRawPtr<SVGElement> sibling = Traversal<SVGElement>::nextSibling(*element); sibling; sibling = Traversal<SVGElement>::nextSibling(*sibling)) {
            if (!expandUseElementsInShadowTree(sibling.get()))
                return false;
        }
    }

    for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChild(*element); child; child = Traversal<SVGElement>::nextSibling(*child)) {
        if (!expandUseElementsInShadowTree(child.get()))
            return false;
    }
    return true;
}
Example #27
0
// The media controls DOM structure looks like:
//
// MediaControls                                       (-webkit-media-controls)
// +-MediaControlOverlayEnclosureElement               (-webkit-media-controls-overlay-enclosure)
// | +-MediaControlOverlayPlayButtonElement            (-webkit-media-controls-overlay-play-button)
// | | {if mediaControlsOverlayPlayButtonEnabled}
// | \-MediaControlCastButtonElement                   (-internal-media-controls-overlay-cast-button)
// \-MediaControlPanelEnclosureElement                 (-webkit-media-controls-enclosure)
//   \-MediaControlPanelElement                        (-webkit-media-controls-panel)
//     +-MediaControlPlayButtonElement                 (-webkit-media-controls-play-button)
//     +-MediaControlTimelineElement                   (-webkit-media-controls-timeline)
//     +-MediaControlCurrentTimeDisplayElement         (-webkit-media-controls-current-time-display)
//     +-MediaControlTimeRemainingDisplayElement       (-webkit-media-controls-time-remaining-display)
//     +-MediaControlMuteButtonElement                 (-webkit-media-controls-mute-button)
//     +-MediaControlVolumeSliderElement               (-webkit-media-controls-volume-slider)
//     +-MediaControlToggleClosedCaptionsButtonElement (-webkit-media-controls-toggle-closed-captions-button)
//     +-MediaControlCastButtonElement                 (-internal-media-controls-cast-button)
//     \-MediaControlFullscreenButtonElement           (-webkit-media-controls-fullscreen-button)
void MediaControls::initializeControls()
{
    RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(*this);

    if (document().settings() && document().settings()->mediaControlsOverlayPlayButtonEnabled()) {
        RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(*this);
        m_overlayPlayButton = overlayPlayButton.get();
        overlayEnclosure->appendChild(overlayPlayButton.release());
    }

    RefPtrWillBeRawPtr<MediaControlCastButtonElement> overlayCastButton = MediaControlCastButtonElement::create(*this, true);
    m_overlayCastButton = overlayCastButton.get();
    overlayEnclosure->appendChild(overlayCastButton.release());

    m_overlayEnclosure = overlayEnclosure.get();
    appendChild(overlayEnclosure.release());

    // Create an enclosing element for the panel so we can visually offset the controls correctly.
    RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(*this);

    RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(*this);

    RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(*this);
    m_playButton = playButton.get();
    panel->appendChild(playButton.release());

    RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(*this);
    m_timeline = timeline.get();
    panel->appendChild(timeline.release());

    RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this);
    m_currentTimeDisplay = currentTimeDisplay.get();
    m_currentTimeDisplay->hide();
    panel->appendChild(currentTimeDisplay.release());

    RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this);
    m_durationDisplay = durationDisplay.get();
    panel->appendChild(durationDisplay.release());

    RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlMuteButtonElement::create(*this);
    m_muteButton = muteButton.get();
    panel->appendChild(muteButton.release());

    RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(*this);
    m_volumeSlider = slider.get();
    panel->appendChild(slider.release());

    RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this);
    m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
    panel->appendChild(toggleClosedCaptionsButton.release());

    RefPtrWillBeRawPtr<MediaControlCastButtonElement> castButton = MediaControlCastButtonElement::create(*this, false);
    m_castButton = castButton.get();
    panel->appendChild(castButton.release());

    RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(*this);
    m_fullScreenButton = fullscreenButton.get();
    panel->appendChild(fullscreenButton.release());

    m_panel = panel.get();
    enclosure->appendChild(panel.release());

    m_enclosure = enclosure.get();
    appendChild(enclosure.release());
}