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; } }
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; }
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 }
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); }
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); }
RenderStyle& RenderTreeBuilder::style() const { if (!m_style) m_style = toElement(m_node)->styleForRenderer(); return *m_style; }
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); }
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()); }
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); }
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; }
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(); }