JSValue jsHTMLBodyElementVLink(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLBodyElement* castedThis = static_cast<JSHTMLBodyElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLBodyElement* imp = static_cast<HTMLBodyElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->getAttribute(HTMLNames::vlinkAttr));
    return result;
}
Example #2
0
void HTMLDocument::setFgColor(const String& value)
{
    HTMLElement* b = body();
    HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;

    if (bodyElement)
        bodyElement->setText(value);
}
Example #3
0
String HTMLDocument::vlinkColor()
{
    HTMLElement* b = body();
    HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;

    if (!bodyElement)
        return String();
    return bodyElement->vLink();
}
Example #4
0
void HTMLDocument::setVlinkColor(const String& value)
{
    HTMLElement* b = body();
    HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;

    if (bodyElement) {
        // This check is a bit silly, but some benchmarks like to set the
        // document's link colors over and over to the same value and we
        // don't want to incur a style update each time.
        if (bodyElement->vLink() != value)
            bodyElement->setVLink(value);
    }
}
JSValue jsHTMLBodyElementOnunload(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLBodyElement* castedThis = static_cast<JSHTMLBodyElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLBodyElement* imp = static_cast<HTMLBodyElement*>(castedThis->impl());
    if (EventListener* listener = imp->onunload()) {
        if (const JSEventListener* jsListener = JSEventListener::cast(listener)) {
            if (JSObject* jsFunction = jsListener->jsFunction(imp->scriptExecutionContext()))
                return jsFunction;
        }
    }
    return jsNull();
}
String StyledMarkupSerializer<Strategy>::createMarkup()
{
    StyledMarkupAccumulator markupAccumulator(m_shouldResolveURLs, toTextOffset(m_start.parentAnchoredEquivalent()), toTextOffset(m_end.parentAnchoredEquivalent()), m_start.document(), m_shouldAnnotate, m_convertBlocksToInlines);

    Node* pastEnd = m_end.nodeAsRangePastLastNode();

    Node* firstNode = m_start.nodeAsRangeFirstNode();
    const VisiblePositionTemplate<Strategy> visibleStart = createVisiblePosition(m_start);
    const VisiblePositionTemplate<Strategy> visibleEnd = createVisiblePosition(m_end);
    if (shouldAnnotate() && needInterchangeNewlineAfter(visibleStart)) {
        markupAccumulator.appendInterchangeNewline();
        if (visibleStart.deepEquivalent() == previousPositionOf(visibleEnd).deepEquivalent())
            return markupAccumulator.takeResults();

        firstNode = nextPositionOf(visibleStart).deepEquivalent().anchorNode();

        if (pastEnd && PositionTemplate<Strategy>::beforeNode(firstNode).compareTo(PositionTemplate<Strategy>::beforeNode(pastEnd)) >= 0) {
            // This condition hits in editing/pasteboard/copy-display-none.html.
            return markupAccumulator.takeResults();
        }
    }

    if (!m_lastClosed)
        m_lastClosed = StyledMarkupTraverser<Strategy>().traverse(firstNode, pastEnd);
    StyledMarkupTraverser<Strategy> traverser(&markupAccumulator, m_lastClosed);
    Node* lastClosed = traverser.traverse(firstNode, pastEnd);

    if (m_highestNodeToBeSerialized && lastClosed) {
        // TODO(hajimehoshi): This is calculated at createMarkupInternal too.
        Node* commonAncestor = Strategy::commonAncestor(*m_start.computeContainerNode(), *m_end.computeContainerNode());
        ASSERT(commonAncestor);
        HTMLBodyElement* body = toHTMLBodyElement(enclosingElementWithTag(firstPositionInNode(commonAncestor), bodyTag));
        HTMLBodyElement* fullySelectedRoot = nullptr;
        // FIXME: Do this for all fully selected blocks, not just the body.
        if (body && areSameRanges(body, m_start, m_end))
            fullySelectedRoot = body;

        // Also include all of the ancestors of lastClosed up to this special ancestor.
        // FIXME: What is ancestor?
        for (ContainerNode* ancestor = Strategy::parent(*lastClosed); ancestor; ancestor = Strategy::parent(*ancestor)) {
            if (ancestor == fullySelectedRoot && !markupAccumulator.convertBlocksToInlines()) {
                RawPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);

                // Bring the background attribute over, but not as an attribute because a background attribute on a div
                // appears to have no effect.
                if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundImage))
                    && fullySelectedRoot->hasAttribute(backgroundAttr))
                    fullySelectedRootStyle->style()->setProperty(CSSPropertyBackgroundImage, "url('" + fullySelectedRoot->getAttribute(backgroundAttr) + "')");

                if (fullySelectedRootStyle->style()) {
                    // Reset the CSS properties to avoid an assertion error in addStyleMarkup().
                    // This assertion is caused at least when we select all text of a <body> element whose
                    // 'text-decoration' property is "inherit", and copy it.
                    if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyTextDecoration))
                        fullySelectedRootStyle->style()->setProperty(CSSPropertyTextDecoration, CSSValueNone);
                    if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyWebkitTextDecorationsInEffect))
                        fullySelectedRootStyle->style()->setProperty(CSSPropertyWebkitTextDecorationsInEffect, CSSValueNone);
                    markupAccumulator.wrapWithStyleNode(fullySelectedRootStyle->style());
                }
            } else {
                RawPtr<EditingStyle> style = traverser.createInlineStyleIfNeeded(*ancestor);
                // Since this node and all the other ancestors are not in the selection we want
                // styles that affect the exterior of the node not to be not included.
                // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
                // only the ones that affect it and the nodes within it.
                if (style && style->style())
                    style->style()->removeProperty(CSSPropertyFloat);
                traverser.wrapWithNode(*ancestor, style);
            }

            if (ancestor == m_highestNodeToBeSerialized)
                break;
        }
    }

    // FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally.
    if (shouldAnnotate() && needInterchangeNewlineAt(visibleEnd))
        markupAccumulator.appendInterchangeNewline();

    return markupAccumulator.takeResults();
}
void setJSHTMLBodyElementOnunload(ExecState* exec, JSObject* thisObject, JSValue value)
{
    UNUSED_PARAM(exec);
    HTMLBodyElement* imp = static_cast<HTMLBodyElement*>(static_cast<JSHTMLBodyElement*>(thisObject)->impl());
    imp->setOnunload(createJSAttributeEventListener(exec, value, thisObject));
}
void setJSHTMLBodyElementVLink(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLBodyElement* castedThisObj = static_cast<JSHTMLBodyElement*>(thisObject);
    HTMLBodyElement* imp = static_cast<HTMLBodyElement*>(castedThisObj->impl());
    imp->setAttribute(HTMLNames::vlinkAttr, valueToStringWithNullCheck(exec, value));
}
Example #9
0
void MediaDocumentParser::createDocumentStructure() {
  DCHECK(document());
  HTMLHtmlElement* rootElement = HTMLHtmlElement::create(*document());
  document()->appendChild(rootElement);
  rootElement->insertedByParser();

  if (isDetached())
    return;  // runScriptsAtDocumentElementAvailable can detach the frame.

  HTMLHeadElement* head = HTMLHeadElement::create(*document());
  HTMLMetaElement* meta = HTMLMetaElement::create(*document());
  meta->setAttribute(nameAttr, "viewport");
  meta->setAttribute(contentAttr, "width=device-width");
  head->appendChild(meta);

  HTMLVideoElement* media = HTMLVideoElement::create(*document());
  media->setAttribute(controlsAttr, "");
  media->setAttribute(autoplayAttr, "");
  media->setAttribute(nameAttr, "media");

  HTMLSourceElement* source = HTMLSourceElement::create(*document());
  source->setSrc(document()->url());

  if (DocumentLoader* loader = document()->loader())
    source->setType(loader->responseMIMEType());

  media->appendChild(source);

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

  document()->willInsertBody();

  HTMLDivElement* div = HTMLDivElement::create(*document());
  // Style sheets for media controls are lazily loaded until a media element is
  // encountered.  As a result, elements encountered before the media element
  // will not get the right style at first if we put the styles in
  // mediacontrols.css. To solve this issue, set the styles inline so that they
  // will be applied when the page loads.  See w3c example on how to centering
  // an element: https://www.w3.org/Style/Examples/007/center.en.html
  div->setAttribute(styleAttr,
                    "display: flex;"
                    "flex-direction: column;"
                    "justify-content: center;"
                    "align-items: center;"
                    "min-height: min-content;"
                    "height: 100%;");
  HTMLContentElement* content = HTMLContentElement::create(*document());
  div->appendChild(content);

  if (RuntimeEnabledFeatures::mediaDocumentDownloadButtonEnabled()) {
    HTMLAnchorElement* anchor = HTMLAnchorElement::create(*document());
    anchor->setAttribute(downloadAttr, "");
    anchor->setURL(document()->url());
    anchor->setTextContent(
        document()
            ->getCachedLocale(document()->contentLanguage())
            .queryString(WebLocalizedString::DownloadButtonLabel)
            .upper());
    // Using CSS style according to Android material design.
    anchor->setAttribute(
        styleAttr,
        "display: inline-block;"
        "margin-top: 32px;"
        "padding: 0 16px 0 16px;"
        "height: 36px;"
        "background: #000000;"
        "-webkit-tap-highlight-color: rgba(255, 255, 255, 0.12);"
        "font-family: Roboto;"
        "font-size: 14px;"
        "border-radius: 5px;"
        "color: white;"
        "font-weight: 500;"
        "text-decoration: none;"
        "line-height: 36px;");
    EventListener* listener = MediaDownloadEventListener::create();
    anchor->addEventListener(EventTypeNames::click, listener, false);
    HTMLDivElement* buttonContainer = HTMLDivElement::create(*document());
    buttonContainer->setAttribute(styleAttr,
                                  "text-align: center;"
                                  "height: 0;"
                                  "flex: none");
    buttonContainer->appendChild(anchor);
    div->appendChild(buttonContainer);
    recordDownloadMetric(MediaDocumentDownloadButtonShown);
  }

  // According to
  // https://html.spec.whatwg.org/multipage/browsers.html#read-media,
  // MediaDocument should have a single child which is the video element. Use
  // shadow root to hide all the elements we added here.
  ShadowRoot& shadowRoot = body->ensureUserAgentShadowRoot();
  shadowRoot.appendChild(div);
  body->appendChild(media);
  rootElement->appendChild(head);
  rootElement->appendChild(body);

  m_didBuildDocumentStructure = true;
}