| /********************************************* | |
| * Manage the MathQuill instance's textarea | |
| * (as owned by the Controller) | |
| ********************************************/ | |
| Controller.open(function(_) { | |
| Options.p.substituteTextarea = function() { | |
| return $('<textarea autocapitalize=off autocomplete=off autocorrect=off ' + | |
| 'spellcheck=false x-palm-disable-ste-all=true />')[0]; | |
| }; | |
| _.createTextarea = function() { | |
| var textareaSpan = this.textareaSpan = $('<span class="mq-textarea"></span>'), | |
| textarea = this.options.substituteTextarea(); | |
| if (!textarea.nodeType) { | |
| throw 'substituteTextarea() must return a DOM element, got ' + textarea; | |
| } | |
| textarea = this.textarea = $(textarea).appendTo(textareaSpan); | |
| var ctrlr = this; | |
| ctrlr.cursor.selectionChanged = function() { ctrlr.selectionChanged(); }; | |
| ctrlr.container.bind('copy', function() { ctrlr.setTextareaSelection(); }); | |
| }; | |
| _.selectionChanged = function() { | |
| var ctrlr = this; | |
| forceIERedraw(ctrlr.container[0]); | |
| // throttle calls to setTextareaSelection(), because setting textarea.value | |
| // and/or calling textarea.select() can have anomalously bad performance: | |
| // https://github.com/mathquill/mathquill/issues/43#issuecomment-1399080 | |
| if (ctrlr.textareaSelectionTimeout === undefined) { | |
| ctrlr.textareaSelectionTimeout = setTimeout(function() { | |
| ctrlr.setTextareaSelection(); | |
| }); | |
| } | |
| }; | |
| _.setTextareaSelection = function() { | |
| this.textareaSelectionTimeout = undefined; | |
| var latex = ''; | |
| if (this.cursor.selection) { | |
| latex = this.cursor.selection.join('latex'); | |
| if (this.options.statelessClipboard) { | |
| // FIXME: like paste, only this works for math fields; should ask parent | |
| latex = '$' + latex + '$'; | |
| } | |
| } | |
| this.selectFn(latex); | |
| }; | |
| _.staticMathTextareaEvents = function() { | |
| var ctrlr = this, root = ctrlr.root, cursor = ctrlr.cursor, | |
| textarea = ctrlr.textarea, textareaSpan = ctrlr.textareaSpan; | |
| this.container.prepend('<span class="mq-selectable">$'+ctrlr.exportLatex()+'$</span>'); | |
| ctrlr.blurred = true; | |
| textarea.bind('cut paste', false) | |
| .focus(function() { ctrlr.blurred = false; }).blur(function() { | |
| if (cursor.selection) cursor.selection.clear(); | |
| setTimeout(detach); //detaching during blur explodes in WebKit | |
| }); | |
| function detach() { | |
| textareaSpan.detach(); | |
| ctrlr.blurred = true; | |
| } | |
| ctrlr.selectFn = function(text) { | |
| textarea.val(text); | |
| if (text) textarea.select(); | |
| }; | |
| }; | |
| _.editablesTextareaEvents = function() { | |
| var ctrlr = this, root = ctrlr.root, cursor = ctrlr.cursor, | |
| textarea = ctrlr.textarea, textareaSpan = ctrlr.textareaSpan; | |
| var keyboardEventsShim = saneKeyboardEvents(textarea, this); | |
| this.selectFn = function(text) { keyboardEventsShim.select(text); }; | |
| this.container.prepend(textareaSpan) | |
| .on('cut', function(e) { | |
| if (cursor.selection) { | |
| setTimeout(function() { | |
| ctrlr.notify('edit'); // deletes selection if present | |
| cursor.parent.bubble('reflow'); | |
| }); | |
| } | |
| }); | |
| this.focusBlurEvents(); | |
| }; | |
| _.typedText = function(ch) { | |
| if (ch === '\n') return this.handle('enter'); | |
| var cursor = this.notify().cursor; | |
| cursor.parent.write(cursor, ch); | |
| this.scrollHoriz(); | |
| }; | |
| _.paste = function(text) { | |
| // TODO: document `statelessClipboard` config option in README, after | |
| // making it work like it should, that is, in both text and math mode | |
| // (currently only works in math fields, so worse than pointless, it | |
| // only gets in the way by \text{}-ifying pasted stuff and $-ifying | |
| // cut/copied LaTeX) | |
| if (this.options.statelessClipboard) { | |
| if (text.slice(0,1) === '$' && text.slice(-1) === '$') { | |
| text = text.slice(1, -1); | |
| } | |
| else { | |
| text = '\\text{'+text+'}'; | |
| } | |
| } | |
| // FIXME: this always inserts math or a TextBlock, even in a RootTextBlock | |
| this.writeLatex(text).cursor.show(); | |
| }; | |
| }); |