void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element* anchorNode) { LayoutObject* layoutObject = this->layoutObject(); SVGViewSpec* view = m_viewSpec.get(); if (view) view->reset(); bool hadUseCurrentView = m_useCurrentView; m_useCurrentView = false; if (fragmentIdentifier.startsWith("svgView(")) { if (!view) view = currentView(); // Create the SVGViewSpec. view->inheritViewAttributesFromElement(this); if (view->parseViewSpec(fragmentIdentifier)) { UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGView); m_useCurrentView = true; } else { view->reset(); } if (layoutObject && (hadUseCurrentView || m_useCurrentView)) markForLayoutAndParentResourceInvalidation(layoutObject); return; } // Spec: If the SVG fragment identifier addresses a 'view' element within an SVG document (e.g., MyDrawing.svg#MyView // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor 'svg' element is displayed in the viewport. // Any view specification attributes included on the given 'view' element override the corresponding view specification // attributes on the closest ancestor 'svg' element. // TODO(ed): The spec text above is a bit unclear. // Should the transform from outermost svg to nested svg be applied to "display" // the inner svg in the viewport, then let the view element override the inner // svg's view specification attributes. Should it fill/override the outer viewport? if (isSVGViewElement(anchorNode)) { SVGViewElement& viewElement = toSVGViewElement(*anchorNode); if (SVGSVGElement* svg = viewElement.ownerSVGElement()) { svg->inheritViewAttributes(&viewElement); if (LayoutObject* layoutObject = svg->layoutObject()) markForLayoutAndParentResourceInvalidation(layoutObject); return; } } // If we previously had a view and didn't get a new one, we need to // layout again. if (layoutObject && hadUseCurrentView) markForLayoutAndParentResourceInvalidation(layoutObject); // FIXME: We need to decide which <svg> to focus on, and zoom to it. // FIXME: We need to actually "highlight" the viewTarget(s). }
void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element* anchorNode) { auto renderer = this->renderer(); SVGViewSpec* view = m_viewSpec.get(); if (view) view->reset(); bool hadUseCurrentView = m_useCurrentView; m_useCurrentView = false; if (fragmentIdentifier.startsWith("xpointer(")) { // FIXME: XPointer references are ignored (https://bugs.webkit.org/show_bug.cgi?id=17491) if (renderer && hadUseCurrentView) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } if (fragmentIdentifier.startsWith("svgView(")) { if (!view) view = currentView(); // Create the SVGViewSpec. if (view->parseViewSpec(fragmentIdentifier)) m_useCurrentView = true; else view->reset(); if (renderer && (hadUseCurrentView || m_useCurrentView)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } // Spec: If the SVG fragment identifier addresses a ‘view’ element within an SVG document (e.g., MyDrawing.svg#MyView // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor ‘svg’ element is displayed in the viewport. // Any view specification attributes included on the given ‘view’ element override the corresponding view specification // attributes on the closest ancestor ‘svg’ element. if (anchorNode && isSVGViewElement(anchorNode)) { if (SVGViewElement* viewElement = toSVGViewElement(anchorNode)) { SVGElement* element = SVGLocatable::nearestViewportElement(viewElement); if (element->hasTagName(SVGNames::svgTag)) { SVGSVGElement* svg = static_cast<SVGSVGElement*>(element); svg->inheritViewAttributes(viewElement); if (RenderElement* renderer = svg->renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); } } return; } // FIXME: We need to decide which <svg> to focus on, and zoom to it. // FIXME: We need to actually "highlight" the viewTarget(s). }
void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element* anchorNode) { if (fragmentIdentifier.startsWith("svgView(")) { SVGViewSpec* viewSpec = SVGViewSpec::createForElement(*this); if (viewSpec->parseViewSpec(fragmentIdentifier)) { UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGView); setViewSpec(viewSpec); return; } } setViewSpec(nullptr); if (!isSVGViewElement(anchorNode)) return; SVGViewElement& viewElement = toSVGViewElement(*anchorNode); // Spec: If the SVG fragment identifier addresses a 'view' element // within an SVG document (e.g., MyDrawing.svg#MyView) then the // closest ancestor 'svg' element is displayed in the // viewport. Any view specification attributes included on the // given 'view' element override the corresponding view // specification attributes on the closest ancestor 'svg' element. // TODO(ed): The spec text above is a bit unclear. // Should the transform from outermost svg to nested svg be applied to // "display" the inner svg in the viewport, then let the view element // override the inner svg's view specification attributes. Should it // fill/override the outer viewport? SVGSVGElement* svg = viewElement.ownerSVGElement(); if (!svg) return; SVGViewSpec* viewSpec = SVGViewSpec::createForElement(*svg); viewSpec->inheritViewAttributesFromElement(viewElement); UseCounter::count(svg->document(), UseCounter::SVGSVGElementFragmentSVGViewElement); svg->setViewSpec(viewSpec); }