void NodeSet::traversalSort() const
{
    HashSet<Node*> nodes;
    bool containsAttributeNodes = false;

    unsigned nodeCount = m_nodes.size();
    ASSERT(nodeCount > 1);
    for (unsigned i = 0; i < nodeCount; ++i) {
        Node* node = m_nodes[i].get();
        nodes.add(node);
        if (node->isAttributeNode())
            containsAttributeNodes = true;
    }

    Vector<RefPtr<Node>> sortedNodes;
    sortedNodes.reserveInitialCapacity(nodeCount);

    for (Node* n = findRootNode(m_nodes.first().get()); n; n = NodeTraversal::next(n)) {
        if (nodes.contains(n))
            sortedNodes.append(n);

        if (!containsAttributeNodes || !n->isElementNode())
            continue;

        Element* element = toElement(n);
        if (!element->hasAttributes())
            continue;

        for (const Attribute& attribute : element->attributesIterator()) {
            RefPtr<Attr> attr = element->attrIfExists(attribute.name());
            if (attr && nodes.contains(attr.get()))
                sortedNodes.append(attr);
        }
    }

    ASSERT(sortedNodes.size() == nodeCount);
    m_nodes = std::move(sortedNodes);
    m_isSorted = true;
}
RenderObject* NodeRenderingContext::parentRenderer() const
{
    if (RenderObject* renderer = m_node->renderer())
        return renderer->parent();

    if (m_node->isElementNode() && toElement(m_node)->shouldBeReparentedUnderRenderView(m_style.get())) {
        // The parent renderer of reparented elements is the RenderView, but only
        // if the normal parent would have had a renderer.
        // FIXME: This behavior isn't quite right as the spec for top layer
        // only talks about display: none ancestors so putting a <dialog> inside
        // an <optgroup> seems like it should still work even though this check
        // will prevent it.
        if (!m_renderingParent || !m_renderingParent->renderer())
            return 0;
        return m_node->document().renderView();
    }

    if (m_parentFlowRenderer)
        return m_parentFlowRenderer;

    return m_renderingParent ? m_renderingParent->renderer() : 0;
}
void SplitTextNodeContainingElementCommand::doApply()
{
    ASSERT(m_text);
    ASSERT(m_offset > 0);

    splitTextNode(m_text.get(), m_offset);

    Element* parent = m_text->parentElement();
    if (!parent || !parent->parentElement() || !parent->parentElement()->rendererIsEditable())
        return;

    RenderObject* parentRenderer = parent->renderer();
    if (!parentRenderer || !parentRenderer->isInline()) {
        wrapContentsInDummySpan(parent);
        Node* firstChild = parent->firstChild();
        if (!firstChild || !firstChild->isElementNode())
            return;
        parent = toElement(firstChild);
    }

    splitElement(parent, m_text.get());
}
void MarkupAccumulator::appendStartMarkup(StringBuilder& result, const Node& node, Namespaces* namespaces)
{
    if (namespaces)
        namespaces->checkConsistency();

    switch (node.nodeType()) {
    case Node::TEXT_NODE:
        appendText(result, toText(node));
        break;
    case Node::COMMENT_NODE:
        appendComment(result, toComment(node).data());
        break;
    case Node::DOCUMENT_NODE:
        appendXMLDeclaration(result, toDocument(node));
        break;
    case Node::DOCUMENT_FRAGMENT_NODE:
        break;
    case Node::DOCUMENT_TYPE_NODE:
        appendDocumentType(result, toDocumentType(node));
        break;
    case Node::PROCESSING_INSTRUCTION_NODE:
        appendProcessingInstruction(result, toProcessingInstruction(node).target(), toProcessingInstruction(node).data());
        break;
    case Node::ELEMENT_NODE:
        appendElement(result, toElement(node), namespaces);
        break;
    case Node::CDATA_SECTION_NODE:
        appendCDATASection(result, toCDATASection(node).data());
        break;
    case Node::ATTRIBUTE_NODE:
    case Node::ENTITY_NODE:
    case Node::ENTITY_REFERENCE_NODE:
    case Node::NOTATION_NODE:
    case Node::XPATH_NAMESPACE_NODE:
        ASSERT_NOT_REACHED();
        break;
    }
}
Exemple #5
0
void SelectorDataList::execute(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const
{
    std::pair<bool, Node*> traverseRoot = findTraverseRoot(rootNode);
    if (!traverseRoot.second)
        return;
    Node* traverseRootNode = traverseRoot.second;
    if (traverseRoot.first) {
        ASSERT(m_selectors.size() == 1);
        ASSERT(traverseRootNode->isElementNode());
        Element* element = toElement(traverseRootNode);
        if (selectorMatches(m_selectors[0], element, rootNode))
            matchedElements.append(element);
        return;
    }

    unsigned selectorCount = m_selectors.size();
    if (selectorCount == 1) {
        const SelectorData& selector = m_selectors[0];
        for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
            if (selectorMatches(selector, element, rootNode)) {
                matchedElements.append(element);
                if (firstMatchOnly)
                    return;
            }
        }
        return;
    }
    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
        for (unsigned i = 0; i < selectorCount; ++i) {
            if (selectorMatches(m_selectors[i], element, rootNode)) {
                matchedElements.append(element);
                if (firstMatchOnly)
                    return;
                break;
            }
        }
    }
}
RenderObject* NodeRenderingContext::previousRenderer() const
{
    if (RenderObject* renderer = m_node->renderer())
        return renderer->previousSibling();

    // FIXME: This doesn't work correctly for reparented elements that are
    // display: none. We'd need to duplicate the logic in nextRenderer, but since
    // nothing needs that yet just assert.
    ASSERT(!m_node->isElementNode() || !toElement(m_node)->shouldBeReparentedUnderRenderView(m_style.get()));

    if (m_parentFlowRenderer)
        return m_parentFlowRenderer->previousRendererForNode(m_node);

    // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
    // however, when I tried adding it, several tests failed.
    for (Node* sibling = NodeRenderingTraversal::previousSibling(m_node); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
        RenderObject* renderer = sibling->renderer();
        if (renderer && !isRendererReparented(renderer))
            return renderer;
    }

    return 0;
}
void CaretBase::paintCaret(Node* node, GraphicsContext* context, const LayoutPoint& paintOffset) const
{
    if (m_caretVisibility == Hidden)
        return;

    LayoutRect drawingRect = localCaretRectWithoutUpdate();
    if (LayoutBlock* layoutObject = caretLayoutObject(node))
        layoutObject->flipForWritingMode(drawingRect);
    drawingRect.moveBy(roundedIntPoint(paintOffset));

    Color caretColor = Color::black;

    Element* element;
    if (node->isElementNode())
        element = toElement(node);
    else
        element = node->parentElement();

    if (element && element->layoutObject())
        caretColor = element->layoutObject()->resolveColor(CSSPropertyColor);

    context->fillRect(FloatRect(drawingRect), caretColor);
}
Element* SlotScopedTraversal::next(const Element& current) {
  Element* nearestInclusiveAncestorAssignedToSlot =
      SlotScopedTraversal::nearestInclusiveAncestorAssignedToSlot(current);
  DCHECK(nearestInclusiveAncestorAssignedToSlot);
  // Search within children of an element which is assigned to a slot.
  if (Element* next = nextSkippingChildrenOfShadowHost(
          current, *nearestInclusiveAncestorAssignedToSlot))
    return next;

  // Seek to the next element assigned to the same slot.
  HTMLSlotElement* slot =
      nearestInclusiveAncestorAssignedToSlot->assignedSlot();
  DCHECK(slot);
  const HeapVector<Member<Node>>& assignedNodes = slot->assignedNodes();
  size_t currentIndex =
      assignedNodes.find(*nearestInclusiveAncestorAssignedToSlot);
  DCHECK_NE(currentIndex, kNotFound);
  for (++currentIndex; currentIndex < assignedNodes.size(); ++currentIndex) {
    if (assignedNodes[currentIndex]->isElementNode())
      return toElement(assignedNodes[currentIndex]);
  }
  return nullptr;
}
Exemple #9
0
bool RenderThemeWinCE::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
    Color buttonColor = (o->node() && o->node()->isElementNode() && toElement(o->node())->active()) ? Color(138, 138, 138) : Color(186, 186, 186);

    IntSize cancelSize(10, 10);
    IntSize cancelRadius(cancelSize.width() / 2, cancelSize.height() / 2);
    int x = r.x() + (r.width() - cancelSize.width()) / 2;
    int y = r.y() + (r.height() - cancelSize.height()) / 2 + 1;
    IntRect cancelBounds(IntPoint(x, y), cancelSize);
    paintInfo.context->save();
    paintInfo.context->clipRoundedRect(RoundedRect(cancelBounds, cancelRadius, cancelRadius, cancelRadius, cancelRadius));
    paintInfo.context->fillRect(cancelBounds, buttonColor, ColorSpaceDeviceRGB);

    // Draw the 'x'
    IntSize xSize(3, 3);
    IntRect xBounds(cancelBounds.location() + IntSize(3, 3), xSize);
    paintInfo.context->setStrokeColor(Color::white, ColorSpaceDeviceRGB);
    paintInfo.context->drawLine(xBounds.location(),  xBounds.location() + xBounds.size());
    paintInfo.context->drawLine(IntPoint(xBounds.maxX(), xBounds.y()),  IntPoint(xBounds.x(), xBounds.maxY()));

    paintInfo.context->restore();
    return false;
}
bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
{
    Document::ListenerType listenerType;
    if (eventType == eventNames().webkitAnimationIterationEvent)
        listenerType = Document::ANIMATIONITERATION_LISTENER;
    else if (eventType == eventNames().webkitAnimationEndEvent)
        listenerType = Document::ANIMATIONEND_LISTENER;
    else {
        ASSERT(eventType == eventNames().webkitAnimationStartEvent);
        if (m_startEventDispatched)
            return false;
        m_startEventDispatched = true;
        listenerType = Document::ANIMATIONSTART_LISTENER;
    }

    if (shouldSendEventForListener(listenerType)) {
        // Dispatch the event
        RefPtr<Element> element;
        if (m_object->node() && m_object->node()->isElementNode())
            element = toElement(m_object->node());

        ASSERT(!element || (element->document() && !element->document()->inPageCache()));
        if (!element)
            return false;

        // Schedule event handling
        m_compAnim->animationController()->addEventToDispatch(element, eventType, m_keyframes.animationName(), elapsedTime);

        // Restore the original (unanimated) style
        if (eventType == eventNames().webkitAnimationEndEvent && element->renderer())
            setNeedsStyleRecalc(element.get());

        return true; // Did dispatch an event
    }

    return false; // Did not dispatch an event
}
Exemple #11
0
Node* SmartClip::findBestOverlappingNode(Node* rootNode, const IntRect& cropRect)
{
    if (!rootNode)
        return 0;

    IntRect resizedCropRect = rootNode->document().view()->windowToContents(cropRect);

    Node* node = rootNode;
    Node* minNode = 0;

    while (node) {
        IntRect nodeRect = node->pixelSnappedBoundingBox();

        if (node->isElementNode() && equalIgnoringCase(toElement(node)->fastGetAttribute(HTMLNames::aria_hiddenAttr), "true")) {
            node = NodeTraversal::nextSkippingChildren(*node, rootNode);
            continue;
        }

        RenderObject* renderer = node->renderer();
        if (renderer && !nodeRect.isEmpty()) {
            if (renderer->isText()
                || renderer->isRenderImage()
                || node->isFrameOwnerElement()
                || (renderer->style()->hasBackgroundImage() && !shouldSkipBackgroundImage(node))) {
                if (resizedCropRect.intersects(nodeRect)) {
                    minNode = minNodeContainsNodes(minNode, node);
                } else {
                    node = NodeTraversal::nextSkippingChildren(*node, rootNode);
                    continue;
                }
            }
        }
        node = NodeTraversal::next(*node, rootNode);
    }

    return minNode;
}
void ScopedStyleResolver::matchHostRules(ElementRuleCollector& collector, bool includeEmptyRules)
{
    // FIXME: Determine tree position.
    CascadeScope cascadeScope = ignoreCascadeScope;

    if (m_atHostRules.isEmpty() || !m_scopingNode.isElementNode())
        return;

    ElementShadow* shadow = toElement(m_scopingNode).shadow();
    if (!shadow)
        return;

    collector.clearMatchedRules();
    collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;

    // FIXME(99827): https://bugs.webkit.org/show_bug.cgi?id=99827
    // add a new flag to ElementShadow and cache whether any @host @-rules are
    // applied to the element or not. So we can quickly exit this method
    // by using the flag.
    ShadowRoot* shadowRoot = shadow->youngestShadowRoot();
    for (; shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
        if (!shadowRoot->containsShadowElements())
            break;
    // All shadow roots have <shadow>.
    if (!shadowRoot)
        shadowRoot = shadow->oldestShadowRoot();

    RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
    SelectorChecker::BehaviorAtBoundary boundary = static_cast<SelectorChecker::BehaviorAtBoundary>(SelectorChecker::DoesNotCrossBoundary | SelectorChecker::ScopeContainsLastMatchedElement);
    for (; shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) {
        if (RuleSet* ruleSet = atHostRuleSetFor(shadowRoot))
            collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, &m_scopingNode), ruleRange, boundary, cascadeScope);
    }

    collector.sortAndTransferMatchedRules();
}
TEST_P(PaintControllerPaintTestForSlimmingPaintV1AndV2, InlineRelayout)
{
    setBodyInnerHTML("<div id='div' style='width:100px; height: 200px'>AAAAAAAAAA BBBBBBBBBB</div>");
    Element& div = *toElement(document().body()->firstChild());
    LayoutBlock& divBlock = *toLayoutBlock(document().body()->firstChild()->layoutObject());
    LayoutText& text = *toLayoutText(divBlock.firstChild());
    InlineTextBox& firstTextBox = *text.firstTextBox();

    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 2,
        TestDisplayItem(layoutView(), backgroundType),
        TestDisplayItem(firstTextBox, foregroundType));

    div.setAttribute(HTMLNames::styleAttr, "width: 10px; height: 200px");
    document().view()->updateAllLifecyclePhases();

    LayoutText& newText = *toLayoutText(divBlock.firstChild());
    InlineTextBox& newFirstTextBox = *newText.firstTextBox();
    InlineTextBox& secondTextBox = *newText.firstTextBox()->nextTextBox();

    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 3,
        TestDisplayItem(layoutView(), backgroundType),
        TestDisplayItem(newFirstTextBox, foregroundType),
        TestDisplayItem(secondTextBox, foregroundType));
}
    QString SettingsSerializer::getOption(QString const& option)
    {
        auto root = m_document.documentElement();
        if (root.isNull() == false)
        {
            auto name = root.tagName();
            auto node = root.firstChild();
            while (node.isNull() == false)
            {
                auto element = node.toElement();
                if (element.isNull() == false)
                {
                    if (element.tagName() == option)
                    {
                        auto value = element.attribute("value");
                        return value;
                    }
                }

                node = node.nextSibling();
            }
        }
        return "";
    }
