OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 import 'package:sky/services/keyboard/keyboard.mojom.dart'; | 5 import 'package:sky/services/keyboard/keyboard.mojom.dart'; |
6 | 6 |
7 typedef void StringChangedCallback(EditableString updated); | 7 typedef void StringUpdated(); |
8 | 8 |
9 class TextRange { | 9 class TextRange { |
10 final int start; | 10 final int start; |
11 final int end; | 11 final int end; |
12 | 12 |
13 TextRange({this.start, this.end}); | 13 TextRange({this.start, this.end}); |
14 TextRange.collapsed(int position) : start = position, end = position; | 14 TextRange.collapsed(int position) : start = position, end = position; |
15 const TextRange.empty() : start = -1, end = -1; | 15 const TextRange.empty() : start = -1, end = -1; |
16 | 16 |
17 bool get isValid => start >= 0 && end >= 0; | 17 bool get isValid => start >= 0 && end >= 0; |
18 bool get isCollapsed => start == end; | 18 bool get isCollapsed => start == end; |
19 } | 19 } |
20 | 20 |
21 class EditableString implements KeyboardClient { | 21 class EditableString implements KeyboardClient { |
22 String text; | 22 String text; |
23 TextRange composing = const TextRange.empty(); | 23 TextRange composing = const TextRange.empty(); |
24 TextRange selection = const TextRange.empty(); | 24 TextRange selection = const TextRange.empty(); |
25 | 25 |
26 final StringChangedCallback onChanged; | 26 final StringUpdated onUpdated; |
27 | 27 |
28 KeyboardClientStub stub; | 28 KeyboardClientStub stub; |
29 | 29 |
30 EditableString({this.text: '', this.onChanged}) { | 30 EditableString({this.text: '', this.onUpdated}) { |
31 stub = new KeyboardClientStub.unbound()..impl = this; | 31 stub = new KeyboardClientStub.unbound()..impl = this; |
32 } | 32 } |
33 | 33 |
34 String textBefore(TextRange range) { | 34 String textBefore(TextRange range) { |
35 return text.substring(0, range.start); | 35 return text.substring(0, range.start); |
36 } | 36 } |
37 | 37 |
38 String textAfter(TextRange range) { | 38 String textAfter(TextRange range) { |
39 return text.substring(range.end); | 39 return text.substring(range.end); |
40 } | 40 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 | 78 |
79 void commitCorrection(CorrectionData correction) { | 79 void commitCorrection(CorrectionData correction) { |
80 // TODO(abarth): Not implemented. | 80 // TODO(abarth): Not implemented. |
81 } | 81 } |
82 | 82 |
83 void commitText(String text, int newCursorPosition) { | 83 void commitText(String text, int newCursorPosition) { |
84 // TODO(abarth): Why is |newCursorPosition| always 1? | 84 // TODO(abarth): Why is |newCursorPosition| always 1? |
85 TextRange committedRange = _replaceOrAppend(composing, text); | 85 TextRange committedRange = _replaceOrAppend(composing, text); |
86 selection = new TextRange.collapsed(committedRange.end); | 86 selection = new TextRange.collapsed(committedRange.end); |
87 composing = const TextRange.empty(); | 87 composing = const TextRange.empty(); |
88 onChanged(this); | 88 onUpdated(); |
89 } | 89 } |
90 | 90 |
91 void deleteSurroundingText(int beforeLength, int afterLength) { | 91 void deleteSurroundingText(int beforeLength, int afterLength) { |
92 TextRange beforeRange = new TextRange(start: selection.start - beforeLength, | 92 TextRange beforeRange = new TextRange(start: selection.start - beforeLength, |
93 end: selection.start); | 93 end: selection.start); |
94 TextRange afterRange = new TextRange(start: selection.end, | 94 TextRange afterRange = new TextRange(start: selection.end, |
95 end: selection.end + afterLength); | 95 end: selection.end + afterLength); |
96 _delete(afterRange); | 96 _delete(afterRange); |
97 _delete(beforeRange); | 97 _delete(beforeRange); |
98 selection = new TextRange(start: selection.start - beforeLength, | 98 selection = new TextRange(start: selection.start - beforeLength, |
99 end: selection.end - beforeLength); | 99 end: selection.end - beforeLength); |
100 onChanged(this); | 100 onUpdated(); |
101 } | 101 } |
102 | 102 |
103 void setComposingRegion(int start, int end) { | 103 void setComposingRegion(int start, int end) { |
104 composing = new TextRange(start: start, end: end); | 104 composing = new TextRange(start: start, end: end); |
105 onChanged(this); | 105 onUpdated(); |
106 } | 106 } |
107 | 107 |
108 void setComposingText(String text, int newCursorPosition) { | 108 void setComposingText(String text, int newCursorPosition) { |
109 // TODO(abarth): Why is |newCursorPosition| always 1? | 109 // TODO(abarth): Why is |newCursorPosition| always 1? |
110 composing = _replaceOrAppend(composing, text); | 110 composing = _replaceOrAppend(composing, text); |
111 selection = new TextRange.collapsed(composing.end); | 111 selection = new TextRange.collapsed(composing.end); |
112 onChanged(this); | 112 onUpdated(); |
113 } | 113 } |
114 | 114 |
115 void setSelection(int start, int end) { | 115 void setSelection(int start, int end) { |
116 selection = new TextRange(start: start, end: end); | 116 selection = new TextRange(start: start, end: end); |
117 onChanged(this); | 117 onUpdated(); |
118 } | 118 } |
119 } | 119 } |
OLD | NEW |