Mercurial > MadButterfly
comparison pyink/unlink_clone.py @ 1299:6949e2b6cae2
Add unlink clone checker.
- Monitor changes of DOM-tree of the document
- Unlinking a clone is actually removing the clone and copying nodes
from the source.
- Copy value of ID of a node to saved_id to track source of copy
nodes.
- For a new node with 'saved_id' is a copy of another node.
- Copy vulae of 'saved_id' to 'ns0:duplicate-src' to keep the source
- Change value of 'saved_id' to the value of ID of the node for
later copying.
- For a new node without 'saved_id' is not a copy of another node.
- only set 'saved_id' to the value of its ID.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Sun, 16 Jan 2011 16:13:37 +0800 |
parents | |
children | 2a35a1cb6cdf |
comparison
equal
deleted
inserted
replaced
1298:2a5da457474d | 1299:6949e2b6cae2 |
---|---|
1 import dom_event | |
2 from data_monitor import data_monitor | |
3 | |
4 class unlink_clone_checker(object): | |
5 __metaclass__ = data_monitor | |
6 | |
7 _no_change_attrs = ('ns0:duplicate-src', 'saved_id') | |
8 | |
9 def __init__(self, domview_ui): | |
10 self._domviewui = domview_ui | |
11 self._locker = domview_ui | |
12 self._doc = None | |
13 self._root = None | |
14 pass | |
15 | |
16 def _start_check(self): | |
17 doc = self._doc | |
18 dom_event.addEventListener(doc, 'DOMNodeInserted', | |
19 self.do_insert_node, None) | |
20 dom_event.addEventListener(doc, 'DOMAttrModified', | |
21 self.do_attr_modified, None) | |
22 pass | |
23 | |
24 def handle_doc_root(self, doc, root): | |
25 self._doc = doc | |
26 self._root = root | |
27 | |
28 self._start_check() | |
29 pass | |
30 | |
31 def _handle_unlinked_or_copied_nodes(self, node, child): | |
32 try: | |
33 saved_id = child.getAttribute('saved_id') | |
34 except: # Skip it for losting saved_id | |
35 pass | |
36 else: | |
37 child.setAttribute('ns0:duplicate-src', saved_id) | |
38 pass | |
39 | |
40 try: | |
41 child_id = child.getAttribute('id') | |
42 except: # still have no ID. | |
43 pass # Assign saved_id later with attr | |
44 # modified event. | |
45 else: | |
46 child.setAttribute('saved_id', child_id) | |
47 pass | |
48 pass | |
49 | |
50 def _handle_new_nodes(self, node, child): | |
51 if child.name() == 'svg:use': | |
52 return | |
53 | |
54 try: | |
55 child_id = child.getAttribute('id') | |
56 except KeyError: | |
57 return | |
58 child.setAttribute('saved_id', child_id) | |
59 pass | |
60 | |
61 ## \brief Check inserted node recurisvely. | |
62 # | |
63 # Travel the tree in post-order. | |
64 # | |
65 def _handle_insert_node_recursive(self, node, child): | |
66 # | |
67 # Traveling forest of children. | |
68 # | |
69 for cchild in child.childList(): | |
70 self._handle_insert_node_recursive(child, cchild) | |
71 pass | |
72 | |
73 # | |
74 # Visit the node | |
75 # | |
76 try: | |
77 child_id = child.getAttribute('saved_id') | |
78 except KeyError: # have no saved_id | |
79 pass | |
80 else: | |
81 self._handle_unlinked_or_copied_nodes(node, child) | |
82 return | |
83 | |
84 # have no saved_id | |
85 self._handle_new_nodes(node, child) | |
86 pass | |
87 | |
88 def do_insert_node(self, node, child): | |
89 self._handle_insert_node_recursive(node, child) | |
90 pass | |
91 | |
92 def do_attr_modified(self, node, name, old_value, new_value): | |
93 if name == 'id' and node.name() != 'svg:use': | |
94 # | |
95 # The ID of a node may not be assigned when it being | |
96 # inserted, and be assigned later. So, we checking | |
97 # attribute modification event to assign value of | |
98 # saved_id. | |
99 # | |
100 node.setAttribute('saved_id', new_value) | |
101 elif old_value and (name in self._no_change_attrs): | |
102 # | |
103 # Restore to old value for attributes that is not allowed | |
104 # to be changed by the user. | |
105 # | |
106 node.setAttribute(name, old_value) | |
107 pass | |
108 pass | |
109 pass |