Chromium Code Reviews| 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.htmlToText; | |
| 6 | |
| 7 import 'dart:math' show | |
| 8 max; | |
|
kasperl
2014/03/25 14:41:22
So you use show on the (small) import of dart:math
ahe
2014/03/26 10:02:12
Yes. Generally, I have allowed myself to import da
| |
| 9 | |
| 10 import 'dart:html'; | |
| 11 | |
| 12 /// Returns true if [node] is a block element, that is, not inline. | |
| 13 bool isBlockElement(Node node) { | |
| 14 if (node is! Element) return false; | |
| 15 Element element = node; | |
| 16 return element.getComputedStyle().display != 'inline'; | |
| 17 } | |
| 18 | |
| 19 /// Position [walker] at the last predecessor (that is, child of child of | |
| 20 /// child...) of [node]. The next call to walker.nextNode will return the first | |
| 21 /// node after [node]. | |
| 22 void skip(Node node, TreeWalker walker) { | |
| 23 if (walker.nextSibling() != null) { | |
| 24 walker.previousNode(); | |
| 25 return; | |
| 26 } | |
| 27 for (Node current = walker.nextNode(); | |
| 28 current != null; | |
| 29 current = walker.nextNode()) { | |
| 30 if (!node.contains(current)) { | |
| 31 walker.previousNode(); | |
| 32 return; | |
| 33 } | |
| 34 } | |
| 35 } | |
| 36 | |
| 37 /// Writes the text of [root] to [buffer]. Keeps track of [selection] and | |
| 38 /// returns the new anchorOffset from beginning of [buffer] or -1 if the | |
| 39 /// selection isn't in [root]. | |
| 40 int htmlToText(Node root, StringBuffer buffer, Selection selection) { | |
| 41 int selectionOffset = -1; | |
| 42 TreeWalker walker = new TreeWalker(root, NodeFilter.SHOW_ALL); | |
| 43 | |
| 44 for (Node node = root; node != null; node = walker.nextNode()) { | |
| 45 | |
|
kasperl
2014/03/25 14:41:22
Remove newline?
ahe
2014/03/26 10:02:12
Done.
| |
| 46 switch (node.nodeType) { | |
| 47 case Node.CDATA_SECTION_NODE: | |
| 48 case Node.TEXT_NODE: | |
| 49 if (selection.isCollapsed && selection.anchorNode == node) { | |
| 50 selectionOffset = selection.anchorOffset + buffer.length; | |
| 51 } | |
| 52 Text text = node; | |
| 53 buffer.write(text.data.replaceAll('\xA0', ' ')); | |
| 54 break; | |
| 55 | |
| 56 default: | |
| 57 if (node.nodeName == 'BR') { | |
| 58 buffer.write('\n'); | |
| 59 } else if (node != root && isBlockElement(node)) { | |
| 60 selectionOffset = | |
| 61 max(htmlToText(node, buffer, selection), selectionOffset); | |
|
kasperl
2014/03/25 14:41:22
I'd put selectorOffset as the first argument to ma
ahe
2014/03/26 10:02:12
Done. Much nicer :-)
| |
| 62 skip(node, walker); | |
| 63 } | |
| 64 break; | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 if (isBlockElement(root)) { | |
| 69 buffer.write('\n'); | |
| 70 } | |
| 71 | |
| 72 return selectionOffset; | |
| 73 } | |
| OLD | NEW |