OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library trydart.shadow_root; | |
6 | |
7 import 'dart:html'; | |
8 | |
9 import 'selection.dart' show | |
10 TrySelection; | |
11 | |
12 import 'html_to_text.dart' show | |
13 htmlToText; | |
14 | |
15 const int WALKER_NEXT = 0; | |
16 const int WALKER_RETURN = 1; | |
17 const int WALKER_SKIP_NODE = 2; | |
18 | |
19 void setShadowRoot(Element node, text) { | |
20 if (text is String) { | |
21 text = new Text(text); | |
22 } | |
23 getShadowRoot(node) | |
24 ..nodes.clear() | |
25 ..append(text); | |
26 } | |
27 | |
28 | |
29 /* ShadowRoot or Element */ getShadowRoot(Element node) { | |
30 if (ShadowRoot.supported) { | |
31 ShadowRoot root = node.shadowRoot; | |
32 return root != null ? root : node.createShadowRoot(); | |
33 } else { | |
34 Element root = node.querySelector('[try-dart-shadow-root]'); | |
35 if (root == null) { | |
36 root = new SpanElement() | |
37 ..setAttribute('try-dart-shadow-root', ''); | |
38 node.append(root); | |
39 } | |
40 return root; | |
41 } | |
42 } | |
43 | |
44 String getText(Element node) { | |
45 if (ShadowRoot.supported) return node.text; | |
46 StringBuffer buffer = new StringBuffer(); | |
47 htmlToText( | |
48 node, buffer, new TrySelection.empty(node), treatRootAsInline: true); | |
49 return '$buffer'; | |
50 } | |
51 | |
52 /// Element.contains(n) doesn't work when n is node(Text) in IE, | |
53 /// so this is a brute-force implementation of contains. | |
54 bool containsNode(parent, child) { | |
55 var p = child; | |
56 while (p != null && p != parent) { | |
57 p = p.parentNode; | |
58 } | |
59 return p != null; | |
60 } | |
61 | |
62 /// Position [walker] at the last predecessor (that is, child of child of | |
63 /// child...) of [node]. The next call to walker.nextNode will return the first | |
64 /// node after [node]. | |
65 void skip(Node node, TreeWalker walker) { | |
66 if (walker.nextSibling() != null) { | |
67 walker.previousNode(); | |
68 return; | |
69 } | |
70 for (Node current = walker.nextNode(); | |
71 current != null; | |
72 current = walker.nextNode()) { | |
73 if (!containsNode(node, current)) { | |
74 walker.previousNode(); | |
75 return; | |
76 } | |
77 } | |
78 } | |
79 | |
80 /// Call [f] on each node in [root] in same order as [TreeWalker]. Skip any | |
81 /// nodes used to implement shadow root polyfill. | |
82 void walkNodes(Node root, int f(Node node)) { | |
83 TreeWalker walker = new TreeWalker(root, NodeFilter.SHOW_ALL); | |
84 | |
85 for (Node node = root; node != null; node = walker.nextNode()) { | |
86 if (!ShadowRoot.supported && | |
87 node is Element && | |
88 node.getAttribute('try-dart-shadow-root') != null) { | |
89 skip(node, walker); | |
90 } else { | |
91 int action = f(node); | |
92 switch (action) { | |
93 case WALKER_RETURN: | |
94 return; | |
95 case WALKER_SKIP_NODE: | |
96 skip(node, walker); | |
97 break; | |
98 case WALKER_NEXT: | |
99 break; | |
100 default: | |
101 throw 'Unexpected action returned from [f]: $action'; | |
102 } | |
103 } | |
104 } | |
105 } | |
OLD | NEW |