da5258c42a
BUG=dartbug.com/20017 R=ahe@google.com Review URL: https://codereview.chromium.org//408783002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@39394 260f80e4-7a28-3924-810f-c04153c831b5
106 lines
2.8 KiB
Dart
106 lines
2.8 KiB
Dart
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
library trydart.shadow_root;
|
|
|
|
import 'dart:html';
|
|
|
|
import 'selection.dart' show
|
|
TrySelection;
|
|
|
|
import 'html_to_text.dart' show
|
|
htmlToText;
|
|
|
|
const int WALKER_NEXT = 0;
|
|
const int WALKER_RETURN = 1;
|
|
const int WALKER_SKIP_NODE = 2;
|
|
|
|
void setShadowRoot(Element node, text) {
|
|
if (text is String) {
|
|
text = new Text(text);
|
|
}
|
|
getShadowRoot(node)
|
|
..nodes.clear()
|
|
..append(text);
|
|
}
|
|
|
|
|
|
/* ShadowRoot or Element */ getShadowRoot(Element node) {
|
|
if (ShadowRoot.supported) {
|
|
ShadowRoot root = node.shadowRoot;
|
|
return root != null ? root : node.createShadowRoot();
|
|
} else {
|
|
Element root = node.querySelector('[try-dart-shadow-root]');
|
|
if (root == null) {
|
|
root = new SpanElement()
|
|
..setAttribute('try-dart-shadow-root', '');
|
|
node.append(root);
|
|
}
|
|
return root;
|
|
}
|
|
}
|
|
|
|
String getText(Element node) {
|
|
if (ShadowRoot.supported) return node.text;
|
|
StringBuffer buffer = new StringBuffer();
|
|
htmlToText(
|
|
node, buffer, new TrySelection.empty(node), treatRootAsInline: true);
|
|
return '$buffer';
|
|
}
|
|
|
|
/// Element.contains(n) doesn't work when n is node(Text) in IE,
|
|
/// so this is a brute-force implementation of contains.
|
|
bool containsNode(parent, child) {
|
|
var p = child;
|
|
while (p != null && p != parent) {
|
|
p = p.parentNode;
|
|
}
|
|
return p != null;
|
|
}
|
|
|
|
/// Position [walker] at the last predecessor (that is, child of child of
|
|
/// child...) of [node]. The next call to walker.nextNode will return the first
|
|
/// node after [node].
|
|
void skip(Node node, TreeWalker walker) {
|
|
if (walker.nextSibling() != null) {
|
|
walker.previousNode();
|
|
return;
|
|
}
|
|
for (Node current = walker.nextNode();
|
|
current != null;
|
|
current = walker.nextNode()) {
|
|
if (!containsNode(node, current)) {
|
|
walker.previousNode();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Call [f] on each node in [root] in same order as [TreeWalker]. Skip any
|
|
/// nodes used to implement shadow root polyfill.
|
|
void walkNodes(Node root, int f(Node node)) {
|
|
TreeWalker walker = new TreeWalker(root, NodeFilter.SHOW_ALL);
|
|
|
|
for (Node node = root; node != null; node = walker.nextNode()) {
|
|
if (!ShadowRoot.supported &&
|
|
node is Element &&
|
|
node.getAttribute('try-dart-shadow-root') != null) {
|
|
skip(node, walker);
|
|
} else {
|
|
int action = f(node);
|
|
switch (action) {
|
|
case WALKER_RETURN:
|
|
return;
|
|
case WALKER_SKIP_NODE:
|
|
skip(node, walker);
|
|
break;
|
|
case WALKER_NEXT:
|
|
break;
|
|
default:
|
|
throw 'Unexpected action returned from [f]: $action';
|
|
}
|
|
}
|
|
}
|
|
}
|