File: SVGElementProxy.h

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (138 lines) | stat: -rw-r--r-- 5,071 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// 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.

#ifndef SVGElementProxy_h
#define SVGElementProxy_h

#include "core/loader/resource/DocumentResource.h"
#include "platform/heap/Handle.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/WTFString.h"

namespace blink {

class Document;
class SVGElement;
class SVGResourceClient;
class TreeScope;

// A proxy to an SVGElement. Allows access to an element with a certain 'id',
// and provides its clients with notifications when the proxied element
// changes.
//
// SVGElements can be referenced using CSS, for example like:
//
//   filter: url(#baz);
//
//    or
//
//   filter: url(foo.com/bar.svg#baz);
//
// SVGElementProxy provide a mechanism to persistently reference an SVGElement
// in such cases - regardless of if the proxied element reside in the same
// document (read: tree scope) or in an external (resource) document. Loading
// events related to external documents case needs be handled by the clients
// (SVGResourceClient's default implementation does this.)
//
// The proxy uses an 'id' (c.f getElementById) to determine which element to
// proxy. The id is looked up in the TreeScope provided by the client for a
// same-document reference and in the TreeScope of the Document for a external
// document reference.
//
// For same document references, the proxy will track changes that could affect
// the 'id' lookup, to handle elements being added, removed or having their
// 'id' mutated. (This does not apply for the external document case because
// it's assumed they will not mutate after load, due to scripts not being run
// etc.)
//
// SVGElementProxys are created by CSSURIValue, and have SVGResourceClients as
// a means to deliver change notifications. Clients that are interested in
// change notifications hence need to register a SVGResourceClient with the
// proxy. Most commonly this registration would take place when the
// ComputedStyle changes.
//
// Registration of a client does not establish a link to the proxied element
// right away. That is instead deferred until findElement(...) is called on the
// SVGElementProxy. At this point, the proxy will be registered with the
// element if the lookup is successful. (For external references lookups will
// not be registered, per the same assumption as mentioned above.)
//
// As content is mutated, clients will get notified via the proxied element
// which in turn will notify all registered proxies, which will notify all
// registered clients.
//
// <event> -> SVG...Element -> SVGElementProxy(0..N) -> SVGResourceClient(0..N)
//
class SVGElementProxy : public GarbageCollectedFinalized<SVGElementProxy> {
 public:
  // Create a proxy to an element in the same document. (See also
  // SVGURLReferenceResolver and the definition of 'local url'.)
  static SVGElementProxy* create(const AtomicString& id) {
    return new SVGElementProxy(id);
  }

  // Create a proxy to an element in a different document (indicated by |url|.)
  static SVGElementProxy* create(const String& url, const AtomicString& id) {
    return new SVGElementProxy(url, id);
  }
  virtual ~SVGElementProxy();

  void addClient(SVGResourceClient*);
  void removeClient(SVGResourceClient*);

  // Resolve a potentially external document reference.
  void resolve(Document&);

  // Returns the proxied element, or null if the proxy is invalid.
  SVGElement* findElement(TreeScope&);

  // Notify the proxy that the structure of the subtree rooted at the proxied
  // element has mutated. This should generally only be called via a proxy set.
  void contentChanged(TreeScope&);

  const AtomicString& id() const { return m_id; }

  DECLARE_VIRTUAL_TRACE();

 private:
  explicit SVGElementProxy(const AtomicString&);
  SVGElementProxy(const String&, const AtomicString&);

  TreeScope* treeScopeForLookup(TreeScope&) const;

  class IdObserver;

  HeapHashMap<Member<SVGResourceClient>, Member<IdObserver>> m_clients;
  HeapHashMap<Member<TreeScope>, Member<IdObserver>> m_observers;
  Member<DocumentResource> m_document;
  AtomicString m_id;
  // URL for resolving references to external resource documents. Contains an
  // absolute URL to the resource to load. Cleared when a load has been
  // initiated. Ignored if m_isLocal is true.
  String m_url;
  bool m_isLocal;
};

// Collection of SVGElementProxys. This is hosted by elements that can be
// subject to proxies (see SVGElement::elementProxySet), and is mainly a helper
// for dealing with the many-to-one structure of SVGElementProxy.
class SVGElementProxySet : public GarbageCollected<SVGElementProxySet> {
 public:
  void add(SVGElementProxy&);
  bool isEmpty() const;

  // Notify proxy clients that the (content of the) proxied element has
  // changed.
  void notifyContentChanged(TreeScope&);

  DECLARE_TRACE();

 private:
  using ProxySet = HeapHashSet<WeakMember<SVGElementProxy>>;
  ProxySet m_elementProxies;
};

}  // namespace blink

#endif  // SVGElementProxy_h