Annotation of modules/damieng/graphical_editor/loncapa_daxe/web/nodes/lm.dart, revision 1.1

1.1     ! damieng     1: /*
        !             2:   This file is part of LONCAPA-Daxe.
        !             3: 
        !             4:   LONCAPA-Daxe is free software: you can redistribute it and/or modify
        !             5:   it under the terms of the GNU General Public License as published by
        !             6:   the Free Software Foundation, either version 3 of the License, or
        !             7:   (at your option) any later version.
        !             8: 
        !             9:   LONCAPA-Daxe is distributed in the hope that it will be useful,
        !            10:   but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            12:   GNU General Public License for more details.
        !            13: 
        !            14:   You should have received a copy of the GNU General Public License
        !            15:   along with Daxe.  If not, see <http://www.gnu.org/licenses/>.
        !            16: */
        !            17: 
        !            18: part of loncapa_daxe;
        !            19: 
        !            20: /**
        !            21:  * Displays lm and dlm elements (LON-CAPA inline and display math).
        !            22:  * Jaxe display type: 'lm'.
        !            23:  */
        !            24: class Lm extends DaxeNode {
        !            25:   
        !            26:   static String constants = 'c, pi, e, hbar, amu';
        !            27:   static js.JsObject parser_symbols;
        !            28:   static js.JsObject parser_units;
        !            29:   
        !            30:   Lm.fromRef(x.Element elementRef) : super.fromRef(elementRef) {
        !            31:   }
        !            32:   
        !            33:   Lm.fromNode(x.Node node, DaxeNode parent) : super.fromNode(node, parent) {
        !            34:   }
        !            35:   
        !            36:   @override
        !            37:   h.Element html() {
        !            38:     h.Element el;
        !            39:     if (nodeName == 'dlm')
        !            40:       el = new h.DivElement();
        !            41:     else
        !            42:       el = new h.SpanElement();
        !            43:     el.id = "$id";
        !            44:     el.classes.add('dn');
        !            45:     el.classes.add('math');
        !            46:     if (!valid)
        !            47:       el.classes.add('invalid');
        !            48:     el.onClick.listen((h.MouseEvent event) => makeEditable());
        !            49:     updateEquationDisplay(el);
        !            50:     return(el);
        !            51:   }
        !            52:   
        !            53:   @override
        !            54:   void newNodeCreationUI(ActionFunction okfct) {
        !            55:     okfct();
        !            56:     makeEditable();
        !            57:   }
        !            58:   
        !            59:   @override
        !            60:   Position firstCursorPositionInside() {
        !            61:     return(null);
        !            62:   }
        !            63:   
        !            64:   @override
        !            65:   Position lastCursorPositionInside() {
        !            66:     return(null);
        !            67:   }
        !            68:   
        !            69:   @override
        !            70:   void afterInsert() {
        !            71:     h.Element el = h.document.getElementById(id);
        !            72:     updateEquationDisplay(el);
        !            73:   }
        !            74:   
        !            75:   void updateEquationDisplay(h.Element el) {
        !            76:     String equationText = '?';
        !            77:     if (firstChild != null && firstChild.nodeValue.trim() != '')
        !            78:       equationText = firstChild.nodeValue;
        !            79:     js.JsObject parser;
        !            80:     if (getAttribute('mode') == 'units') {
        !            81:       if (parser_units == null)
        !            82:         parser_units = new js.JsObject(js.context['LCMATH']['Parser'], [true, true, constants]);
        !            83:       parser = parser_units;
        !            84:     } else {
        !            85:       if (parser_symbols == null)
        !            86:         parser_symbols = new js.JsObject(js.context['LCMATH']['Parser'], [true, false, constants]);
        !            87:       parser = parser_symbols;
        !            88:     }
        !            89:     for (h.Node n in el.childNodes)
        !            90:       n.remove();
        !            91:     try {
        !            92:       js.JsObject root = parser.callMethod('parse', [equationText]);
        !            93:       if (root != null) {
        !            94:         h.Element math = h.document.createElement('math');
        !            95:         math.setAttribute('display', nodeName == 'dlm' ? 'block' : 'inline');
        !            96:         js.JsObject colors = new js.JsObject.jsify(['#000000']); // to use only black
        !            97:         math.append(root.callMethod('toMathML', [colors]));
        !            98:         el.append(math);
        !            99:         Timer.run(() {
        !           100:           js.JsArray params = new js.JsObject.jsify( ['Typeset', js.context['MathJax']['Hub'], id] );
        !           101:           js.context['MathJax']['Hub'].callMethod('Queue', [params]);
        !           102:           js.context['MathJax']['Hub'].callMethod('Queue', [() => page.cursor.refresh()]);
        !           103:         });
        !           104:       }
        !           105:     } catch (e) {
        !           106:       el.text = 'Error: ' + e.toString();
        !           107:     }
        !           108:   }
        !           109:   
        !           110:   void makeEditable() {
        !           111:     h.Element el = h.document.getElementById(id);
        !           112:     if (el == null)
        !           113:       return;
        !           114:     h.Element editEl;
        !           115:     if (nodeName == 'dlm')
        !           116:       editEl = new h.DivElement();
        !           117:     else
        !           118:       editEl = new h.SpanElement();
        !           119:     editEl.id = id;
        !           120:     h.TextInputElement input = new h.TextInputElement();
        !           121:     input.classes.add('math');
        !           122:     input.setAttribute('data-unit_mode', getAttribute('mode') == 'units' ? 'true' : 'false');
        !           123:     input.setAttribute('data-constants', constants);
        !           124:     input.setAttribute('data-implicit_operators', 'true');
        !           125:     input.setAttribute('spellcheck', 'false');
        !           126:     if (firstChild != null) {
        !           127:       input.value = firstChild.nodeValue;
        !           128:       if (input.value.length > 20)
        !           129:         input.size = input.value.length;
        !           130:     }
        !           131:     editEl.append(input);
        !           132:     h.SelectElement select = new h.SelectElement();
        !           133:     h.OptionElement symbolsOption = new h.OptionElement();
        !           134:     symbolsOption.value = 'symbols';
        !           135:     symbolsOption.appendText(LCDStrings.get('lm_symbols'));
        !           136:     if (getAttribute('mode') != 'units')
        !           137:       symbolsOption.setAttribute('selected', 'selected');
        !           138:     select.append(symbolsOption);
        !           139:     h.OptionElement unitsOption = new h.OptionElement();
        !           140:     unitsOption.value = 'units';
        !           141:     unitsOption.appendText(LCDStrings.get('lm_units'));
        !           142:     if (getAttribute('mode') == 'units')
        !           143:       unitsOption.setAttribute('selected', 'selected');
        !           144:     select.append(unitsOption);
        !           145:     select.onInput.listen((h.Event event) {
        !           146:       if (select.value == 'symbols' && getAttribute('mode') == 'units') {
        !           147:         setAttribute('mode', 'symbols');
        !           148:         input.setAttribute('data-unit_mode', 'false');
        !           149:         js.context['LCMATH'].callMethod('initEditors');
        !           150:       } else if (select.value == 'units' && getAttribute('mode') != 'units') {
        !           151:         setAttribute('mode', 'units');
        !           152:         input.setAttribute('data-unit_mode', 'true');
        !           153:         js.context['LCMATH'].callMethod('initEditors');
        !           154:       }
        !           155:       input.focus();
        !           156:     });
        !           157:     editEl.append(select);
        !           158:     el.replaceWith(editEl);
        !           159:     input.focus();
        !           160:     js.context['LCMATH'].callMethod('initEditors');
        !           161:     var switchDisplay = () {
        !           162:       String equationText = input.value;
        !           163:       if (equationText != '') {
        !           164:         if (firstChild != null)
        !           165:           firstChild.nodeValue = equationText;
        !           166:         else
        !           167:           appendChild(new DNText(equationText));
        !           168:       } else {
        !           169:         if (firstChild != null)
        !           170:           removeChild(firstChild);
        !           171:       }
        !           172:       editEl.replaceWith(html());
        !           173:     };
        !           174:     input.onBlur.listen((h.Event event) {
        !           175:       Timer.run(() { // timer so that activeElement is updated
        !           176:         if (h.document.activeElement == select)
        !           177:           return;
        !           178:         switchDisplay();
        !           179:       });
        !           180:     });
        !           181:     select.onBlur.listen((h.Event event) {
        !           182:       Timer.run(() {
        !           183:         if (h.document.activeElement == input)
        !           184:           return;
        !           185:         switchDisplay();
        !           186:       });
        !           187:     });
        !           188:     if (editEl is h.DivElement) {
        !           189:       editEl.onClick.listen((h.MouseEvent event) {
        !           190:         if (event.target != input && event.target != select) {
        !           191:           page.moveCursorTo(new Position(parent, parent.offsetOf(this)+1));
        !           192:         }
        !           193:       });
        !           194:     }
        !           195:     input.onKeyDown.listen((h.KeyboardEvent event) {
        !           196:       String equationText = input.value;
        !           197:       int inputSize = input.size;
        !           198:       if (equationText != null && equationText.length > inputSize)
        !           199:         input.size = equationText.length;
        !           200:     });
        !           201:   }
        !           202: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>