| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library trydart.htmlToText; | 5 library trydart.htmlToText; |
| 6 | 6 |
| 7 import 'dart:math' show | 7 import 'dart:math' show |
| 8 max; | 8 max; |
| 9 | 9 |
| 10 import 'dart:html' show | 10 import 'dart:html' show |
| 11 Element, | 11 Element, |
| 12 Node, | 12 Node, |
| 13 NodeFilter, | 13 NodeFilter, |
| 14 ShadowRoot, | 14 ShadowRoot, |
| 15 Text, | 15 Text, |
| 16 TreeWalker; | 16 TreeWalker; |
| 17 | 17 |
| 18 import 'selection.dart' show | 18 import 'selection.dart' show |
| 19 TrySelection; | 19 TrySelection; |
| 20 | 20 |
| 21 /// Returns true if [node] is a block element, that is, not inline. | 21 /// Returns true if [node] is a block element, that is, not inline. |
| 22 bool isBlockElement(Node node) { | 22 bool isBlockElement(Node node) { |
| 23 if (node is! Element) return false; | 23 if (node is! Element) return false; |
| 24 Element element = node; | 24 Element element = node; |
| 25 |
| 26 // TODO(ahe): Remove this line by changing code completion to avoid using a |
| 27 // div element. |
| 28 if (element.classes.contains('dart-code-completion')) return false; |
| 29 |
| 25 return element.getComputedStyle().display != 'inline'; | 30 return element.getComputedStyle().display != 'inline'; |
| 26 } | 31 } |
| 27 | 32 |
| 28 /// Position [walker] at the last predecessor (that is, child of child of | 33 /// Position [walker] at the last predecessor (that is, child of child of |
| 29 /// child...) of [node]. The next call to walker.nextNode will return the first | 34 /// child...) of [node]. The next call to walker.nextNode will return the first |
| 30 /// node after [node]. | 35 /// node after [node]. |
| 31 void skip(Node node, TreeWalker walker) { | 36 void skip(Node node, TreeWalker walker) { |
| 32 if (walker.nextSibling() != null) { | 37 if (walker.nextSibling() != null) { |
| 33 walker.previousNode(); | 38 walker.previousNode(); |
| 34 return; | 39 return; |
| 35 } | 40 } |
| 36 for (Node current = walker.nextNode(); | 41 for (Node current = walker.nextNode(); |
| 37 current != null; | 42 current != null; |
| 38 current = walker.nextNode()) { | 43 current = walker.nextNode()) { |
| 39 if (!node.contains(current)) { | 44 if (!node.contains(current)) { |
| 40 walker.previousNode(); | 45 walker.previousNode(); |
| 41 return; | 46 return; |
| 42 } | 47 } |
| 43 } | 48 } |
| 44 } | 49 } |
| 45 | 50 |
| 46 /// Writes the text of [root] to [buffer]. Keeps track of [selection] and | 51 /// Writes the text of [root] to [buffer]. Keeps track of [selection] and |
| 47 /// returns the new anchorOffset from beginning of [buffer] or -1 if the | 52 /// returns the new anchorOffset from beginning of [buffer] or -1 if the |
| 48 /// selection isn't in [root]. | 53 /// selection isn't in [root]. |
| 49 int htmlToText(Node root, StringBuffer buffer, TrySelection selection) { | 54 int htmlToText(Node root, |
| 55 StringBuffer buffer, |
| 56 TrySelection selection, |
| 57 {bool treatRootAsInline: false}) { |
| 50 int selectionOffset = -1; | 58 int selectionOffset = -1; |
| 51 TreeWalker walker = new TreeWalker(root, NodeFilter.SHOW_ALL); | 59 TreeWalker walker = new TreeWalker(root, NodeFilter.SHOW_ALL); |
| 52 | 60 |
| 53 for (Node node = root; node != null; node = walker.nextNode()) { | 61 for (Node node = root; node != null; node = walker.nextNode()) { |
| 54 switch (node.nodeType) { | 62 switch (node.nodeType) { |
| 55 case Node.CDATA_SECTION_NODE: | 63 case Node.CDATA_SECTION_NODE: |
| 56 case Node.TEXT_NODE: | 64 case Node.TEXT_NODE: |
| 57 if (selection.anchorNode == node) { | 65 if (selection.anchorNode == node) { |
| 58 selectionOffset = selection.anchorOffset + buffer.length; | 66 selectionOffset = selection.anchorOffset + buffer.length; |
| 59 } | 67 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 70 buffer.write('\n'); | 78 buffer.write('\n'); |
| 71 } else if (node != root && isBlockElement(node)) { | 79 } else if (node != root && isBlockElement(node)) { |
| 72 selectionOffset = | 80 selectionOffset = |
| 73 max(selectionOffset, htmlToText(node, buffer, selection)); | 81 max(selectionOffset, htmlToText(node, buffer, selection)); |
| 74 skip(node, walker); | 82 skip(node, walker); |
| 75 } | 83 } |
| 76 break; | 84 break; |
| 77 } | 85 } |
| 78 } | 86 } |
| 79 | 87 |
| 80 if (isBlockElement(root)) { | 88 if (!treatRootAsInline && isBlockElement(root)) { |
| 81 buffer.write('\n'); | 89 buffer.write('\n'); |
| 82 } | 90 } |
| 83 | 91 |
| 84 return selectionOffset; | 92 return selectionOffset; |
| 85 } | 93 } |
| OLD | NEW |