예제 #1
0
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
{
    SVGStyledTransformableElement::svgAttributeChanged(attrName);

    bool isXYAttribute = attrName == SVGNames::xAttr || attrName == SVGNames::yAttr;
    bool isWidthHeightAttribute = attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr;

    if (isXYAttribute || isWidthHeightAttribute)
        updateRelativeLengthsInformation();

    if (SVGTests::handleAttributeChange(this, attrName))
        return;

    RenderObject* object = renderer();
    if (!object)
        return;

    if (SVGURIReference::isKnownAttribute(attrName)) {
        if (hasPendingResources()) {
            OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(document()->accessSVGExtensions()->removePendingResource(m_resourceId));
            ASSERT(!clients->isEmpty());

            const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
            for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
                ASSERT((*it)->hasPendingResources());
                (*it)->setHasPendingResources(false);
            }

            m_resourceId = String();
            setHasPendingResources(false);
        }

        invalidateShadowTree();
        return;
    }

    if (isXYAttribute) {
        updateContainerOffsets();
        return;
    }

    if (isWidthHeightAttribute) {
        updateContainerSizes();
        return;
    }

    // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree!
    if (SVGStyledElement::isKnownAttribute(attrName)) {
        setNeedsStyleRecalc();
        return;
    }

    if (SVGLangSpace::isKnownAttribute(attrName)
            || SVGExternalResourcesRequired::isKnownAttribute(attrName))
        invalidateShadowTree();
}
예제 #2
0
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
{
    SVGStyledTransformableElement::svgAttributeChanged(attrName);

    bool isXYAttribute = attrName == SVGNames::xAttr || attrName == SVGNames::yAttr;
    bool isWidthHeightAttribute = attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr;

    if (isXYAttribute || isWidthHeightAttribute)
        updateRelativeLengthsInformation();

    if (SVGTests::handleAttributeChange(this, attrName))
        return;

    RenderObject* object = renderer();
    if (!object)
        return;

    if (SVGURIReference::isKnownAttribute(attrName)) {
        if (m_isPendingResource) {
            document()->accessSVGExtensions()->removePendingResource(m_resourceId);
            m_resourceId = String();
            m_isPendingResource = false;
        }

        invalidateShadowTree();
        return;
    }

    if (isXYAttribute) {
        updateContainerOffsets();
        return;
    }

    if (isWidthHeightAttribute) {
        updateContainerSizes();
        return;
    }

    // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree!
    if (SVGStyledElement::isKnownAttribute(attrName)) {
        setNeedsStyleRecalc();
        return;
    }

    if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
        object->setNeedsTransformUpdate();
        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
        return;
    }

    if (SVGLangSpace::isKnownAttribute(attrName)
        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
        invalidateShadowTree();
}
예제 #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);
}
예제 #4
0
void SVGUseElement::buildPendingResource()
{
    // If we're called the first time (during shadow tree root creation from RenderSVGShadowTreeRootContainer)
    // we either determine that our target is available or not - then we add ourselves to the pending resource list
    // Once the pending resource appears, it will call buildPendingResource(), so we're called a second time.
    String id = SVGURIReference::getTarget(href());
    Element* targetElement = document()->getElementById(id);
    ASSERT(!m_targetElementInstance);

    if (!targetElement) {
        if (m_isPendingResource || id.isEmpty())
            return;

        m_isPendingResource = true;
        m_resourceId = id;
        document()->accessSVGExtensions()->addPendingResource(id, this);
        return;
    }

    if (m_isPendingResource) {
        ASSERT(!m_targetElementInstance);
        m_isPendingResource = false;    
        invalidateShadowTree();
    }
}
예제 #5
0
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
{
    SVGStyledTransformableElement::svgAttributeChanged(attrName);

    if (!renderer())
        return;

    if (SVGURIReference::isKnownAttribute(attrName)) {
        if (m_isPendingResource) {
            document()->accessSVGExtensions()->removePendingResource(m_resourceId);
            m_resourceId = String();
            m_isPendingResource = false;
        }

        invalidateShadowTree();
        return;
    }

    if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) {
        updateContainerOffsets();
        return;
    }

    if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) {
        updateContainerSizes();
        return;
    }

    // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree!
    if (SVGStyledElement::isKnownAttribute(attrName)) {
        setNeedsStyleRecalc();
        return;
    }

    if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
        renderer()->setNeedsTransformUpdate();
        renderer()->setNeedsLayout(true);
        return;
    }

    if (SVGTests::isKnownAttribute(attrName)
        || SVGLangSpace::isKnownAttribute(attrName)
        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
        invalidateShadowTree();
}
예제 #6
0
Node::InsertionNotificationRequest SVGUseElement::insertedInto(ContainerNode* rootParent)
{
    // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied.
    SVGGraphicsElement::insertedInto(rootParent);
    if (!rootParent->inDocument())
        return InsertionDone;
    ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document()));
    ASSERT(!hasPendingResources() || !isWellFormedDocument(&document()));
    invalidateShadowTree();
    return InsertionDone;
}
예제 #7
0
void SVGUseElement::notifyFinished(CachedResource* resource)
{
    if (!inDocument())
        return;

    invalidateShadowTree();
    if (resource->errorOccurred())
        dispatchEvent(Event::create(eventNames().errorEvent, false, false));
    else if (!resource->wasCanceled())
        SVGExternalResourcesRequired::dispatchLoadEvent(this);
}
예제 #8
0
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
{
    if (!isSupportedAttribute(attrName)) {
        SVGGraphicsElement::svgAttributeChanged(attrName);
        return;
    }

    SVGElementInstance::InvalidationGuard invalidationGuard(this);

    auto renderer = this->renderer();
    if (attrName == SVGNames::xAttr
        || attrName == SVGNames::yAttr
        || attrName == SVGNames::widthAttr
        || attrName == SVGNames::heightAttr) {
        updateRelativeLengthsInformation();
        if (renderer)
            RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
        return;
    }

    if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName))
        return;

    if (SVGURIReference::isKnownAttribute(attrName)) {
        bool isExternalReference = isExternalURIReference(href(), document());
        if (isExternalReference) {
            URL url = document().completeURL(href());
            if (url.hasFragmentIdentifier()) {
                CachedResourceRequest request(ResourceRequest(url.string()));
                request.setInitiator(this);
                setCachedDocument(document().cachedResourceLoader()->requestSVGDocument(request));
            }
        } else
            setCachedDocument(0);

        if (!m_wasInsertedByParser)
            buildPendingResource();

        return;
    }

    if (SVGLangSpace::isKnownAttribute(attrName)
        || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
        invalidateShadowTree();
        return;
    }

    ASSERT_NOT_REACHED();
}
예제 #9
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.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);
}
예제 #10
0
void SVGUseElement::notifyFinished(Resource* resource)
{
    if (!inDocument())
        return;

    invalidateShadowTree();
    if (resource->errorOccurred()) {
        dispatchEvent(Event::create(EventTypeNames::error));
    } else if (!resource->wasCanceled()) {
        if (m_haveFiredLoadEvent)
            return;
        if (!isStructurallyExternal())
            return;
        ASSERT(!m_haveFiredLoadEvent);
        m_haveFiredLoadEvent = true;
        svgUseLoadEventSender().dispatchEventSoon(this);
    }
}