void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
{
    if (attrName == SVGNames::dAttr) {
        SVGElement::InvalidationGuard invalidationGuard(this);
        invalidateSVGPresentationAttributeStyle();
        setNeedsStyleRecalc(LocalStyleChange,
            StyleChangeReasonForTracing::fromAttribute(attrName));

        if (LayoutSVGShape* layoutPath = toLayoutSVGShape(this->layoutObject()))
            layoutPath->setNeedsShapeUpdate();

        invalidateMPathDependencies();
        if (layoutObject())
            markForLayoutAndParentResourceInvalidation(layoutObject());

        return;
    }

    if (attrName == SVGNames::pathLengthAttr) {
        SVGElement::InvalidationGuard invalidationGuard(this);
        if (layoutObject())
            markForLayoutAndParentResourceInvalidation(layoutObject());
        return;
    }

    SVGGeometryElement::svgAttributeChanged(attrName);
}
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).
}
Beispiel #3
0
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) {
  if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
      attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) {
    SVGElement::InvalidationGuard invalidationGuard(this);

    if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) {
      invalidateSVGPresentationAttributeStyle();
      setNeedsStyleRecalc(LocalStyleChange,
                          StyleChangeReasonForTracing::fromAttribute(attrName));
    }

    updateRelativeLengthsInformation();
    if (m_targetElementInstance) {
      ASSERT(m_targetElementInstance->correspondingElement());
      transferUseWidthAndHeightIfNeeded(
          *this, *m_targetElementInstance,
          *m_targetElementInstance->correspondingElement());
    }

    LayoutObject* object = this->layoutObject();
    if (object)
      markForLayoutAndParentResourceInvalidation(object);
    return;
  }

  if (SVGURIReference::isKnownAttribute(attrName)) {
    SVGElement::InvalidationGuard invalidationGuard(this);
    updateTargetReference();
    invalidateShadowTree();
    return;
  }

  SVGGraphicsElement::svgAttributeChanged(attrName);
}
Beispiel #4
0
void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
{
    if (!isSupportedAttribute(attrName)) {
        SVGGeometryElement::svgAttributeChanged(attrName);
        return;
    }

    SVGElement::InvalidationGuard invalidationGuard(this);

    bool isLengthAttribute = attrName == SVGNames::cxAttr
                          || attrName == SVGNames::cyAttr
                          || attrName == SVGNames::rxAttr
                          || attrName == SVGNames::ryAttr;

    if (isLengthAttribute)
        updateRelativeLengthsInformation();

    RenderSVGShape* renderer = toRenderSVGShape(this->renderer());
    if (!renderer)
        return;

    if (isLengthAttribute) {
        renderer->setNeedsShapeUpdate();
        markForLayoutAndParentResourceInvalidation(renderer);
        return;
    }

    ASSERT_NOT_REACHED();
}
void SVGForeignObjectElement::svgAttributeChanged(
    const QualifiedName& attrName) {
  bool isWidthHeightAttribute =
      attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr;
  bool isXYAttribute =
      attrName == SVGNames::xAttr || attrName == SVGNames::yAttr;

  if (isXYAttribute || isWidthHeightAttribute) {
    SVGElement::InvalidationGuard invalidationGuard(this);

    invalidateSVGPresentationAttributeStyle();
    setNeedsStyleRecalc(
        LocalStyleChange,
        isWidthHeightAttribute
            ? StyleChangeReasonForTracing::create(
                  StyleChangeReason::SVGContainerSizeChange)
            : StyleChangeReasonForTracing::fromAttribute(attrName));

    updateRelativeLengthsInformation();
    if (LayoutObject* layoutObject = this->layoutObject())
      markForLayoutAndParentResourceInvalidation(layoutObject);

    return;
  }

  SVGGraphicsElement::svgAttributeChanged(attrName);
}
void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName)
{
    bool updateRelativeLengths = attrName == SVGNames::xAttr
                                 || attrName == SVGNames::yAttr
                                 || attrName == SVGNames::dxAttr
                                 || attrName == SVGNames::dyAttr;

    if (updateRelativeLengths)
        updateRelativeLengthsInformation();

    if (updateRelativeLengths || attrName == SVGNames::rotateAttr) {
        SVGElement::InvalidationGuard invalidationGuard(this);

        LayoutObject* layoutObject = this->layoutObject();
        if (!layoutObject)
            return;

        if (LayoutSVGText* textLayoutObject = LayoutSVGText::locateLayoutSVGTextAncestor(layoutObject))
            textLayoutObject->setNeedsPositioningValuesUpdate();
        markForLayoutAndParentResourceInvalidation(layoutObject);
        return;
    }

    SVGTextContentElement::svgAttributeChanged(attrName);
}
Beispiel #7
0
void SVGSVGElement::setViewSpec(SVGViewSpec* viewSpec) {
  // Even if the viewspec object itself doesn't change, it could still
  // have been mutated, so only treat a "no viewspec" -> "no viewspec"
  // transition as a no-op.
  if (!m_viewSpec && !viewSpec)
    return;
  m_viewSpec = viewSpec;
  if (LayoutObject* layoutObject = this->layoutObject())
    markForLayoutAndParentResourceInvalidation(layoutObject);
}
Beispiel #8
0
void SVGFEImageElement::notifyFinished(Resource*) {
  if (!isConnected())
    return;

  Element* parent = parentElement();
  if (!parent || !isSVGFilterElement(parent) || !parent->layoutObject())
    return;

  if (LayoutObject* layoutObject = this->layoutObject())
    markForLayoutAndParentResourceInvalidation(layoutObject);
}
Beispiel #9
0
void SVGFELightElement::childrenChanged(const ChildrenChange& change)
{
    SVGElement::childrenChanged(change);

    if (!change.byParser) {
        if (ContainerNode* parent = parentNode()) {
            LayoutObject* layoutObject = parent->layoutObject();
            if (layoutObject && layoutObject->isSVGResourceFilterPrimitive())
                markForLayoutAndParentResourceInvalidation(layoutObject);
        }
    }
}
void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
{
    bool updateRelativeLengthsOrViewBox = false;
    bool widthChanged = attrName == SVGNames::widthAttr;
    bool heightChanged = attrName == SVGNames::heightAttr;
    if (widthChanged || heightChanged
        || attrName == SVGNames::xAttr
        || attrName == SVGNames::yAttr) {
        updateRelativeLengthsOrViewBox = true;
        updateRelativeLengthsInformation();
        invalidateRelativeLengthClients();

        // At the SVG/HTML boundary (aka LayoutSVGRoot), the width and
        // height attributes can affect the replaced size so we need
        // to mark it for updating.
        //
        // FIXME: For width/height animated as XML attributes on SVG
        // roots, there is an attribute synchronization missing. See
        // http://crbug.com/364807
        if (widthChanged || heightChanged) {
            LayoutObject* layoutObject = this->layoutObject();
            if (layoutObject && layoutObject->isSVGRoot()) {
                invalidateSVGPresentationAttributeStyle();
                setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::SVGContainerSizeChange));
            }
        } else {
            invalidateSVGPresentationAttributeStyle();
            setNeedsStyleRecalc(LocalStyleChange,
                StyleChangeReasonForTracing::fromAttribute(attrName));
        }
    }

    if (SVGFitToViewBox::isKnownAttribute(attrName)) {
        updateRelativeLengthsOrViewBox = true;
        invalidateRelativeLengthClients();
        if (LayoutObject* object = layoutObject())
            object->setNeedsTransformUpdate();
    }

    if (updateRelativeLengthsOrViewBox
        || SVGZoomAndPan::isKnownAttribute(attrName)) {
        SVGElement::InvalidationGuard invalidationGuard(this);
        if (layoutObject())
            markForLayoutAndParentResourceInvalidation(layoutObject());
        return;
    }

    SVGGraphicsElement::svgAttributeChanged(attrName);
}
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
{
    if (attrName == SVGNames::xAttr
        || attrName == SVGNames::yAttr
        || attrName == SVGNames::widthAttr
        || attrName == SVGNames::heightAttr) {
        SVGElement::InvalidationGuard invalidationGuard(this);

        if (attrName == SVGNames::xAttr
            || attrName == SVGNames::yAttr) {
            invalidateSVGPresentationAttributeStyle();
            setNeedsStyleRecalc(LocalStyleChange,
                StyleChangeReasonForTracing::fromAttribute(attrName));
        }

        updateRelativeLengthsInformation();
        if (m_targetElementInstance) {
            ASSERT(m_targetElementInstance->correspondingElement());
            transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_targetElementInstance->correspondingElement());
        }

        LayoutObject* object = this->layoutObject();
        if (object)
            markForLayoutAndParentResourceInvalidation(object);
        return;
    }

    if (SVGURIReference::isKnownAttribute(attrName)) {
        SVGElement::InvalidationGuard invalidationGuard(this);
        if (isStructurallyExternal()) {
            KURL url = document().completeURL(hrefString());
            const KURL& existingURL = m_resource ? m_resource->url() : KURL();
            if (url.hasFragmentIdentifier() && !equalIgnoringFragmentIdentifier(url, existingURL)) {
                FetchRequest request(ResourceRequest(url), localName());
                setDocumentResource(DocumentResource::fetchSVGDocument(request, document().fetcher()));
            }
        } else {
            setDocumentResource(nullptr);
        }

        invalidateShadowTree();

        return;
    }

    SVGGraphicsElement::svgAttributeChanged(attrName);
}
void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
{
    if (attrName == SVGNames::x1Attr
        || attrName == SVGNames::y1Attr
        || attrName == SVGNames::x2Attr
        || attrName == SVGNames::y2Attr) {
        updateRelativeLengthsInformation();

        LayoutSVGShape* layoutObject = toLayoutSVGShape(this->layoutObject());
        if (!layoutObject)
            return;

        SVGElement::InvalidationGuard invalidationGuard(this);
        layoutObject->setNeedsShapeUpdate();
        markForLayoutAndParentResourceInvalidation(layoutObject);
        return;
    }

    SVGGeometryElement::svgAttributeChanged(attrName);
}
Beispiel #13
0
void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName) {
  if (attrName == SVGNames::rAttr || attrName == SVGNames::cxAttr ||
      attrName == SVGNames::cyAttr) {
    SVGElement::InvalidationGuard invalidationGuard(this);

    invalidateSVGPresentationAttributeStyle();
    setNeedsStyleRecalc(LocalStyleChange,
                        StyleChangeReasonForTracing::fromAttribute(attrName));
    updateRelativeLengthsInformation();

    LayoutSVGShape* layoutObject = toLayoutSVGShape(this->layoutObject());
    if (!layoutObject)
      return;

    layoutObject->setNeedsShapeUpdate();
    markForLayoutAndParentResourceInvalidation(layoutObject);
    return;
  }

  SVGGraphicsElement::svgAttributeChanged(attrName);
}
void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
{
    bool isLengthAttribute = attrName == SVGNames::xAttr
                             || attrName == SVGNames::yAttr
                             || attrName == SVGNames::widthAttr
                             || attrName == SVGNames::heightAttr;

    if (isLengthAttribute || attrName == SVGNames::preserveAspectRatioAttr) {
        SVGElement::InvalidationGuard invalidationGuard(this);

        if (isLengthAttribute) {
            invalidateSVGPresentationAttributeStyle();
            setNeedsStyleRecalc(LocalStyleChange,
                                StyleChangeReasonForTracing::fromAttribute(attrName));
            updateRelativeLengthsInformation();
        }

        LayoutObject* object = this->layoutObject();
        if (!object)
            return;

        // FIXME: if isLengthAttribute then we should avoid this
        // call if the viewport didn't change, however since we don't
        // have the computed style yet we can't use updateImageViewport.
        // See http://crbug.com/466200.
        markForLayoutAndParentResourceInvalidation(object);
        return;
    }

    if (SVGURIReference::isKnownAttribute(attrName)) {
        SVGElement::InvalidationGuard invalidationGuard(this);
        if (inDocument())
            imageLoader().updateFromElement(ImageLoader::UpdateIgnorePreviousError);
        else
            m_needsLoaderURIUpdate = true;
        return;
    }

    SVGGraphicsElement::svgAttributeChanged(attrName);
}
void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName)
{
    // Reattach so the isValid() check will be run again during layoutObject creation.
    if (SVGTests::isKnownAttribute(attrName)) {
        SVGElement::InvalidationGuard invalidationGuard(this);
        lazyReattachIfAttached();
        return;
    }

    if (attrName == SVGNames::transformAttr) {
        LayoutObject* object = layoutObject();
        if (!object)
            return;

        SVGElement::InvalidationGuard invalidationGuard(this);
        object->setNeedsTransformUpdate();
        markForLayoutAndParentResourceInvalidation(object);
        return;
    }

    SVGElement::svgAttributeChanged(attrName);
}
void SVGFilterPrimitiveStandardAttributes::invalidate()
{
    if (LayoutObject* primitiveLayoutObject = layoutObject())
        markForLayoutAndParentResourceInvalidation(primitiveLayoutObject);
}