@@ -59,11 +59,7 @@ class ProxyTag(ProxyToolkitObject):
59
59
#: Reference to the declaration
60
60
declaration = ForwardTyped (lambda : Tag )
61
61
62
- #: A cached reference to the root element.
63
- #: WARNING: If the root is changed this becomes invalid
64
- root = ForwardTyped (lambda : ProxyTag )
65
-
66
- def xpath (self , query : str , ** kwargs ) -> Generator [ProxyToolkitObject , None , None ]:
62
+ def xpath (self , query : str , ** kwargs ) -> Generator ["ProxyTag" , None , None ]:
67
63
"""Perform an xpath lookup on the node"""
68
64
raise NotImplementedError
69
65
@@ -189,18 +185,15 @@ def _update_proxy(self, change: ChangeDict):
189
185
handler (value )
190
186
else :
191
187
proxy .set_attribute (name , value )
192
- root = proxy .root
193
- if root is not None and root .rendered :
194
- self ._notify_modified (
195
- root .declaration ,
196
- {
197
- "id" : self .id ,
198
- "type" : change ["type" ],
199
- "name" : name ,
200
- "value" : value ,
201
- "oldvalue" : change ["oldvalue" ],
202
- },
203
- )
188
+ self ._notify_modified (
189
+ {
190
+ "id" : self .id ,
191
+ "type" : change ["type" ],
192
+ "name" : name ,
193
+ "value" : value ,
194
+ "oldvalue" : change ["oldvalue" ],
195
+ },
196
+ )
204
197
205
198
# =========================================================================
206
199
# Object API
@@ -209,32 +202,23 @@ def _update_proxy(self, change: ChangeDict):
209
202
def child_added (self , child : Declarative ):
210
203
super ().child_added (child )
211
204
if self .proxy_is_active and isinstance (child , Tag ):
212
- proxy = self .proxy
213
- assert proxy is not None
214
- root = proxy .root
215
- assert root is not None
216
- if root .rendered :
217
- self ._notify_modified (
218
- root .declaration ,
219
- {
220
- "id" : self .id ,
221
- "type" : "added" ,
222
- "name" : "children" ,
223
- "value" : child .render (),
224
- "index" : self ._child_index (child ),
225
- },
226
- )
205
+ self ._notify_modified (
206
+ {
207
+ "id" : self .id ,
208
+ "type" : "added" ,
209
+ "name" : "children" ,
210
+ "value" : child .render (),
211
+ "index" : self ._child_index (child ),
212
+ },
213
+ )
227
214
228
215
def child_moved (self , child : Declarative ):
229
216
super ().child_moved (child )
230
217
if self .proxy_is_active and isinstance (child , Tag ):
231
218
proxy = self .proxy
232
219
assert proxy is not None
233
- root = proxy .root
234
- assert root is not None
235
- if root .rendered and proxy .child_moved (child .proxy ):
220
+ if proxy .child_moved (child .proxy ):
236
221
self ._notify_modified (
237
- root .declaration ,
238
222
{
239
223
"id" : self .id ,
240
224
"type" : "moved" ,
@@ -252,28 +236,26 @@ def child_removed(self, child: Declarative):
252
236
"""
253
237
super ().child_removed (child )
254
238
if self .proxy_is_active and isinstance (child , Tag ):
255
- proxy = self .proxy
256
- assert proxy is not None
257
- root = proxy .root
258
- assert root is not None
259
- if root .rendered :
260
- self ._notify_modified (
261
- root .declaration ,
262
- {
263
- "id" : self .id ,
264
- "type" : "removed" ,
265
- "name" : "children" ,
266
- "value" : child .id ,
267
- },
268
- )
269
-
270
- def _notify_modified (self , root : Optional [Tag ], change : dict [str , Any ]):
239
+ self ._notify_modified (
240
+ {
241
+ "id" : self .id ,
242
+ "type" : "removed" ,
243
+ "name" : "children" ,
244
+ "value" : child .id ,
245
+ },
246
+ )
247
+
248
+ def _notify_modified (self , change : dict [str , Any ]):
271
249
"""Trigger a modified event on the root node. Subclasses may override
272
250
this to update change parameters if needed.
273
251
274
252
"""
275
- if root is not None :
276
- root .modified (change )
253
+ root = self .root_object ()
254
+ if isinstance (root , Html ):
255
+ proxy = root .proxy
256
+ assert proxy is not None
257
+ if proxy .rendered :
258
+ root .modified (change )
277
259
278
260
def _child_index (self , child : Tag ) -> int :
279
261
"""Find the index of the child ignoring any pattern nodes"""
@@ -282,7 +264,25 @@ def _child_index(self, child: Tag) -> int:
282
264
# =========================================================================
283
265
# Tag API
284
266
# =========================================================================
285
- def xpath (self , query : str , ** kwargs ) -> list [Tag ]:
267
+ def find_by_id (self , id : str ) -> Optional [Tag ]:
268
+ """Find a child node with the given id.
269
+
270
+ Parameters
271
+ ----------
272
+ id: str
273
+ The id to look for.
274
+
275
+ Returns
276
+ -------
277
+ results: Optional[Tag]
278
+ The first node with the given id or None.
279
+
280
+ """
281
+ for child in self .traverse ():
282
+ if isinstance (child , Tag ) and child .id == id :
283
+ return child
284
+
285
+ def xpath (self , query : str , ** kwargs ) -> list [Tag ,...]:
286
286
"""Find nodes matching the given xpath query
287
287
288
288
Parameters
@@ -300,7 +300,7 @@ def xpath(self, query: str, **kwargs) -> list[Tag]:
300
300
"""
301
301
proxy = self .proxy
302
302
assert proxy is not None
303
- return [n . declaration for n in proxy .xpath (query , ** kwargs )]
303
+ return [n for n in proxy .xpath (query , ** kwargs )]
304
304
305
305
def prepare (self , ** kwargs : dict [str , Any ]):
306
306
"""Prepare this node for rendering.
0 commit comments