| Index: third_party/WebKit/Source/core/svg/SVGElementProxy.cpp
|
| diff --git a/third_party/WebKit/Source/core/svg/SVGElementProxy.cpp b/third_party/WebKit/Source/core/svg/SVGElementProxy.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8e2e83812ff99c12697b5c33e12f7d09a483853c
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/core/svg/SVGElementProxy.cpp
|
| @@ -0,0 +1,133 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "core/svg/SVGElementProxy.h"
|
| +
|
| +#include "core/fetch/FetchInitiatorTypeNames.h"
|
| +#include "core/fetch/FetchRequest.h"
|
| +#include "core/fetch/ResourceFetcher.h"
|
| +#include "core/svg/SVGDocumentExtensions.h"
|
| +#include "core/svg/SVGElement.h"
|
| +#include "core/svg/SVGFilterElement.h"
|
| +#include "core/svg/SVGResourceClient.h"
|
| +
|
| +namespace blink {
|
| +
|
| +SVGElementProxy::SVGElementProxy(const AtomicString& id)
|
| + : m_id(id), m_generation(0), m_isLocal(true) {}
|
| +
|
| +SVGElementProxy::SVGElementProxy(const String& url, const AtomicString& id)
|
| + : m_id(id), m_url(url), m_generation(0), m_isLocal(false) {}
|
| +
|
| +SVGElementProxy::~SVGElementProxy() {}
|
| +
|
| +void SVGElementProxy::addClient(SVGResourceClient* client) {
|
| + m_clients.add(client);
|
| +}
|
| +
|
| +void SVGElementProxy::removeClient(SVGResourceClient* client) {
|
| + m_clients.remove(client);
|
| +}
|
| +
|
| +void SVGElementProxy::resolve(Document& document) {
|
| + if (m_isLocal || m_url.isEmpty())
|
| + return;
|
| + FetchRequest request(ResourceRequest(m_url), FetchInitiatorTypeNames::css);
|
| + m_document = DocumentResource::fetchSVGDocument(request, document.fetcher());
|
| + m_url = String();
|
| + if (m_document) {
|
| + m_document->addClient(this);
|
| + ThreadState::current()->registerPreFinalizer(this);
|
| + }
|
| +}
|
| +
|
| +TreeScope* SVGElementProxy::treeScopeForLookup(TreeScope& treeScope) const {
|
| + if (m_isLocal)
|
| + return &treeScope;
|
| + if (!m_document)
|
| + return nullptr;
|
| + return m_document->document();
|
| +}
|
| +
|
| +SVGElement* SVGElementProxy::element(TreeScope& treeScope) {
|
| + // An empty id will never be a valid element reference.
|
| + if (m_id.isEmpty())
|
| + return nullptr;
|
| + TreeScope* lookupScope = treeScopeForLookup(treeScope);
|
| + if (!lookupScope)
|
| + return nullptr;
|
| + if (Element* targetElement = lookupScope->getElementById(m_id)) {
|
| + if (isSVGFilterElement(*targetElement)) {
|
| + toSVGFilterElement(*targetElement).elementProxySet().add(*this);
|
| + return toSVGElement(targetElement);
|
| + }
|
| + }
|
| + // For external references we wait for the document to finish loading. If the
|
| + // reference is not valid then it will never be (because the document will
|
| + // not mutate.)
|
| + if (!m_isLocal)
|
| + return nullptr;
|
| + // If the lookup fails for some reason (no element with said 'id' or no
|
| + // element of the required type), attach the proxy to SVGDocumentExtensions.
|
| + // It will then send notifications when an element with the associated id is
|
| + // added to the tree etc.
|
| + treeScope.document().accessSVGExtensions().attachPendingProxy(*this);
|
| + return nullptr;
|
| +}
|
| +
|
| +void SVGElementProxy::contentChanged() {
|
| + HeapVector<Member<SVGResourceClient>> clients;
|
| + copyToVector(m_clients, clients);
|
| + for (SVGResourceClient* client : clients)
|
| + client->resourceContentChanged();
|
| +}
|
| +
|
| +void SVGElementProxy::referenceChanged() {
|
| + incrementGeneration();
|
| + HeapVector<Member<SVGResourceClient>> clients;
|
| + copyToVector(m_clients, clients);
|
| + for (SVGResourceClient* client : clients)
|
| + client->resourceReferenceChanged();
|
| +}
|
| +
|
| +void SVGElementProxy::notifyFinished(Resource*) {
|
| + referenceChanged();
|
| +}
|
| +
|
| +void SVGElementProxy::detachDocumentClient() {
|
| + m_document->removeClient(this);
|
| + m_document = nullptr;
|
| +}
|
| +
|
| +DEFINE_TRACE(SVGElementProxy) {
|
| + visitor->trace(m_clients);
|
| + visitor->trace(m_document);
|
| + DocumentResourceClient::trace(visitor);
|
| +}
|
| +
|
| +void SVGElementProxySet::add(SVGElementProxy& elementProxy) {
|
| + m_elementProxies.add(&elementProxy);
|
| +}
|
| +
|
| +bool SVGElementProxySet::isEmpty() const {
|
| + return m_elementProxies.isEmpty();
|
| +}
|
| +
|
| +void SVGElementProxySet::notifyContentChanged() {
|
| + for (SVGElementProxy* proxy : m_elementProxies)
|
| + proxy->contentChanged();
|
| +}
|
| +
|
| +void SVGElementProxySet::invalidateProxies() {
|
| + ProxySet elementProxies;
|
| + elementProxies.swap(m_elementProxies);
|
| + for (SVGElementProxy* proxy : elementProxies)
|
| + proxy->referenceChanged();
|
| +}
|
| +
|
| +DEFINE_TRACE(SVGElementProxySet) {
|
| + visitor->trace(m_elementProxies);
|
| +}
|
| +
|
| +} // namespace blink
|
|
|