@@ -6,6 +6,7 @@ import config from './config.js'
6
6
import Keyboard from './keyboard.js'
7
7
import { closest } from './util/dom.js'
8
8
import { replaceLast , endsWithSingleSpace } from './util/string.js'
9
+ import { shouldApplySmartQuotes , isQuote , isOpeningQuote , isClosingQuote } from './smartQuotes.js'
9
10
10
11
/**
11
12
* The Dispatcher module is responsible for dealing with events and their handlers.
@@ -144,6 +145,39 @@ export default class Dispatcher {
144
145
. setupDocumentListener ( 'input' , function inputListener ( evt ) {
145
146
const block = this . getEditableBlockByEvent ( evt )
146
147
if ( ! block ) return
148
+
149
+ const target = evt . target
150
+ const currentChar = evt . data
151
+
152
+
153
+ if ( target . isContentEditable && shouldApplySmartQuotes ( config ) ) {
154
+ if ( isQuote ( currentChar ) ) {
155
+ const selection = this . selectionWatcher . getFreshSelection ( )
156
+ const wholeText = selection . range . startContainer . wholeText
157
+ // const firstPart = selection.range.startContainer.textContent
158
+ const offset = selection . range . startOffset
159
+ if ( isClosingQuote ( [ ...wholeText ] , offset - 2 ) ) {
160
+ const textArr = [ ...target . innerText ]
161
+ const index = offset - 1
162
+ if ( index >= 0 && index < textArr . length ) {
163
+ textArr [ index ] = '»'
164
+ target . innerText = textArr . join ( '' )
165
+ }
166
+ this . editable . createCursorAtCharacterOffset ( { element : block , offset} )
167
+ }
168
+
169
+ if ( isOpeningQuote ( [ ...wholeText ] , offset - 2 ) ) {
170
+ const textArr = [ ...target . innerText ]
171
+ const index = offset - 1
172
+ if ( index >= 0 && index < textArr . length ) {
173
+ textArr [ index ] = '«'
174
+ target . innerText = textArr . join ( '' )
175
+ }
176
+ this . editable . createCursorAtCharacterOffset ( { element : block , offset} )
177
+ }
178
+ }
179
+
180
+ }
147
181
this . notify ( 'change' , block )
148
182
} )
149
183
0 commit comments