void NodeSet::traversalSort() const
{
    WillBeHeapHashSet<RawPtrWillBeMember<Node>> nodes;
    bool containsAttributeNodes = false;

    unsigned nodeCount = m_nodes.size();
    ASSERT(nodeCount > 1);
    for (unsigned i = 0; i < nodeCount; ++i) {
        Node* node = m_nodes[i].get();
        nodes.add(node);
        if (node->isAttributeNode())
            containsAttributeNodes = true;
    }

    WillBeHeapVector<RefPtrWillBeMember<Node>> sortedNodes;
    sortedNodes.reserveInitialCapacity(nodeCount);

    for (Node& n : NodeTraversal::startsAt(findRootNode(m_nodes.first().get()))) {
        if (nodes.contains(&n))
            sortedNodes.append(&n);

        if (!containsAttributeNodes || !n.isElementNode())
            continue;

        Element* element = toElement(&n);
        AttributeCollection attributes = element->attributes();
        for (auto& attribute : attributes) {
            RefPtrWillBeRawPtr<Attr> attr = element->attrIfExists(attribute.name());
            if (attr && nodes.contains(attr.get()))
                sortedNodes.append(attr);
        }
    }

    ASSERT(sortedNodes.size() == nodeCount);
    const_cast<WillBeHeapVector<RefPtrWillBeMember<Node>>&>(m_nodes).swap(sortedNodes);
}
Exemple #16
0
void CaretBase::paintCaret(Node* node, GraphicsContext* context, const LayoutPoint& paintOffset, const LayoutRect& clipRect) const
{
    if (m_caretVisibility == Hidden)
        return;

    LayoutRect drawingRect = localCaretRectWithoutUpdate();
    drawingRect.moveBy(roundedIntPoint(paintOffset));
    LayoutRect caret = intersection(drawingRect, clipRect);
    if (caret.isEmpty())
        return;

    Color caretColor = Color::black;

    Element* element;
    if (node->isElementNode())
        element = toElement(node);
    else
        element = node->parentElement();

    if (element && element->renderer())
        caretColor = element->renderer()->resolveColor(CSSPropertyColor);

    context->fillRect(caret, caretColor);
}
Exemple #17
0
RenderStyle& RenderTreeBuilder::style() const
{
    if (!m_style)
        m_style = toElement(m_node)->styleForRenderer();
    return *m_style;
}
Exemple #18
0
int main(){

	exception e;
	FILE *f = NULL;
	int i = 0,count=0,par_count=0,v=0;
	
	char* filename = "./bioinfo.xml";
	struct stat s;
	UByte *xml = NULL; // this is the buffer containing the XML content, UByte means unsigned byte
	VTDGen *vg = NULL; // This is the VTDGen that parses XML
	VTDNav *vn = NULL; // This is the VTDNav that navigates the VTD records
	AutoPilot *ap = NULL;

	// allocate a piece of buffer then reads in the document content
	// assume "c:\soap2.xml" is the name of the file
	f = fopen(filename,"r");

	stat(filename,&s);

	i = (int) s.st_size;	
	wprintf(L"size of the file is %d \n",i);

	xml = (UByte *)malloc(sizeof(UByte) *i);
	i = fread(xml,sizeof(UByte),i,f);
	Try{
		vg = createVTDGen();
		setDoc(vg,xml,i);
		parse(vg,TRUE);
		vn = getNav(vg);
		ap = createAutoPilot2();
		bind(ap,vn);
		if (selectXPath(ap,L"/bix/package/command/parlist")){
			while(evalXPath(ap)!= -1){
				count++;
			}
		}
		
		if (selectXPath(ap,L"/bix/package/command/parlist/par")){
			while(evalXPath(ap)!= -1){
				par_count++;
			}
		}
		wprintf(L"count ==> %d \n",count);
		wprintf(L"par_count ==> %d \n",par_count);

		toElement(vn,ROOT);
		selectElement(ap,L"par");
		while(iterateAP(ap)){
			if (getCurrentDepth(vn) == 4){
				v++;
			}
		}
		wprintf(L"verify ==> %d \n",v);
		fclose(f);
		// remember C has no automatic garbage collector
		// needs to deallocate manually.
		freeVTDNav(vn);
		freeVTDGen(vg);
		freeAutoPilot(ap);

	}
	Catch (e) {
		if (e.et == parse_exception)
			printf("parse exception e ==> %s \n %s\n", e.msg, e.sub_msg);	
		// manual garbage collection here
		freeVTDGen(vg);
	}
  return 0;
}	
void UserActionElementSet::clearFlags(Node* node, unsigned flags)
{
    if (!node->isElementNode())
        return;
    return clearFlags(toElement(node), flags);
}
bool UserActionElementSet::hasFlags(const Node* node, unsigned flags) const
{
    DCHECK(node->isUserActionElement() && node->isElementNode());
    return hasFlags(toElement(node), flags);
}
Exemple #21
0
static inline Element* parentOrPseudoHostElement(const RenderObject* object)
{
    if (object->node()->isPseudoElement())
        return toPseudoElement(object->node())->hostElement();
    return toElement(object->node())->parentElement();
}
Element* IntersectionObservation::target() const
{
    return toElement(m_target.get());
}
Exemple #23
0
WebElement::operator PassRefPtr<Element>() const
{
    return toElement(m_private.get());
}
static inline ElementShadow* shadowFor(const Node* node)
{
    if (node && node->isElementNode())
        return toElement(node)->shadow();
    return 0;
}
void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int indent)
{
    writeStandardPrefix(ts, object, indent);

    Element* element = toElement(object.node());
    const AtomicString& id = element->getIdAttribute();
    writeNameAndQuotedValue(ts, "id", id);

    RenderSVGResourceContainer* resource = const_cast<RenderObject&>(object).toRenderSVGResourceContainer();
    ASSERT(resource);

    if (resource->resourceType() == MaskerResourceType) {
        RenderSVGResourceMasker* masker = toRenderSVGResourceMasker(resource);
        writeNameValuePair(ts, "maskUnits", masker->maskUnits());
        writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits());
        ts << "\n";
    } else if (resource->resourceType() == FilterResourceType) {
        RenderSVGResourceFilter* filter = toRenderSVGResourceFilter(resource);
        writeNameValuePair(ts, "filterUnits", filter->filterUnits());
        writeNameValuePair(ts, "primitiveUnits", filter->primitiveUnits());
        ts << "\n";
        // Creating a placeholder filter which is passed to the builder.
        FloatRect dummyRect;
        RefPtr<SVGFilter> dummyFilter = SVGFilter::create(AffineTransform(), dummyRect, dummyRect, dummyRect, true);
        if (RefPtr<SVGFilterBuilder> builder = filter->buildPrimitives(dummyFilter.get())) {
            if (FilterEffect* lastEffect = builder->lastEffect())
                lastEffect->externalRepresentation(ts, indent + 1);
        }
    } else if (resource->resourceType() == ClipperResourceType) {
        writeNameValuePair(ts, "clipPathUnits", toRenderSVGResourceClipper(resource)->clipPathUnits());
        ts << "\n";
    } else if (resource->resourceType() == MarkerResourceType) {
        RenderSVGResourceMarker* marker = toRenderSVGResourceMarker(resource);
        writeNameValuePair(ts, "markerUnits", marker->markerUnits());
        ts << " [ref at " << marker->referencePoint() << "]";
        ts << " [angle=";
        if (marker->angle() == -1)
            ts << "auto" << "]\n";
        else
            ts << marker->angle() << "]\n";
    } else if (resource->resourceType() == PatternResourceType) {
        RenderSVGResourcePattern* pattern = static_cast<RenderSVGResourcePattern*>(resource);

        // Dump final results that are used for rendering. No use in asking SVGPatternElement for its patternUnits(), as it may
        // link to other patterns using xlink:href, we need to build the full inheritance chain, aka. collectPatternProperties()
        PatternAttributes attributes;
        toSVGPatternElement(pattern->element())->collectPatternAttributes(attributes);

        writeNameValuePair(ts, "patternUnits", attributes.patternUnits());
        writeNameValuePair(ts, "patternContentUnits", attributes.patternContentUnits());

        AffineTransform transform = attributes.patternTransform();
        if (!transform.isIdentity())
            ts << " [patternTransform=" << transform << "]";
        ts << "\n";
    } else if (resource->resourceType() == LinearGradientResourceType) {
        RenderSVGResourceLinearGradient* gradient = static_cast<RenderSVGResourceLinearGradient*>(resource);

        // Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may
        // link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties()
        LinearGradientAttributes attributes;
        toSVGLinearGradientElement(gradient->element())->collectGradientAttributes(attributes);
        writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.gradientUnits());

        ts << " [start=" << gradient->startPoint(attributes) << "] [end=" << gradient->endPoint(attributes) << "]\n";
    }  else if (resource->resourceType() == RadialGradientResourceType) {
        RenderSVGResourceRadialGradient* gradient = toRenderSVGResourceRadialGradient(resource);

        // Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may
        // link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties()
        RadialGradientAttributes attributes;
        toSVGRadialGradientElement(gradient->element())->collectGradientAttributes(attributes);
        writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.gradientUnits());

        FloatPoint focalPoint = gradient->focalPoint(attributes);
        FloatPoint centerPoint = gradient->centerPoint(attributes);
        float radius = gradient->radius(attributes);
        float focalRadius = gradient->focalRadius(attributes);

        ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "] [focalRadius=" << focalRadius << "]\n";
    } else
        ts << "\n";
    writeChildren(ts, object, indent);
}
Exemple #26
0
static PassRefPtr<InspectorObject> buildObjectForElementInfo(Node* node)
{
    if (!node->isElementNode() || !node->document().frame())
        return nullptr;

    RefPtr<InspectorObject> elementInfo = InspectorObject::create();

    Element* element = toElement(node);
    bool isXHTML = element->document().isXHTMLDocument();
    elementInfo->setString("tagName", isXHTML ? element->nodeName() : element->nodeName().lower());
    elementInfo->setString("idValue", element->getIdAttribute());
    HashSet<AtomicString> usedClassNames;
    if (element->hasClass() && element->isStyledElement()) {
        StringBuilder classNames;
        const SpaceSplitString& classNamesString = toStyledElement(element)->classNames();
        size_t classNameCount = classNamesString.size();
        for (size_t i = 0; i < classNameCount; ++i) {
            const AtomicString& className = classNamesString[i];
            if (usedClassNames.contains(className))
                continue;
            usedClassNames.add(className);
            classNames.append('.');
            classNames.append(className);
        }
        elementInfo->setString("className", classNames.toString());
    }

    RenderElement* renderer = element->renderer();
    Frame* containingFrame = node->document().frame();
    FrameView* containingView = containingFrame->view();
    IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect()));
    RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : nullptr;
    elementInfo->setString("nodeWidth", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetWidth(), *modelObject) : boundingBox.width()));
    elementInfo->setString("nodeHeight", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetHeight(), *modelObject) : boundingBox.height()));
    
    if (renderer->isRenderNamedFlowFragmentContainer()) {
        RenderNamedFlowFragment* region = toRenderBlockFlow(renderer)->renderNamedFlowFragment();
        if (region->isValid()) {
            RenderFlowThread* flowThread = region->flowThread();
            ASSERT(flowThread && flowThread->isRenderNamedFlowThread());
            RefPtr<InspectorObject> regionFlowInfo = InspectorObject::create();
            regionFlowInfo->setString("name", toRenderNamedFlowThread(flowThread)->flowThreadName());
            regionFlowInfo->setArray("regions", buildObjectForCSSRegionsHighlight(region, flowThread));
            elementInfo->setObject("regionFlowInfo", regionFlowInfo.release());
        }
    }

    RenderFlowThread* containingFlowThread = renderer->flowThreadContainingBlock();
    if (containingFlowThread && containingFlowThread->isRenderNamedFlowThread()) {
        RefPtr<InspectorObject> contentFlowInfo = InspectorObject::create();
        contentFlowInfo->setString("name", toRenderNamedFlowThread(containingFlowThread)->flowThreadName());
        elementInfo->setObject("contentFlowInfo", contentFlowInfo.release());
    }

