UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

648 lines (572 loc) 24.3 kB
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The source code</title> <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="../resources/prettify/prettify.js"></script> <style type="text/css"> .highlight { display: block; background-color: #ddd; } </style> <script type="text/javascript"> function highlight() { document.getElementById(location.hash.replace(/#/, "")).className = "highlight"; } </script> </head> <body onload="prettyPrint(); highlight();"> <pre class="prettyprint lang-js">/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ Ext.define(&#39;Ext.ux.form.field.CodeMirror&#39;, { extend : &#39;Ext.Component&#39;, alias : &#39;widget.jseditor&#39;, alternateClassName : &#39;Ext.form.CodeMirror&#39;, requires : [ &#39;Ext.tip.QuickTipManager&#39;, &#39;Ext.toolbar.Item&#39;, &#39;Ext.util.Format&#39; ], width : &#39;100%&#39;, <span id='global-cfg-mode'> /** </span> * @cfg {String} mode The default mode to use when the editor is initialized. When not given, this will default to the first mode that was loaded. * It may be a string, which either simply names the mode or is a MIME type associated with the mode. Alternatively, * it may be an object containing configuration options for the mode, with a name property that names the mode * (for example {name: &quot;javascript&quot;, json: true}). The demo pages for each mode contain information about what * configuration parameters the mode supports. */ mode : &#39;text/javascript&#39;, <span id='global-cfg-showLineNumbers'> /** </span> * @cfg {Boolean} showLineNumbers Enable line numbers button in the toolbar. */ showLineNumbers : true, <span id='global-cfg-enableMatchBrackets'> /** </span> * @cfg {Boolean} enableMatchBrackets Force matching-bracket-highlighting to happen */ enableMatchBrackets : true, <span id='global-cfg-enableElectricChars'> /** </span> * @cfg {Boolean} enableElectricChars Configures whether the editor should re-indent the current line when a character is typed * that might change its proper indentation (only works if the mode supports indentation). */ enableElectricChars : false, <span id='global-cfg-enableIndentWithTabs'> /** </span> * @cfg {Boolean} enableIndentWithTabs Whether, when indenting, the first N*tabSize spaces should be replaced by N tabs. */ enableIndentWithTabs : true, <span id='global-cfg-enableSmartIndent'> /** </span> * @cfg {Boolean} enableSmartIndent Whether to use the context-sensitive indentation that the mode provides (or just indent the same as the line before). */ enableSmartIndent : true, <span id='global-cfg-enableLineWrapping'> /** </span> * @cfg {Boolean} enableLineWrapping Whether CodeMirror should scroll or wrap for long lines. */ enableLineWrapping : false, <span id='global-cfg-enableLineNumbers'> /** </span> * @cfg {Boolean} enableLineNumbers Whether to show line numbers to the left of the editor. */ enableLineNumbers : true, <span id='global-cfg-enableFixedGutter'> /** </span> * @cfg {Boolean} enableFixedGutter When enabled (off by default), this will make the gutter stay visible when the * document is scrolled horizontally. */ enableFixedGutter : false, <span id='global-cfg-firstLineNumber'> /** </span> * @cfg {Number} firstLineNumber At which number to start counting lines. */ firstLineNumber : 1, <span id='global-cfg-readOnly'> /** </span> * @cfg {Boolean} readOnly &lt;tt&gt;true&lt;/tt&gt; to mark the field as readOnly. */ readOnly : false, <span id='global-cfg-pollInterval'> /** </span> * @cfg {Number} pollInterval Indicates how quickly (miliseconds) CodeMirror should poll its input textarea for changes. * Most input is captured by events, but some things, like IME input on some browsers, doesn&#39;t generate events * that allow CodeMirror to properly detect it. Thus, it polls. */ pollInterval : 100, <span id='global-cfg-indentUnit'> /** </span> * @cfg {Number} indentUnit How many spaces a block (whatever that means in the edited language) should be indented. */ indentUnit : 4, <span id='global-cfg-tabSize'> /** </span> * @cfg {Number} tabSize The width of a tab character. */ tabSize : 4, <span id='global-cfg-theme'> /** </span> * @cfg {String} theme The theme to style the editor with. You must make sure the CSS file defining the corresponding * .cm-s-[name] styles is loaded (see the theme directory in the distribution). The default is &quot;default&quot;, for which * colors are included in codemirror.css. It is possible to use multiple theming classes at once—for example * &quot;foo bar&quot; will assign both the cm-s-foo and the cm-s-bar classes to the editor. */ theme : &#39;default&#39;, scriptsLoaded : [], lastMode : &#39;&#39;, initComponent : function () { var me = this; //me.addEvents( <span id='global-event-initialize'> /** </span> * @event initialize * Fires when the editor is fully initialized (including the iframe) * @param {Ext.ux.form.field.CodeMirror} this */ //&#39;initialize&#39;, <span id='global-event-activate'> /** </span> * @event activate * Fires when the editor is first receives the focus. Any insertion must wait * until after this event. * @param {Ext.ux.form.field.CodeMirror} this */ //&#39;activate&#39;, <span id='global-event-deactivate'> /** </span> * @event deactivate * Fires when the editor looses the focus. * @param {Ext.ux.form.field.CodeMirror} this */ //&#39;deactivate&#39;, <span id='global-event-change'> /** </span> * @event change * Fires when the content of the editor is changed. * @param {Ext.ux.form.field.CodeMirror} this * @param {String} newValue New value * @param {String} oldValue Old value * @param {Array} options */ //&#39;change&#39;, <span id='global-event-cursoractivity'> /** </span> * @event cursoractivity * Fires when the cursor or selection moves, or any change is made to the editor content. * @param {Ext.ux.form.field.CodeMirror} this */ //&#39;cursoractivity&#39;, <span id='global-event-gutterclick'> /** </span> * @event gutterclick * Fires whenever the editor gutter (the line-number area) is clicked. * @param {Ext.ux.form.field.CodeMirror} this * @param {Number} lineNumber Zero-based number of the line that was clicked * @param {Object} event The raw mousedown event */ //&#39;gutterclick&#39;, <span id='global-event-scroll'> /** </span> * @event scroll * Fires whenever the editor is scrolled. * @param {Ext.ux.form.field.CodeMirror} this */ //&#39;scroll&#39;, <span id='global-event-highlightcomplete'> /** </span> * @event highlightcomplete * Fires whenever the editor&#39;s content has been fully highlighted. * @param {Ext.ux.form.field.CodeMirror} this */ //&#39;highlightcomplete&#39;, <span id='global-event-update'> /** </span> * @event update * Fires whenever CodeMirror updates its DOM display. * @param {Ext.ux.form.field.CodeMirror} this */ //&#39;update&#39;, <span id='global-event-keyevent'> /** </span> * @event keyevent * Fires on eery keydown, keyup, and keypress event that CodeMirror captures. * @param {Ext.ux.form.field.CodeMirror} this * @param {Object} event This key event is pretty much the raw key event, except that a stop() method is always * added to it. You could feed it to, for example, jQuery.Event to further normalize it. This function can inspect * the key event, and handle it if it wants to. It may return true to tell CodeMirror to ignore the event. * Be wary that, on some browsers, stopping a keydown does not stop the keypress from firing, whereas on others * it does. If you respond to an event, you should probably inspect its type property and only do something when * it is keydown (or keypress for actions that need character data). */ //&#39;keyevent&#39; //); me.callParent(arguments); /* Fix resize issues as suggested by user koblass on the Extjs forums http://www.sencha.com/forum/showthread.php?167047-Ext.ux.form.field.CodeMirror-for-Ext-4.x&amp;p=860535&amp;viewfull=1#post860535 */ me.on(&#39;resize&#39;, function () { if (me.editor) { me.editor.refresh(); } }, me); }, resetOriginalValue : Ext.emptyFn, isValid : function() { var errors = this.getErrors() || []; return errors.length === 0; }, <span id='global-method-afterRender'> /** </span> * @private override */ afterRender : function () { var me = this; me.callParent(arguments); me.initEditor(); }, <span id='global-method-initEditor'> /** </span> * @private override */ initEditor : function () { var me = this, mode = &#39;javascript&#39;; me.editor = CodeMirror(me.el.dom, { matchBrackets : me.enableMatchBrackets, electricChars : me.enableElectricChars, autoClearEmptyLines : true, indentUnit : me.indentUnit, smartIndent : me.enableSmartIndent, indentWithTabs : me.indentWithTabs, pollInterval : me.pollInterval, lineNumbers : me.enableLineNumbers, lineWrapping : me.enableLineWrapping, firstLineNumber : me.firstLineNumber, tabSize : me.tabSize, gutters : [&quot;CodeMirror-lint-markers&quot;], fixedGutter : me.enableFixedGutter, theme : me.theme, mode : mode, lintWith : CodeMirror.javascriptValidatorWithOptions({ &quot;onecase&quot; : true, &quot;asi&quot; : true, &quot;expr&quot; : true, // allow fn &amp;&amp; fn() &quot;loopfunc&quot; : true, &quot;laxbreak&quot; : true, &quot;debug&quot; : true, &quot;laxcomma&quot; : true, smarttabs : true }), onChange : function (editor, tc) { me.checkValid(); //me.last-child(); //me.fireEvent(&#39;change&#39;, me, tc.from, tc.to, tc.text, tc.next || null); }, onCursorActivity : function (editor) { me.fireEvent(&#39;cursoractivity&#39;, me); }, onGutterClick : function (editor, line, event) { me.fireEvent(&#39;gutterclick&#39;, me, line, event); }, onFocus : function (editor) { me.fireEvent(&#39;activate&#39;, me); }, onBlur : function (editor, e) { me.fireEvent(&#39;deactivate&#39;, me); me.onBlur(e); }, onScroll : function (editor) { me.fireEvent(&#39;scroll&#39;, me); }, onHighlightComplete : function (editor) { me.fireEvent(&#39;highlightcomplete&#39;, me); }, onUpdate : function (editor) { me.fireEvent(&#39;update&#39;, me); }, onKeyEvent : function (editor, event) { event.cancelBubble = true; // fix suggested by koblass user on Sencha forums (http://www.sencha.com/forum/showthread.php?167047-Ext.ux.form.field.CodeMirror-for-Ext-4.x&amp;p=862029&amp;viewfull=1#post862029) me.fireEvent(&#39;keyevent&#39;, me, event); } }); //me.editor.setValue(me.rawValue); // me.setMode(me.mode); me.setReadOnly(me.readOnly); me.fireEvent(&#39;initialize&#39;, me); // change the codemirror css var css = Ext.util.CSS.getRule(&#39;.CodeMirror&#39;); if (css) { css.style.height = &#39;100%&#39;; css.style.position = &#39;relative&#39;; css.style.overflow = &#39;hidden&#39;; } var css = Ext.util.CSS.getRule(&#39;.CodeMirror-Scroll&#39;); if (css) { css.style.height = &#39;100%&#39;; } }, checkValid : function() { var errors = this.getErrors() || []; if (errors.length &gt; 0) { this.addCls(&#39;siesta-invalid-syntax&#39;); } else { this.removeCls(&#39;siesta-invalid-syntax&#39;); } }, getErrors : function() { }, <span id='global-method-relayBtnCmd'> /** </span> * @private */ relayBtnCmd : function (btn) { this.relayCmd(btn.getItemId()); }, <span id='global-method-relayCmd'> /** </span> * @private */ relayCmd : function (cmd) { Ext.defer(function () { var me = this; me.editor.focus(); switch (cmd) { // auto formatting case &#39;justifycenter&#39;: if (!CodeMirror.extensions.autoIndentRange) { me.loadDependencies(me.extensions.format, me.pathExtensions, me.doIndentSelection, me); } else { me.doIndentSelection(); } break; // line numbers case &#39;insertorderedlist&#39;: me.doChangeLineNumbers(); break; } }, 10, this); }, doChangeLineNumbers : function () { var me = this; me.enableLineNumbers = !me.enableLineNumbers; me.editor.setOption(&#39;lineNumbers&#39;, me.enableLineNumbers); }, <span id='global-method-doIndentSelection'> /** </span> * @private */ doIndentSelection : function () { var me = this; me.reloadExtentions(); try { var range = { from : me.editor.getCursor(true), to : me.editor.getCursor(false) }; me.editor.autoIndentRange(range.from, range.to); } catch (err) { } }, <span id='global-method-setReadOnly'> /** </span> * Set the editor as read only * * @param {Boolean} readOnly */ setReadOnly : function (readOnly) { var me = this; if (me.editor) { me.editor.setOption(&#39;readOnly&#39;, readOnly); } }, onDisable : function () { this.bodyEl.mask(); this.callParent(arguments); }, onEnable : function () { this.bodyEl.unmask(); this.callParent(arguments); }, <span id='global-method-setValue'> /** </span> * Sets a data value into the field and runs the change detection. * @param {Mixed} value The value to set * @return {Ext.ux.form.field.CodeMirror} this */ setValue : function (value) { value = value || &#39;&#39;; var me = this; // me.mixins.field.setValue.call(me, value); // me.rawValue = value; if (me.editor) { me.editor.setValue(value); } return me; }, <span id='global-method-getSubmitValue'> /** </span> * Return submit value to the owner form. * @return {Mixed} The field value */ getSubmitValue : function () { var me = this; return me.getValue(); }, getRawValue : function () { return this.getValue(); }, <span id='global-method-getValue'> /** </span> * Return the value of the CodeMirror editor * @return {Mixed} The field value */ getValue : function () { var me = this; if (me.editor) return me.editor.getValue() || &#39;&#39;; else return &#39;&#39;; }, <span id='global-method-onDestroy'> /** </span> * @private */ onDestroy : function () { var me = this; if (me.rendered) { for (var prop in me.editor) { if (me.editor.hasOwnProperty(prop)) { delete me.editor[prop]; } } Ext.destroyMembers(&#39;tb&#39;, &#39;toolbarWrap&#39;, &#39;editorEl&#39;); } me.callParent(); }, commentLine : function () { var editor = this.editor; var start = editor.getCursor(true); var end = editor.getCursor(false); var currentLine = start.line; var doFormat = false; function toggleCommented(line) { text = editor.getLine(line); if (text.match(/^\s*\/\/\s*/)) { text = text.replace(/\s*\/\/\s*/, &#39;&#39;); doFormat = true; } else { text = text.substr(0, text.indexOf(Ext.String.trim(text))) + &#39;// &#39; + Ext.String.trim(text); } editor.setLine(line, text); } if (start.line === end.line &amp;&amp; start.ch === end.ch) { toggleCommented(start.line); } else if (start.character == 0) { while (currentLine != end.line) { toggleCommented(currentLine); currentLine = editor.getLine(++currentLine); } editor.selectLines(start.line, start.ch, end.line, end.ch); } else { var text = editor.getSelection(); var diff = 1; if (text.match(/^\/\*/) &amp;&amp; text.match(/^\/\*/)) { text = text.substring(2, text.length - 2); diff = -1; doFormat = true; } else { text = &quot;/*&quot; + text + &quot;*/&quot;; } editor.replaceSelection(text); // following line crash // if (start.line == end.line) { // editor.setSelection(start.line, start.ch, end.line, end.ch+(diff*4)); // } else { // editor.setSelection(start.line, start.ch, end.line, end.ch+(diff*2)); // } } if (doFormat) { editor.autoIndentRange({ line : 0 }, { line : editor.lineCount() }); } } }); // //(function () { // CodeMirror.extendMode(&quot;css&quot;, { // commentStart : &quot;/*&quot;, // commentEnd : &quot;*/&quot;, // newlineAfterToken : function (type, content) { // return /^[;{}]$/.test(content); // } // }); // // CodeMirror.extendMode(&quot;javascript&quot;, { // commentStart : &quot;/*&quot;, // commentEnd : &quot;*/&quot;, // // FIXME semicolons inside of for // newlineAfterToken : function (type, content, textAfter, state) { // if (this.jsonMode) { // return /^[\[,{]$/.test(content) || /^}/.test(textAfter); // } else { // if (content == &quot;;&quot; &amp;&amp; state.lexical &amp;&amp; state.lexical.type == &quot;)&quot;) return false; // return /^[;{}]$/.test(content) &amp;&amp; !/^;/.test(textAfter); // } // } // }); // // CodeMirror.extendMode(&quot;xml&quot;, { // commentStart : &quot;&lt;!--&quot;, // commentEnd : &quot;--&gt;&quot;, // newlineAfterToken : function (type, content, textAfter) { // return type == &quot;tag&quot; &amp;&amp; /&gt;$/.test(content) || /^&lt;/.test(textAfter); // } // }); // // // Comment/uncomment the specified range // CodeMirror.defineExtension(&quot;commentRange&quot;, function (isComment, from, to) { // var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode; // cm.operation(function () { // if (isComment) { // Comment range // cm.replaceRange(curMode.commentEnd, to); // cm.replaceRange(curMode.commentStart, from); // if (from.line == to.line &amp;&amp; from.ch == to.ch) // An empty comment inserted - put cursor inside // cm.setCursor(from.line, from.ch + curMode.commentStart.length); // } else { // Uncomment range // var selText = cm.getRange(from, to); // var startIndex = selText.indexOf(curMode.commentStart); // var endIndex = selText.lastIndexOf(curMode.commentEnd); // if (startIndex &gt; -1 &amp;&amp; endIndex &gt; -1 &amp;&amp; endIndex &gt; startIndex) { // // Take string till comment start // selText = selText.substr(0, startIndex) // // From comment start till comment end // + selText.substring(startIndex + curMode.commentStart.length, endIndex) // // From comment end till string end // + selText.substr(endIndex + curMode.commentEnd.length); // } // cm.replaceRange(selText, from, to); // } // }); // }); // // // Applies automatic mode-aware indentation to the specified range // CodeMirror.defineExtension(&quot;autoIndentRange&quot;, function (from, to) { // var cmInstance = this; // this.operation(function () { // for (var i = from.line; i &lt;= to.line; i++) { // cmInstance.indentLine(i, &quot;smart&quot;); // } // }); // }); // // // Applies automatic formatting to the specified range // CodeMirror.defineExtension(&quot;autoFormatRange&quot;, function (from, to) { // var cm = this; // var outer = cm.getMode(), text = cm.getRange(from, to).split(&quot;\n&quot;); // var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state); // var tabSize = cm.getOption(&quot;tabSize&quot;); // // var out = &quot;&quot;, lines = 0, atSol = from.ch == 0; // // function newline() { // out += &quot;\n&quot;; // atSol = true; // ++lines; // } // // for (var i = 0; i &lt; text.length; ++i) { // var stream = new CodeMirror.StringStream(text[i], tabSize); // while (!stream.eol()) { // var inner = CodeMirror.innerMode(outer, state); // var style = outer.token(stream, state), cur = stream.current(); // stream.start = stream.pos; // if (!atSol || /\S/.test(cur)) { // out += cur; // atSol = false; // } // if (!atSol &amp;&amp; inner.mode.newlineAfterToken &amp;&amp; // inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i + 1] || &quot;&quot;, inner.state)) // newline(); // } // if (!stream.pos &amp;&amp; outer.blankLine) outer.blankLine(state); // if (!atSol) newline(); // } // // cm.operation(function () { // cm.replaceRange(out, from, to); // for (var cur = from.line + 1, end = from.line + lines; cur &lt;= end; ++cur) // cm.indentLine(cur, &quot;smart&quot;); // cm.setSelection(from, cm.getCursor(false)); // }); // }); //})(); </pre> </body> </html>