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