#if ENABLE(CSS_SHAPES)
    if (renderer->isBox()) {
        RenderBox* renderBox = toRenderBox(renderer);
        if (RefPtr<InspectorObject> shapeObject = buildObjectForShapeOutside(containingFrame, renderBox))
            elementInfo->setObject("shapeOutsideInfo", shapeObject.release());
    }
#endif

    // Need to enable AX to get the computed role.
    if (!WebCore::AXObjectCache::accessibilityEnabled())
        WebCore::AXObjectCache::enableAccessibility();

    if (AXObjectCache* axObjectCache = node->document().axObjectCache()) {
        if (AccessibilityObject* axObject = axObjectCache->getOrCreate(node))
            elementInfo->setString("role", axObject->computedRoleString());
    }

    return elementInfo.release();
}
GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, const TextRun& run, WidthIterator& iterator, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength)
{
    const SimpleFontData* primaryFont = font.primaryFont();
    ASSERT(primaryFont);

    pair<GlyphData, GlyphPage*> pair = font.glyphDataAndPageForCharacter(character, mirror);
    GlyphData glyphData = pair.first;

    // Check if we have the missing glyph data, in which case we can just return.
    GlyphData missingGlyphData = primaryFont->missingGlyphData();
    if (glyphData.glyph == missingGlyphData.glyph && glyphData.fontData == missingGlyphData.fontData) {
        ASSERT(glyphData.fontData);
        return glyphData;
    }

    // Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage.
    const SimpleFontData* originalFontData = glyphData.fontData;
    if (glyphData.fontData && !glyphData.fontData->isSVGFont()) {
        if (TextRun::RenderingContext* renderingContext = run.renderingContext()) {
            RenderObject* renderObject = static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer();
            RenderObject* parentRenderObject = renderObject->isText() ? renderObject->parent() : renderObject;
            ASSERT(parentRenderObject);
            if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
                if (parentRenderObjectElement->hasTagName(SVGNames::altGlyphTag))
                    glyphData.fontData = primaryFont;
            }
        }
    }

    const SimpleFontData* fontData = glyphData.fontData;
    if (fontData) {
        if (!fontData->isSVGFont())
            return glyphData;

        SVGFontElement* fontElement = 0;
        SVGFontFaceElement* fontFaceElement = 0;

        const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
        if (!fontElement || !fontFaceElement)
            return glyphData;

        // If we got here, we're dealing with a glyph defined in a SVG Font.
        // The returned glyph by glyphDataAndPageForCharacter() is a glyph stored in the SVG Font glyph table.
        // This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its
        // arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that.
        if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength))
            return glyphData;
    }

    GlyphPage* page = pair.second;
    ASSERT(page);

    FontFallbackList* fontList = font.fontList();
    ASSERT(fontList);

    // No suitable glyph found that is compatible with the requirments (same language, arabic-form, orientation etc.)
    // Even though our GlyphPage contains an entry for eg. glyph "a", it's not compatible. So we have to temporarily
    // remove the glyph data information from the GlyphPage, and retry the lookup, which handles font fallbacks correctly.
    GlyphPageTreeNode* originalGlyphPageZero = fontList->glyphPageZero();
    const FontFallbackList::GlyphPages& originalGlyphPages = fontList->glyphPages();
    page->setGlyphDataForCharacter(character, glyphData.glyph, 0);

    // Assure that the font fallback glyph selection worked, aka. the fallbackGlyphData font data is not the same as before.
    GlyphData fallbackGlyphData = font.glyphDataForCharacter(character, mirror);
    ASSERT(fallbackGlyphData.fontData != fontData);

    // Restore original state of the SVG Font glyph table and the current font fallback list,
    // to assure the next lookup of the same glyph won't immediately return the fallback glyph.
    page->setGlyphDataForCharacter(character, glyphData.glyph, originalFontData);
    fontList->setGlyphPageZero(originalGlyphPageZero);
    fontList->setGlyphPages(originalGlyphPages);
    ASSERT(fallbackGlyphData.fontData);
    return fallbackGlyphData;
}
static inline ElementShadow* shadowFor(const Node& node)
{
    return node.isElementNode() ? toElement(node).shadow() : nullptr;
}
Exemple #29
0
void UserActionElementSet::didDetach(Node* node)
{
    ASSERT(node->isUserActionElement());
    clearFlags(toElement(node), IsActiveFlag | InActiveChainFlag | IsHoveredFlag);
}
static inline bool isShadowHost(Node* node)
{
    return node->isElementNode() && toElement(node)->hasShadowRoot();
}