| 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.interaction_manager; | 5 library trydart.interaction_manager; |
| 6 | 6 |
| 7 import 'dart:html'; | 7 import 'dart:html'; |
| 8 | 8 |
| 9 import 'dart:convert' show | 9 import 'dart:convert' show |
| 10 JSON; | 10 JSON; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 outputDiv; | 33 outputDiv; |
| 34 | 34 |
| 35 import 'decoration.dart' show | 35 import 'decoration.dart' show |
| 36 CodeCompletionDecoration, | 36 CodeCompletionDecoration, |
| 37 Decoration, | 37 Decoration, |
| 38 DiagnosticDecoration, | 38 DiagnosticDecoration, |
| 39 error, | 39 error, |
| 40 info, | 40 info, |
| 41 warning; | 41 warning; |
| 42 | 42 |
| 43 import 'html_to_text.dart' show |
| 44 htmlToText; |
| 43 import 'editor.dart' as editor; | 45 import 'editor.dart' as editor; |
| 44 | 46 |
| 45 import 'mock.dart' as mock; | 47 import 'mock.dart' as mock; |
| 46 | 48 |
| 47 import 'settings.dart' as settings; | 49 import 'settings.dart' as settings; |
| 48 | 50 |
| 49 /** | 51 /** |
| 50 * UI interaction manager for the entire application. | 52 * UI interaction manager for the entire application. |
| 51 */ | 53 */ |
| 52 abstract class InteractionManager { | 54 abstract class InteractionManager { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 print('onMutation'); | 168 print('onMutation'); |
| 167 | 169 |
| 168 for (String query in const ['a.diagnostic>span', | 170 for (String query in const ['a.diagnostic>span', |
| 169 '.dart-code-completion', | 171 '.dart-code-completion', |
| 170 '.hazed-suggestion']) { | 172 '.hazed-suggestion']) { |
| 171 for (Element element in inputPre.querySelectorAll(query)) { | 173 for (Element element in inputPre.querySelectorAll(query)) { |
| 172 element.remove(); | 174 element.remove(); |
| 173 } | 175 } |
| 174 } | 176 } |
| 175 | 177 |
| 176 // Discard clean-up mutations. | |
| 177 observer.takeRecords(); | |
| 178 | |
| 179 Selection selection = window.getSelection(); | 178 Selection selection = window.getSelection(); |
| 180 | 179 |
| 181 while (!mutations.isEmpty) { | 180 for (MutationRecord record in mutations) { |
| 182 for (MutationRecord record in mutations) { | 181 if (record.addedNodes.isEmpty) continue; |
| 183 String type = record.type; | 182 for (Node node in record.addedNodes) { |
| 184 switch (type) { | 183 if (node.parent == null) continue; |
| 185 | 184 StringBuffer buffer = new StringBuffer(); |
| 186 case 'characterData': | 185 int selectionOffset = htmlToText(node, buffer, selection); |
| 187 bool hasSelection = false; | 186 Text newNode = new Text('$buffer'); |
| 188 int offset = selection.anchorOffset; | 187 node.replaceWith(newNode); |
| 189 if (selection.isCollapsed && | 188 if (selectionOffset != -1) { |
| 190 selection.anchorNode == record.target) { | 189 selection.collapse(newNode, selectionOffset); |
| 191 hasSelection = true; | |
| 192 } | |
| 193 var parent = record.target.parentNode; | |
| 194 if (parent != inputPre) { | |
| 195 editor.inlineChildren(parent); | |
| 196 } | |
| 197 if (hasSelection) { | |
| 198 selection.collapse(record.target, offset); | |
| 199 } | |
| 200 break; | |
| 201 | |
| 202 default: | |
| 203 if (!record.addedNodes.isEmpty) { | |
| 204 for (var node in record.addedNodes) { | |
| 205 | |
| 206 if (node.nodeType != Node.ELEMENT_NODE) continue; | |
| 207 | |
| 208 if (node is BRElement) { | |
| 209 if (selection.anchorNode != node) { | |
| 210 node.replaceWith(new Text('\n')); | |
| 211 } | |
| 212 } else { | |
| 213 var parent = node.parentNode; | |
| 214 if (parent == null) continue; | |
| 215 var nodes = new List.from(node.nodes); | |
| 216 var style = node.getComputedStyle(); | |
| 217 if (style.display != 'inline') { | |
| 218 var previous = node.previousNode; | |
| 219 if (previous is Text) { | |
| 220 previous.appendData('\n'); | |
| 221 } else { | |
| 222 parent.insertBefore(new Text('\n'), node); | |
| 223 } | |
| 224 } | |
| 225 for (Node child in nodes) { | |
| 226 child.remove(); | |
| 227 parent.insertBefore(child, node); | |
| 228 } | |
| 229 node.remove(); | |
| 230 } | |
| 231 } | |
| 232 } | |
| 233 } | 190 } |
| 234 } | 191 } |
| 235 mutations = observer.takeRecords(); | |
| 236 } | 192 } |
| 237 | 193 |
| 238 if (!inputPre.nodes.isEmpty && inputPre.nodes.last is Text) { | 194 if (!inputPre.nodes.isEmpty && inputPre.nodes.last is Text) { |
| 239 Text text = inputPre.nodes.last; | 195 Text text = inputPre.nodes.last; |
| 240 if (!text.text.endsWith('\n')) { | 196 if (!text.text.endsWith('\n')) { |
| 241 text.appendData('\n'); | 197 text.appendData('\n'); |
| 242 } | 198 } |
| 243 } | 199 } |
| 244 | 200 |
| 245 int offset = 0; | 201 int offset = 0; |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 event.getModifierState("Fn") || | 591 event.getModifierState("Fn") || |
| 636 event.getModifierState("Meta") || | 592 event.getModifierState("Meta") || |
| 637 event.getModifierState("NumLock") || | 593 event.getModifierState("NumLock") || |
| 638 event.getModifierState("ScrollLock") || | 594 event.getModifierState("ScrollLock") || |
| 639 event.getModifierState("Scroll") || | 595 event.getModifierState("Scroll") || |
| 640 event.getModifierState("Win") || | 596 event.getModifierState("Win") || |
| 641 event.getModifierState("Shift") || | 597 event.getModifierState("Shift") || |
| 642 event.getModifierState("SymbolLock") || | 598 event.getModifierState("SymbolLock") || |
| 643 event.getModifierState("OS"); | 599 event.getModifierState("OS"); |
| 644 } | 600 } |
| OLD | NEW |