Index: dart/site/try/src/interaction_manager.dart |
diff --git a/dart/site/try/src/interaction_manager.dart b/dart/site/try/src/interaction_manager.dart |
index ecd7663b1ab51ba60c2eb35568dcb34f33c394c9..97c06d460eef977fa048c39183e68c80448643bf 100644 |
--- a/dart/site/try/src/interaction_manager.dart |
+++ b/dart/site/try/src/interaction_manager.dart |
@@ -236,6 +236,7 @@ class InteractionContext extends InteractionManager { |
void onKeyUp(KeyboardEvent event) => state.onKeyUp(event); |
void onMutation(List<MutationRecord> mutations, MutationObserver observer) { |
+ workAroundFirefoxBug(); |
try { |
try { |
return state.onMutation(mutations, observer); |
@@ -308,7 +309,6 @@ abstract class InteractionState implements InteractionManager { |
void set state(InteractionState newState); |
void onStateChanged(InteractionState previous) { |
- print('State change ${previous.runtimeType} -> ${runtimeType}.'); |
} |
void transitionToInitialState() { |
@@ -336,10 +336,8 @@ class InitialState extends InteractionState { |
void onKeyUp(KeyboardEvent event) { |
if (computeHasModifier(event)) { |
- print('onKeyUp (modified)'); |
onModifiedKeyUp(event); |
} else { |
- print('onKeyUp (unmodified)'); |
onUnmodifiedKeyUp(event); |
} |
} |
@@ -413,8 +411,6 @@ class InitialState extends InteractionState { |
} |
void onMutation(List<MutationRecord> mutations, MutationObserver observer) { |
- print('onMutation'); |
- |
removeCodeCompletion(); |
Selection selection = window.getSelection(); |
@@ -456,7 +452,11 @@ class InitialState extends InteractionState { |
node.parent.insertAllBefore(nodes, node); |
node.remove(); |
- trySelection.adjust(selection); |
+ if (mainEditorPane.contains(trySelection.anchorNode)) { |
+ // Sometimes the anchor node is removed by the above call. This has |
+ // only been observed in Firefox, and is hard to reproduce. |
+ trySelection.adjust(selection); |
+ } |
// TODO(ahe): We know almost exactly what has changed. It could be |
// more efficient to only communicate what changed. |
@@ -1206,7 +1206,10 @@ void normalizeMutationRecord(MutationRecord record, |
} |
normalizedNodes.add(line); |
} |
- if (record.type == "characterData") { |
+ if (record.type == "characterData" && record.target.parent != null) { |
+ // At least Firefox sends a "characterData" record whose target is the |
+ // deleted text node. It also sends a record where "removedNodes" isn't |
+ // empty whose target is the parent (which we are interested in). |
normalizedNodes.add(findLine(record.target)); |
} |
} |
@@ -1259,3 +1262,23 @@ bool isCompilerStageMarker(String message) { |
message == "Compiling..." || |
message.startsWith('Compiled '); |
} |
+ |
+void workAroundFirefoxBug() { |
+ Selection selection = window.getSelection(); |
+ if (!isCollapsed(selection)) return; |
+ Node node = selection.anchorNode; |
+ int offset = selection.anchorOffset; |
+ if (selection.anchorNode is Element && selection.anchorOffset != 0) { |
+ // In some cases, Firefox reports the wrong anchorOffset (always seems to |
+ // be 6) when anchorNode is an Element. Moving the cursor back and forth |
+ // adjusts the anchorOffset. |
+ // Safari can also reach this code, but the offset isn't wrong, just |
+ // inconsistent. After moving the cursor back and forth, Safari will make |
+ // the offset relative to a text node. |
+ selection |
+ ..modify('move', 'backward', 'character') |
+ ..modify('move', 'forward', 'character'); |
+ print('Selection adjusted $node@$offset -> ' |
+ '${selection.anchorNode}@${selection.anchorOffset}.'); |
+ } |
+} |