Esites_Editor - Version 0.3.0

Version Notes

Landed support for transactional emails, added a new code beautifier and implemented HTML autocompletion.

The GitHub repo can be found at: https://github.com/e-sites/magento-advanced-html-editor

Download this release

Release Info

Developer Boye Oomens
Extension Esites_Editor
Version 0.3.0
Comparing to
See all releases


Code changes from version 0.2.4 to 0.3.0

app/code/local/Esites/Editor/Model/Config.php CHANGED
@@ -53,6 +53,7 @@ class Esites_Editor_Model_Config extends Varien_Object
53
  'matchHighlight' => (bool) Mage::getStoreConfig('editor/prefs/matchHighlight', $store),
54
  'closeTags' => (bool) Mage::getStoreConfig('editor/prefs/closeTags', $store),
55
  'search' => (bool) Mage::getStoreConfig('editor/prefs/search', $store),
 
56
  'fontSize' => (string) Mage::getStoreConfig('editor/appearance/fontSize', $store),
57
  'keymap' => (string) Mage::getStoreConfig('editor/prefs/keymap', $store)
58
  )
53
  'matchHighlight' => (bool) Mage::getStoreConfig('editor/prefs/matchHighlight', $store),
54
  'closeTags' => (bool) Mage::getStoreConfig('editor/prefs/closeTags', $store),
55
  'search' => (bool) Mage::getStoreConfig('editor/prefs/search', $store),
56
+ 'completion' => (bool) Mage::getStoreConfig('editor/prefs/completion', $store),
57
  'fontSize' => (string) Mage::getStoreConfig('editor/appearance/fontSize', $store),
58
  'keymap' => (string) Mage::getStoreConfig('editor/prefs/keymap', $store)
59
  )
app/code/local/Esites/Editor/etc/config.xml CHANGED
@@ -22,7 +22,7 @@
22
  <config>
23
  <modules>
24
  <Esites_Editor>
25
- <version>0.2.1</version>
26
  </Esites_Editor>
27
  </modules>
28
 
@@ -55,6 +55,7 @@
55
  <matchHighlight>0</matchHighlight>
56
  <closeTags>1</closeTags>
57
  <search>1</search>
 
58
  </prefs>
59
  <appearance>
60
  <theme>default</theme>
22
  <config>
23
  <modules>
24
  <Esites_Editor>
25
+ <version>0.3.0</version>
26
  </Esites_Editor>
27
  </modules>
28
 
55
  <matchHighlight>0</matchHighlight>
56
  <closeTags>1</closeTags>
57
  <search>1</search>
58
+ <completion>0</completion>
59
  </prefs>
60
  <appearance>
61
  <theme>default</theme>
app/code/local/Esites/Editor/etc/system.xml CHANGED
@@ -119,7 +119,7 @@
119
  <show_in_default>1</show_in_default>
120
  <show_in_website>1</show_in_website>
121
  <show_in_store>0</show_in_store>
122
- <comment><![CDATA[Whether to show line numbers to the left of the editor.]]></comment>
123
  </lineWrapping>
124
  <matchTags>
125
  <label>Match tags</label>
@@ -161,6 +161,16 @@
161
  <show_in_store>0</show_in_store>
162
  <comment><![CDATA[Provides a dialog to search through the code]]></comment>
163
  </search>
 
 
 
 
 
 
 
 
 
 
164
  </fields>
165
  </prefs>
166
  <appearance translate="label" module="editor">
119
  <show_in_default>1</show_in_default>
120
  <show_in_website>1</show_in_website>
121
  <show_in_store>0</show_in_store>
122
+ <comment><![CDATA[Whether the editor should scroll or wrap for long lines.]]></comment>
123
  </lineWrapping>
124
  <matchTags>
125
  <label>Match tags</label>
161
  <show_in_store>0</show_in_store>
162
  <comment><![CDATA[Provides a dialog to search through the code]]></comment>
163
  </search>
164
+ <completion>
165
+ <label>Autocomplete</label>
166
+ <frontend_type>select</frontend_type>
167
+ <source_model>adminhtml/system_config_source_yesno</source_model>
168
+ <sort_order>6</sort_order>
169
+ <show_in_default>1</show_in_default>
170
+ <show_in_website>1</show_in_website>
171
+ <show_in_store>0</show_in_store>
172
+ <comment><![CDATA[HTML tag and attribute completion]]></comment>
173
+ </completion>
174
  </fields>
175
  </prefs>
176
  <appearance translate="label" module="editor">
js/tiny_mce/plugins/esites_editor/esites_editor_plugin.js CHANGED
@@ -1 +1 @@
1
- !function(){"use strict";var i,e="esites_editor",t=window.wysiwygpage_content||window.wysiwygblock_content,n=t.config.plugins,o=tinymce.each;tinymce.PluginManager.requireLangPack(e),tinymce.create("tinymce.plugins.EsitesEditorPlugin",{defaults:{emmet:!1,theme:"default",codeFolding:!1},settings:{},init:function(t,d){i=this,i.editor=t,i.url=d,o(n,function(t){t.name===e&&(i.settings=tinymce.extend(i.defaults,t.config))}),i.editor.addCommand("mceEsitesEditor",i.showSourceEditor),i.editor.addButton(e,{image:i.url+"/img/icon-esites-editor.png",title:e+".editor_button",cmd:"mceEsitesEditor"})},showSourceEditor:function(){i.editor.windowManager.open({width:i.editor.getParam("code_dialog_width",900),height:i.editor.getParam("code_dialog_height",600),inline:!0,maximizable:!0,file:i.url+"/esites_editor.html"},{plugin_url:i.url})}}),tinymce.PluginManager.add("esites_editor",tinymce.plugins.EsitesEditorPlugin)}();
1
+ !function(){"use strict";var i,e,t,n="esites_editor",o=tinymce.each,d=["wysiwygpage_content","wysiwygblock_content","wysiwygtemplate_text"];o(d,function(e){window[e]&&(i=window[e])}),i&&(e=i.config.plugins,tinymce.PluginManager.requireLangPack(n),tinymce.create("tinymce.plugins.EsitesEditorPlugin",{defaults:{emmet:!1,theme:"default",codeFolding:!1},settings:{},init:function(i,d){t=this,t.editor=i,t.url=d,o(e,function(i){i.name===n&&(t.settings=tinymce.extend(t.defaults,i.config))}),t.editor.addCommand("mceEsitesEditor",t.showSourceEditor),t.editor.addButton(n,{image:t.url+"/img/icon-esites-editor.png",title:n+".editor_button",cmd:"mceEsitesEditor"})},showSourceEditor:function(){t.editor.windowManager.open({width:t.editor.getParam("code_dialog_width",900),height:t.editor.getParam("code_dialog_height",600),inline:!0,maximizable:!0,file:t.url+"/esites_editor.html"},{plugin_url:t.url})}}),tinymce.PluginManager.add("esites_editor",tinymce.plugins.EsitesEditorPlugin))}();
js/tiny_mce/plugins/esites_editor/esites_editor_plugin_src.js CHANGED
@@ -3,9 +3,9 @@
3
  * This is the TinyMCE plugin of the Magento extension that incorporates the CodeMirror library
4
  *
5
  * @author : Boye Oomens <boye@e-sites.nl>
6
- * @version : 0.2.1
7
  * @license : OSL 3.0
8
- * @see : http://github.e-sites.nl/magento-advanced-html-editor/
9
  * @see : http://codemirror.net/
10
  * @see : http://emmet.io/
11
  */
@@ -15,13 +15,28 @@
15
 
16
  'use strict';
17
 
18
- var pluginName = 'esites_editor',
19
- /*jshint sub:true */
20
- section = window['wysiwygpage_content'] || window['wysiwygblock_content'],
21
- plugins = section.config.plugins,
22
  each = tinymce.each,
23
- tiny;
 
 
 
 
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  tinymce.PluginManager.requireLangPack(pluginName);
26
 
27
  tinymce.create('tinymce.plugins.EsitesEditorPlugin', {
3
  * This is the TinyMCE plugin of the Magento extension that incorporates the CodeMirror library
4
  *
5
  * @author : Boye Oomens <boye@e-sites.nl>
6
+ * @version : 0.3.0
7
  * @license : OSL 3.0
8
+ * @see : https://github.com/e-sites/magento-advanced-html-editor
9
  * @see : http://codemirror.net/
10
  * @see : http://emmet.io/
11
  */
15
 
16
  'use strict';
17
 
18
+ var section, plugins, tiny,
19
+ pluginName = 'esites_editor',
 
 
20
  each = tinymce.each,
21
+ sections = [
22
+ 'wysiwygpage_content',
23
+ 'wysiwygblock_content',
24
+ 'wysiwygtemplate_text'
25
+ ];
26
 
27
+ // Determine which section is currently active
28
+ each(sections, function (s) {
29
+ if ( window[s] ) {
30
+ section = window[s];
31
+ }
32
+ });
33
+
34
+ // Fail silently when we're dealing with an unknown section
35
+ if ( !section ) {
36
+ return;
37
+ }
38
+
39
+ plugins = section.config.plugins;
40
  tinymce.PluginManager.requireLangPack(pluginName);
41
 
42
  tinymce.create('tinymce.plugins.EsitesEditorPlugin', {
js/tiny_mce/plugins/esites_editor/js/app/main.js CHANGED
@@ -24,14 +24,15 @@
24
  '../app/var/deps',
25
  '../app/module/popup',
26
  '../app/module/util',
27
- '../app/module/editor',
28
  'codemirror/lib/codemirror',
 
 
29
  'codemirror/mode/htmlmixed/htmlmixed',
30
  'css!codemirror/addon/fold/foldgutter.css',
31
  'css!codemirror/addon/search/matchesonscrollbar.css',
32
  'css!codemirror/addon/dialog/dialog.css',
33
  'css!codemirror/addon/hint/show-hint.css'
34
- ], function (textarea, addons, cmOptions, plugin, deps, popup, util, editor, CodeMirror) {
35
 
36
  // Expose to global scope (needed for the formatting util)
37
  window.CodeMirror = CodeMirror;
@@ -43,7 +44,17 @@
43
  */
44
  function _prepareEditor() {
45
  /*jshint camelcase:false */
46
- textarea.value = tinyMCEPopup.editor.getContent({source_view : true});
 
 
 
 
 
 
 
 
 
 
47
 
48
  // Set custom font-size if it differs from the default value
49
  if ( plugin.settings.fontSize !== '12' ) {
@@ -81,11 +92,6 @@
81
  cm = CodeMirror.fromTextArea(textarea, cmOptions);
82
  cm.setSize(null, tinyMCEPopup.dom.getViewPort(window).h - 65);
83
 
84
- // Auto-format code
85
- if ( plugin.settings.autoFormat ) {
86
- editor.formatCode(cm);
87
- }
88
-
89
  // Load Emmet separately (if necessary)
90
  if ( plugin.settings.emmet ) {
91
  requirejs(['emmet/emmet'], function (emmetCodeMirror) {
24
  '../app/var/deps',
25
  '../app/module/popup',
26
  '../app/module/util',
 
27
  'codemirror/lib/codemirror',
28
+ 'beautify/beautify',
29
+ 'beautify/beautify-html',
30
  'codemirror/mode/htmlmixed/htmlmixed',
31
  'css!codemirror/addon/fold/foldgutter.css',
32
  'css!codemirror/addon/search/matchesonscrollbar.css',
33
  'css!codemirror/addon/dialog/dialog.css',
34
  'css!codemirror/addon/hint/show-hint.css'
35
+ ], function (textarea, addons, cmOptions, plugin, deps, popup, util, CodeMirror, js_beautify, formatter) {
36
 
37
  // Expose to global scope (needed for the formatting util)
38
  window.CodeMirror = CodeMirror;
44
  */
45
  function _prepareEditor() {
46
  /*jshint camelcase:false */
47
+ var code = tinyMCEPopup.editor.getContent({source_view : true});
48
+
49
+ // Auto-format code
50
+ if ( plugin.settings.autoFormat ) {
51
+ code = formatter.html_beautify(code, {
52
+ indent_size: plugin.settings.indentUnit,
53
+ wrap_line_length: 100
54
+ });
55
+ }
56
+
57
+ textarea.value = code;
58
 
59
  // Set custom font-size if it differs from the default value
60
  if ( plugin.settings.fontSize !== '12' ) {
92
  cm = CodeMirror.fromTextArea(textarea, cmOptions);
93
  cm.setSize(null, tinyMCEPopup.dom.getViewPort(window).h - 65);
94
 
 
 
 
 
 
95
  // Load Emmet separately (if necessary)
96
  if ( plugin.settings.emmet ) {
97
  requirejs(['emmet/emmet'], function (emmetCodeMirror) {
js/tiny_mce/plugins/esites_editor/js/app/module/editor.js CHANGED
@@ -1,46 +1,36 @@
1
  define([
2
  'codemirror/lib/codemirror'
3
  ], function (CodeMirror) {
4
- return {
 
 
5
 
6
- /**
7
- * Returns the selected range of the give editor instance
8
- *
9
- * @param {Object} editor CodeMirror instance
10
- * @return {Object}
11
- */
12
- getSelectedRange: function (editor) {
13
- return {
14
- from: editor.getCursor(true),
15
- to: editor.getCursor(false)
16
- };
17
- },
18
-
19
- /**
20
- * Handles all logic that's needed for code formatting
21
- *
22
- * @param {Object} editor CodeMirror instance
23
- */
24
- formatCode: function (editor) {
25
- var range, off,
26
- charWidth = editor.defaultCharWidth();
27
- basePadding = 4;
28
-
29
- CodeMirror.commands['selectAll'](editor);
30
-
31
- range = this.getSelectedRange(editor);
32
 
33
- editor.autoFormatRange(range.from, range.to);
34
- editor.scrollTo(0,0);
35
- editor.setCursor(0);
36
 
37
- editor.on('renderLine', function (editor, line, elt) {
38
- off = CodeMirror.countColumn(line.text, null, editor.getOption('tabSize')) * charWidth;
39
- elt.style.textIndent = '-' + off + 'px';
40
- elt.style.paddingLeft = (basePadding + off) + 'px';
41
  });
 
42
 
43
- editor.refresh();
 
 
 
 
 
 
44
  }
45
- }
 
 
46
  });
1
  define([
2
  'codemirror/lib/codemirror'
3
  ], function (CodeMirror) {
4
+ var ed = {
5
+ completeAfter: function (cm, pred) {
6
+ var cur = cm.getCursor();
7
 
8
+ if (!pred || pred()) setTimeout(function () {
9
+ if (!cm.state.completionActive)
10
+ cm.showHint({
11
+ completeSingle: false
12
+ });
13
+ }, 100);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ return CodeMirror.Pass;
16
+ },
 
17
 
18
+ completeIfAfterLt: function (cm) {
19
+ return ed.completeAfter(cm, function () {
20
+ var cur = cm.getCursor();
21
+ return cm.getRange(CodeMirror.Pos(cur.line, cur.ch - 1), cur) == "<";
22
  });
23
+ },
24
 
25
+ completeIfInTag: function (cm) {
26
+ return ed.completeAfter(cm, function () {
27
+ var tok = cm.getTokenAt(cm.getCursor());
28
+ if (tok.type == "string" && (!/['"]/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1)) return false;
29
+ var inner = CodeMirror.innerMode(cm.getMode(), tok.state).state;
30
+ return inner.tagName;
31
+ });
32
  }
33
+ };
34
+
35
+ return ed;
36
  });
js/tiny_mce/plugins/esites_editor/js/app/module/popup.js CHANGED
@@ -36,7 +36,7 @@
36
  tinyMCEPopup.close();
37
  return false;
38
  }
39
- }
40
  });
41
 
42
  }(tinyMCEPopup));
36
  tinyMCEPopup.close();
37
  return false;
38
  }
39
+ };
40
  });
41
 
42
  }(tinyMCEPopup));
js/tiny_mce/plugins/esites_editor/js/app/module/util.js CHANGED
@@ -78,7 +78,7 @@ define(function () {
78
 
79
  return proxy;
80
  }
81
- }
82
 
83
  return util;
84
  });
78
 
79
  return proxy;
80
  }
81
+ };
82
 
83
  return util;
84
  });
js/tiny_mce/plugins/esites_editor/js/app/var/addons.js CHANGED
@@ -1,4 +1,4 @@
1
- define(function () {
2
  return {
3
  'activeLine': {
4
  deps: [
@@ -19,6 +19,29 @@ define(function () {
19
  gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
20
  }
21
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  'lineWrapping': {
23
  deps: [
24
  'codemirror/addon/wrap/hardwrap'
1
+ define(['./plugin', '../module/editor'], function (plugin, editor) {
2
  return {
3
  'activeLine': {
4
  deps: [
19
  gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
20
  }
21
  },
22
+ 'completion': {
23
+ deps: [
24
+ 'codemirror/addon/hint/show-hint',
25
+ 'codemirror/addon/hint/xml-hint',
26
+ 'codemirror/addon/hint/html-hint'
27
+ ],
28
+ options: {
29
+ extraKeys: {
30
+ "'<'": editor.completeAfter,
31
+ "'/'": editor.completeIfAfterLt,
32
+ "' '": editor.completeIfInTag,
33
+ "Ctrl-Space": 'autocomplete'
34
+ }
35
+ }
36
+ },
37
+ 'keymap': {
38
+ deps: [
39
+ (plugin.settings.keymap !== 'default' ? 'codemirror/keymap/' + plugin.settings.keymap : '')
40
+ ],
41
+ options: {
42
+ keyMap: plugin.settings.keymap
43
+ }
44
+ },
45
  'lineWrapping': {
46
  deps: [
47
  'codemirror/addon/wrap/hardwrap'
js/tiny_mce/plugins/esites_editor/js/app/var/cmOptions.js CHANGED
@@ -1,6 +1,6 @@
1
  define(['./plugin'], function (plugin) {
2
  return {
3
- mode: 'text/html',
4
  lineNumbers: true,
5
  indentUnit: plugin.settings.indentUnit,
6
  theme: plugin.settings.theme,
1
  define(['./plugin'], function (plugin) {
2
  return {
3
+ mode: 'htmlmixed',
4
  lineNumbers: true,
5
  indentUnit: plugin.settings.indentUnit,
6
  theme: plugin.settings.theme,
js/tiny_mce/plugins/esites_editor/js/app/var/deps.js CHANGED
@@ -1,3 +1,3 @@
1
  define(function () {
2
- return ['codemirror/util/formatting'];
3
  });
1
  define(function () {
2
+ return [];
3
  });
js/tiny_mce/plugins/esites_editor/js/vendor/beautify/beautify-css.js ADDED
@@ -0,0 +1,491 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
2
+ /*
3
+
4
+ The MIT License (MIT)
5
+
6
+ Copyright (c) 2007-2013 Einar Lielmanis and contributors.
7
+
8
+ Permission is hereby granted, free of charge, to any person
9
+ obtaining a copy of this software and associated documentation files
10
+ (the "Software"), to deal in the Software without restriction,
11
+ including without limitation the rights to use, copy, modify, merge,
12
+ publish, distribute, sublicense, and/or sell copies of the Software,
13
+ and to permit persons to whom the Software is furnished to do so,
14
+ subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+
29
+ CSS Beautifier
30
+ ---------------
31
+
32
+ Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)
33
+
34
+ Based on code initially developed by: Einar Lielmanis, <einar@jsbeautifier.org>
35
+ http://jsbeautifier.org/
36
+
37
+ Usage:
38
+ css_beautify(source_text);
39
+ css_beautify(source_text, options);
40
+
41
+ The options are (default in brackets):
42
+ indent_size (4) — indentation size,
43
+ indent_char (space) — character to indent with,
44
+ selector_separator_newline (true) - separate selectors with newline or
45
+ not (e.g. "a,\nbr" or "a, br")
46
+ end_with_newline (false) - end with a newline
47
+ newline_between_rules (true) - add a new line after every css rule
48
+
49
+ e.g
50
+
51
+ css_beautify(css_source_text, {
52
+ 'indent_size': 1,
53
+ 'indent_char': '\t',
54
+ 'selector_separator': ' ',
55
+ 'end_with_newline': false,
56
+ 'newline_between_rules': true
57
+ });
58
+ */
59
+
60
+ // http://www.w3.org/TR/CSS21/syndata.html#tokenization
61
+ // http://www.w3.org/TR/css3-syntax/
62
+
63
+ (function() {
64
+ function css_beautify(source_text, options) {
65
+ options = options || {};
66
+ source_text = source_text || '';
67
+ // HACK: newline parsing inconsistent. This brute force normalizes the input.
68
+ source_text = source_text.replace(/\r\n|[\r\u2028\u2029]/g, '\n')
69
+
70
+ var indentSize = options.indent_size || 4;
71
+ var indentCharacter = options.indent_char || ' ';
72
+ var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline;
73
+ var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
74
+ var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules;
75
+ var eol = options.eol ? options.eol : '\n';
76
+
77
+ // compatibility
78
+ if (typeof indentSize === "string") {
79
+ indentSize = parseInt(indentSize, 10);
80
+ }
81
+
82
+ if(options.indent_with_tabs){
83
+ indentCharacter = '\t';
84
+ indentSize = 1;
85
+ }
86
+
87
+ eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n')
88
+
89
+
90
+ // tokenizer
91
+ var whiteRe = /^\s+$/;
92
+ var wordRe = /[\w$\-_]/;
93
+
94
+ var pos = -1,
95
+ ch;
96
+ var parenLevel = 0;
97
+
98
+ function next() {
99
+ ch = source_text.charAt(++pos);
100
+ return ch || '';
101
+ }
102
+
103
+ function peek(skipWhitespace) {
104
+ var result = '';
105
+ var prev_pos = pos;
106
+ if (skipWhitespace) {
107
+ eatWhitespace();
108
+ }
109
+ result = source_text.charAt(pos + 1) || '';
110
+ pos = prev_pos - 1;
111
+ next();
112
+ return result;
113
+ }
114
+
115
+ function eatString(endChars) {
116
+ var start = pos;
117
+ while (next()) {
118
+ if (ch === "\\") {
119
+ next();
120
+ } else if (endChars.indexOf(ch) !== -1) {
121
+ break;
122
+ } else if (ch === "\n") {
123
+ break;
124
+ }
125
+ }
126
+ return source_text.substring(start, pos + 1);
127
+ }
128
+
129
+ function peekString(endChar) {
130
+ var prev_pos = pos;
131
+ var str = eatString(endChar);
132
+ pos = prev_pos - 1;
133
+ next();
134
+ return str;
135
+ }
136
+
137
+ function eatWhitespace() {
138
+ var result = '';
139
+ while (whiteRe.test(peek())) {
140
+ next();
141
+ result += ch;
142
+ }
143
+ return result;
144
+ }
145
+
146
+ function skipWhitespace() {
147
+ var result = '';
148
+ if (ch && whiteRe.test(ch)) {
149
+ result = ch;
150
+ }
151
+ while (whiteRe.test(next())) {
152
+ result += ch;
153
+ }
154
+ return result;
155
+ }
156
+
157
+ function eatComment(singleLine) {
158
+ var start = pos;
159
+ singleLine = peek() === "/";
160
+ next();
161
+ while (next()) {
162
+ if (!singleLine && ch === "*" && peek() === "/") {
163
+ next();
164
+ break;
165
+ } else if (singleLine && ch === "\n") {
166
+ return source_text.substring(start, pos);
167
+ }
168
+ }
169
+
170
+ return source_text.substring(start, pos) + ch;
171
+ }
172
+
173
+
174
+ function lookBack(str) {
175
+ return source_text.substring(pos - str.length, pos).toLowerCase() ===
176
+ str;
177
+ }
178
+
179
+ // Nested pseudo-class if we are insideRule
180
+ // and the next special character found opens
181
+ // a new block
182
+ function foundNestedPseudoClass() {
183
+ var openParen = 0;
184
+ for (var i = pos + 1; i < source_text.length; i++) {
185
+ var ch = source_text.charAt(i);
186
+ if (ch === "{") {
187
+ return true;
188
+ } else if (ch === '(') {
189
+ // pseudoclasses can contain ()
190
+ openParen += 1;
191
+ } else if (ch === ')') {
192
+ if (openParen == 0) {
193
+ return false;
194
+ }
195
+ openParen -= 1;
196
+ } else if (ch === ";" || ch === "}") {
197
+ return false;
198
+ }
199
+ }
200
+ return false;
201
+ }
202
+
203
+ // printer
204
+ var basebaseIndentString = source_text.match(/^[\t ]*/)[0];
205
+ var singleIndent = new Array(indentSize + 1).join(indentCharacter);
206
+ var indentLevel = 0;
207
+ var nestedLevel = 0;
208
+
209
+ function indent() {
210
+ indentLevel++;
211
+ basebaseIndentString += singleIndent;
212
+ }
213
+
214
+ function outdent() {
215
+ indentLevel--;
216
+ basebaseIndentString = basebaseIndentString.slice(0, -indentSize);
217
+ }
218
+
219
+ var print = {};
220
+ print["{"] = function(ch) {
221
+ print.singleSpace();
222
+ output.push(ch);
223
+ print.newLine();
224
+ };
225
+ print["}"] = function(ch) {
226
+ print.newLine();
227
+ output.push(ch);
228
+ print.newLine();
229
+ };
230
+
231
+ print._lastCharWhitespace = function() {
232
+ return whiteRe.test(output[output.length - 1]);
233
+ };
234
+
235
+ print.newLine = function(keepWhitespace) {
236
+ if (output.length) {
237
+ if (!keepWhitespace && output[output.length - 1] !== '\n') {
238
+ print.trim();
239
+ }
240
+
241
+ output.push('\n');
242
+
243
+ if (basebaseIndentString) {
244
+ output.push(basebaseIndentString);
245
+ }
246
+ }
247
+ };
248
+ print.singleSpace = function() {
249
+ if (output.length && !print._lastCharWhitespace()) {
250
+ output.push(' ');
251
+ }
252
+ };
253
+
254
+ print.preserveSingleSpace = function() {
255
+ if (isAfterSpace) {
256
+ print.singleSpace();
257
+ }
258
+ };
259
+
260
+ print.trim = function() {
261
+ while (print._lastCharWhitespace()) {
262
+ output.pop();
263
+ }
264
+ };
265
+
266
+
267
+ var output = [];
268
+ /*_____________________--------------------_____________________*/
269
+
270
+ var insideRule = false;
271
+ var insidePropertyValue = false;
272
+ var enteringConditionalGroup = false;
273
+ var top_ch = '';
274
+ var last_top_ch = '';
275
+
276
+ while (true) {
277
+ var whitespace = skipWhitespace();
278
+ var isAfterSpace = whitespace !== '';
279
+ var isAfterNewline = whitespace.indexOf('\n') !== -1;
280
+ last_top_ch = top_ch;
281
+ top_ch = ch;
282
+
283
+ if (!ch) {
284
+ break;
285
+ } else if (ch === '/' && peek() === '*') { /* css comment */
286
+ var header = indentLevel === 0;
287
+
288
+ if (isAfterNewline || header) {
289
+ print.newLine();
290
+ }
291
+
292
+ output.push(eatComment());
293
+ print.newLine();
294
+ if (header) {
295
+ print.newLine(true);
296
+ }
297
+ } else if (ch === '/' && peek() === '/') { // single line comment
298
+ if (!isAfterNewline && last_top_ch !== '{' ) {
299
+ print.trim();
300
+ }
301
+ print.singleSpace();
302
+ output.push(eatComment());
303
+ print.newLine();
304
+ } else if (ch === '@') {
305
+ print.preserveSingleSpace();
306
+ output.push(ch);
307
+
308
+ // strip trailing space, if present, for hash property checks
309
+ var variableOrRule = peekString(": ,;{}()[]/='\"");
310
+
311
+ if (variableOrRule.match(/[ :]$/)) {
312
+ // we have a variable or pseudo-class, add it and insert one space before continuing
313
+ next();
314
+ variableOrRule = eatString(": ").replace(/\s$/, '');
315
+ output.push(variableOrRule);
316
+ print.singleSpace();
317
+ }
318
+
319
+ variableOrRule = variableOrRule.replace(/\s$/, '')
320
+
321
+ // might be a nesting at-rule
322
+ if (variableOrRule in css_beautify.NESTED_AT_RULE) {
323
+ nestedLevel += 1;
324
+ if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) {
325
+ enteringConditionalGroup = true;
326
+ }
327
+ }
328
+ } else if (ch === '#' && peek() === '{') {
329
+ print.preserveSingleSpace();
330
+ output.push(eatString('}'));
331
+ } else if (ch === '{') {
332
+ if (peek(true) === '}') {
333
+ eatWhitespace();
334
+ next();
335
+ print.singleSpace();
336
+ output.push("{}");
337
+ print.newLine();
338
+ if (newline_between_rules && indentLevel === 0) {
339
+ print.newLine(true);
340
+ }
341
+ } else {
342
+ indent();
343
+ print["{"](ch);
344
+ // when entering conditional groups, only rulesets are allowed
345
+ if (enteringConditionalGroup) {
346
+ enteringConditionalGroup = false;
347
+ insideRule = (indentLevel > nestedLevel);
348
+ } else {
349
+ // otherwise, declarations are also allowed
350
+ insideRule = (indentLevel >= nestedLevel);
351
+ }
352
+ }
353
+ } else if (ch === '}') {
354
+ outdent();
355
+ print["}"](ch);
356
+ insideRule = false;
357
+ insidePropertyValue = false;
358
+ if (nestedLevel) {
359
+ nestedLevel--;
360
+ }
361
+ if (newline_between_rules && indentLevel === 0) {
362
+ print.newLine(true);
363
+ }
364
+ } else if (ch === ":") {
365
+ eatWhitespace();
366
+ if ((insideRule || enteringConditionalGroup) &&
367
+ !(lookBack("&") || foundNestedPseudoClass())) {
368
+ // 'property: value' delimiter
369
+ // which could be in a conditional group query
370
+ insidePropertyValue = true;
371
+ output.push(':');
372
+ print.singleSpace();
373
+ } else {
374
+ // sass/less parent reference don't use a space
375
+ // sass nested pseudo-class don't use a space
376
+ if (peek() === ":") {
377
+ // pseudo-element
378
+ next();
379
+ output.push("::");
380
+ } else {
381
+ // pseudo-class
382
+ output.push(':');
383
+ }
384
+ }
385
+ } else if (ch === '"' || ch === '\'') {
386
+ print.preserveSingleSpace();
387
+ output.push(eatString(ch));
388
+ } else if (ch === ';') {
389
+ insidePropertyValue = false;
390
+ output.push(ch);
391
+ print.newLine();
392
+ } else if (ch === '(') { // may be a url
393
+ if (lookBack("url")) {
394
+ output.push(ch);
395
+ eatWhitespace();
396
+ if (next()) {
397
+ if (ch !== ')' && ch !== '"' && ch !== '\'') {
398
+ output.push(eatString(')'));
399
+ } else {
400
+ pos--;
401
+ }
402
+ }
403
+ } else {
404
+ parenLevel++;
405
+ print.preserveSingleSpace();
406
+ output.push(ch);
407
+ eatWhitespace();
408
+ }
409
+ } else if (ch === ')') {
410
+ output.push(ch);
411
+ parenLevel--;
412
+ } else if (ch === ',') {
413
+ output.push(ch);
414
+ eatWhitespace();
415
+ if (selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1) {
416
+ print.newLine();
417
+ } else {
418
+ print.singleSpace();
419
+ }
420
+ } else if (ch === ']') {
421
+ output.push(ch);
422
+ } else if (ch === '[') {
423
+ print.preserveSingleSpace();
424
+ output.push(ch);
425
+ } else if (ch === '=') { // no whitespace before or after
426
+ eatWhitespace()
427
+ ch = '=';
428
+ output.push(ch);
429
+ } else {
430
+ print.preserveSingleSpace();
431
+ output.push(ch);
432
+ }
433
+ }
434
+
435
+
436
+ var sweetCode = '';
437
+ if (basebaseIndentString) {
438
+ sweetCode += basebaseIndentString;
439
+ }
440
+
441
+ sweetCode += output.join('').replace(/[\r\n\t ]+$/, '');
442
+
443
+ // establish end_with_newline
444
+ if (end_with_newline) {
445
+ sweetCode += '\n';
446
+ }
447
+
448
+ if (eol != '\n') {
449
+ sweetCode = sweetCode.replace(/[\n]/g, eol);
450
+ }
451
+
452
+ return sweetCode;
453
+ }
454
+
455
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule
456
+ css_beautify.NESTED_AT_RULE = {
457
+ "@page": true,
458
+ "@font-face": true,
459
+ "@keyframes": true,
460
+ // also in CONDITIONAL_GROUP_RULE below
461
+ "@media": true,
462
+ "@supports": true,
463
+ "@document": true
464
+ };
465
+ css_beautify.CONDITIONAL_GROUP_RULE = {
466
+ "@media": true,
467
+ "@supports": true,
468
+ "@document": true
469
+ };
470
+
471
+ /*global define */
472
+ if (typeof define === "function" && define.amd) {
473
+ // Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
474
+ define([], function() {
475
+ return {
476
+ css_beautify: css_beautify
477
+ };
478
+ });
479
+ } else if (typeof exports !== "undefined") {
480
+ // Add support for CommonJS. Just put this file somewhere on your require.paths
481
+ // and you will be able to `var html_beautify = require("beautify").html_beautify`.
482
+ exports.css_beautify = css_beautify;
483
+ } else if (typeof window !== "undefined") {
484
+ // If we're running a web page and don't have either of the above, add our one global
485
+ window.css_beautify = css_beautify;
486
+ } else if (typeof global !== "undefined") {
487
+ // If we don't even have window, try global.
488
+ global.css_beautify = css_beautify;
489
+ }
490
+
491
+ }());
js/tiny_mce/plugins/esites_editor/js/vendor/beautify/beautify-html.js ADDED
@@ -0,0 +1,952 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
2
+ /*
3
+
4
+ The MIT License (MIT)
5
+
6
+ Copyright (c) 2007-2013 Einar Lielmanis and contributors.
7
+
8
+ Permission is hereby granted, free of charge, to any person
9
+ obtaining a copy of this software and associated documentation files
10
+ (the "Software"), to deal in the Software without restriction,
11
+ including without limitation the rights to use, copy, modify, merge,
12
+ publish, distribute, sublicense, and/or sell copies of the Software,
13
+ and to permit persons to whom the Software is furnished to do so,
14
+ subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+
29
+ Style HTML
30
+ ---------------
31
+
32
+ Written by Nochum Sossonko, (nsossonko@hotmail.com)
33
+
34
+ Based on code initially developed by: Einar Lielmanis, <einar@jsbeautifier.org>
35
+ http://jsbeautifier.org/
36
+
37
+ Usage:
38
+ style_html(html_source);
39
+
40
+ style_html(html_source, options);
41
+
42
+ The options are:
43
+ indent_inner_html (default false) — indent <head> and <body> sections,
44
+ indent_size (default 4) — indentation size,
45
+ indent_char (default space) — character to indent with,
46
+ wrap_line_length (default 250) - maximum amount of characters per line (0 = disable)
47
+ brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none"
48
+ put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are.
49
+ unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted
50
+ indent_scripts (default normal) - "keep"|"separate"|"normal"
51
+ preserve_newlines (default true) - whether existing line breaks before elements should be preserved
52
+ Only works before elements, not inside tags or for text.
53
+ max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk
54
+ indent_handlebars (default false) - format and indent {{#foo}} and {{/foo}}
55
+ end_with_newline (false) - end with a newline
56
+ extra_liners (default [head,body,/html]) -List of tags that should have an extra newline before them.
57
+
58
+ e.g.
59
+
60
+ style_html(html_source, {
61
+ 'indent_inner_html': false,
62
+ 'indent_size': 2,
63
+ 'indent_char': ' ',
64
+ 'wrap_line_length': 78,
65
+ 'brace_style': 'expand',
66
+ 'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u'],
67
+ 'preserve_newlines': true,
68
+ 'max_preserve_newlines': 5,
69
+ 'indent_handlebars': false,
70
+ 'extra_liners': ['/html']
71
+ });
72
+ */
73
+
74
+ (function() {
75
+
76
+ function trim(s) {
77
+ return s.replace(/^\s+|\s+$/g, '');
78
+ }
79
+
80
+ function ltrim(s) {
81
+ return s.replace(/^\s+/g, '');
82
+ }
83
+
84
+ function rtrim(s) {
85
+ return s.replace(/\s+$/g,'');
86
+ }
87
+
88
+ function style_html(html_source, options, js_beautify, css_beautify) {
89
+ //Wrapper function to invoke all the necessary constructors and deal with the output.
90
+
91
+ var multi_parser,
92
+ indent_inner_html,
93
+ indent_size,
94
+ indent_character,
95
+ wrap_line_length,
96
+ brace_style,
97
+ unformatted,
98
+ preserve_newlines,
99
+ max_preserve_newlines,
100
+ indent_handlebars,
101
+ wrap_attributes,
102
+ wrap_attributes_indent_size,
103
+ end_with_newline,
104
+ extra_liners,
105
+ eol;
106
+
107
+ options = options || {};
108
+
109
+ // backwards compatibility to 1.3.4
110
+ if ((options.wrap_line_length === undefined || parseInt(options.wrap_line_length, 10) === 0) &&
111
+ (options.max_char !== undefined && parseInt(options.max_char, 10) !== 0)) {
112
+ options.wrap_line_length = options.max_char;
113
+ }
114
+
115
+ indent_inner_html = (options.indent_inner_html === undefined) ? false : options.indent_inner_html;
116
+ indent_size = (options.indent_size === undefined) ? 4 : parseInt(options.indent_size, 10);
117
+ indent_character = (options.indent_char === undefined) ? ' ' : options.indent_char;
118
+ brace_style = (options.brace_style === undefined) ? 'collapse' : options.brace_style;
119
+ wrap_line_length = parseInt(options.wrap_line_length, 10) === 0 ? 32786 : parseInt(options.wrap_line_length || 250, 10);
120
+ unformatted = options.unformatted || ['a', 'span', 'img', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd',
121
+ 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike',
122
+ 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
123
+ preserve_newlines = (options.preserve_newlines === undefined) ? true : options.preserve_newlines;
124
+ max_preserve_newlines = preserve_newlines ?
125
+ (isNaN(parseInt(options.max_preserve_newlines, 10)) ? 32786 : parseInt(options.max_preserve_newlines, 10))
126
+ : 0;
127
+ indent_handlebars = (options.indent_handlebars === undefined) ? false : options.indent_handlebars;
128
+ wrap_attributes = (options.wrap_attributes === undefined) ? 'auto' : options.wrap_attributes;
129
+ wrap_attributes_indent_size = (options.wrap_attributes_indent_size === undefined) ? indent_size : parseInt(options.wrap_attributes_indent_size, 10) || indent_size;
130
+ end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
131
+ extra_liners = (typeof options.extra_liners == 'object') && options.extra_liners ?
132
+ options.extra_liners.concat() : (typeof options.extra_liners === 'string') ?
133
+ options.extra_liners.split(',') : 'head,body,/html'.split(',');
134
+ eol = options.eol ? options.eol : '\n';
135
+
136
+ if(options.indent_with_tabs){
137
+ indent_character = '\t';
138
+ indent_size = 1;
139
+ }
140
+
141
+ eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n')
142
+
143
+ function Parser() {
144
+
145
+ this.pos = 0; //Parser position
146
+ this.token = '';
147
+ this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
148
+ this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values
149
+ parent: 'parent1',
150
+ parentcount: 1,
151
+ parent1: ''
152
+ };
153
+ this.tag_type = '';
154
+ this.token_text = this.last_token = this.last_text = this.token_type = '';
155
+ this.newlines = 0;
156
+ this.indent_content = indent_inner_html;
157
+
158
+ this.Utils = { //Uilities made available to the various functions
159
+ whitespace: "\n\r\t ".split(''),
160
+ single_token: 'br,input,link,meta,source,!doctype,basefont,base,area,hr,wbr,param,img,isindex,embed'.split(','), //all the single tags for HTML
161
+ extra_liners: extra_liners, //for tags that need a line of whitespace before them
162
+ in_array: function(what, arr) {
163
+ for (var i = 0; i < arr.length; i++) {
164
+ if (what === arr[i]) {
165
+ return true;
166
+ }
167
+ }
168
+ return false;
169
+ }
170
+ };
171
+
172
+ // Return true if the given text is composed entirely of whitespace.
173
+ this.is_whitespace = function(text) {
174
+ for (var n = 0; n < text.length; text++) {
175
+ if (!this.Utils.in_array(text.charAt(n), this.Utils.whitespace)) {
176
+ return false;
177
+ }
178
+ }
179
+ return true;
180
+ };
181
+
182
+ this.traverse_whitespace = function() {
183
+ var input_char = '';
184
+
185
+ input_char = this.input.charAt(this.pos);
186
+ if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
187
+ this.newlines = 0;
188
+ while (this.Utils.in_array(input_char, this.Utils.whitespace)) {
189
+ if (preserve_newlines && input_char === '\n' && this.newlines <= max_preserve_newlines) {
190
+ this.newlines += 1;
191
+ }
192
+
193
+ this.pos++;
194
+ input_char = this.input.charAt(this.pos);
195
+ }
196
+ return true;
197
+ }
198
+ return false;
199
+ };
200
+
201
+ // Append a space to the given content (string array) or, if we are
202
+ // at the wrap_line_length, append a newline/indentation.
203
+ this.space_or_wrap = function(content) {
204
+ if (this.line_char_count >= this.wrap_line_length) { //insert a line when the wrap_line_length is reached
205
+ this.print_newline(false, content);
206
+ this.print_indentation(content);
207
+ } else {
208
+ this.line_char_count++;
209
+ content.push(' ');
210
+ }
211
+ };
212
+
213
+ this.get_content = function() { //function to capture regular content between tags
214
+ var input_char = '',
215
+ content = [],
216
+ space = false; //if a space is needed
217
+
218
+ while (this.input.charAt(this.pos) !== '<') {
219
+ if (this.pos >= this.input.length) {
220
+ return content.length ? content.join('') : ['', 'TK_EOF'];
221
+ }
222
+
223
+ if (this.traverse_whitespace()) {
224
+ this.space_or_wrap(content);
225
+ continue;
226
+ }
227
+
228
+ if (indent_handlebars) {
229
+ // Handlebars parsing is complicated.
230
+ // {{#foo}} and {{/foo}} are formatted tags.
231
+ // {{something}} should get treated as content, except:
232
+ // {{else}} specifically behaves like {{#if}} and {{/if}}
233
+ var peek3 = this.input.substr(this.pos, 3);
234
+ if (peek3 === '{{#' || peek3 === '{{/') {
235
+ // These are tags and not content.
236
+ break;
237
+ } else if (peek3 === '{{!') {
238
+ return [this.get_tag(), 'TK_TAG_HANDLEBARS_COMMENT'];
239
+ } else if (this.input.substr(this.pos, 2) === '{{') {
240
+ if (this.get_tag(true) === '{{else}}') {
241
+ break;
242
+ }
243
+ }
244
+ }
245
+
246
+ input_char = this.input.charAt(this.pos);
247
+ this.pos++;
248
+ this.line_char_count++;
249
+ content.push(input_char); //letter at-a-time (or string) inserted to an array
250
+ }
251
+ return content.length ? content.join('') : '';
252
+ };
253
+
254
+ this.get_contents_to = function(name) { //get the full content of a script or style to pass to js_beautify
255
+ if (this.pos === this.input.length) {
256
+ return ['', 'TK_EOF'];
257
+ }
258
+ var input_char = '';
259
+ var content = '';
260
+ var reg_match = new RegExp('</' + name + '\\s*>', 'igm');
261
+ reg_match.lastIndex = this.pos;
262
+ var reg_array = reg_match.exec(this.input);
263
+ var end_script = reg_array ? reg_array.index : this.input.length; //absolute end of script
264
+ if (this.pos < end_script) { //get everything in between the script tags
265
+ content = this.input.substring(this.pos, end_script);
266
+ this.pos = end_script;
267
+ }
268
+ return content;
269
+ };
270
+
271
+ this.record_tag = function(tag) { //function to record a tag and its parent in this.tags Object
272
+ if (this.tags[tag + 'count']) { //check for the existence of this tag type
273
+ this.tags[tag + 'count']++;
274
+ this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
275
+ } else { //otherwise initialize this tag type
276
+ this.tags[tag + 'count'] = 1;
277
+ this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
278
+ }
279
+ this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
280
+ this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
281
+ };
282
+
283
+ this.retrieve_tag = function(tag) { //function to retrieve the opening tag to the corresponding closer
284
+ if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it
285
+ var temp_parent = this.tags.parent; //check to see if it's a closable tag.
286
+ while (temp_parent) { //till we reach '' (the initial value);
287
+ if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it
288
+ break;
289
+ }
290
+ temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
291
+ }
292
+ if (temp_parent) { //if we caught something
293
+ this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
294
+ this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
295
+ }
296
+ delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
297
+ delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
298
+ if (this.tags[tag + 'count'] === 1) {
299
+ delete this.tags[tag + 'count'];
300
+ } else {
301
+ this.tags[tag + 'count']--;
302
+ }
303
+ }
304
+ };
305
+
306
+ this.indent_to_tag = function(tag) {
307
+ // Match the indentation level to the last use of this tag, but don't remove it.
308
+ if (!this.tags[tag + 'count']) {
309
+ return;
310
+ }
311
+ var temp_parent = this.tags.parent;
312
+ while (temp_parent) {
313
+ if (tag + this.tags[tag + 'count'] === temp_parent) {
314
+ break;
315
+ }
316
+ temp_parent = this.tags[temp_parent + 'parent'];
317
+ }
318
+ if (temp_parent) {
319
+ this.indent_level = this.tags[tag + this.tags[tag + 'count']];
320
+ }
321
+ };
322
+
323
+ this.get_tag = function(peek) { //function to get a full tag and parse its type
324
+ var input_char = '',
325
+ content = [],
326
+ comment = '',
327
+ space = false,
328
+ first_attr = true,
329
+ tag_start, tag_end,
330
+ tag_start_char,
331
+ orig_pos = this.pos,
332
+ orig_line_char_count = this.line_char_count;
333
+
334
+ peek = peek !== undefined ? peek : false;
335
+
336
+ do {
337
+ if (this.pos >= this.input.length) {
338
+ if (peek) {
339
+ this.pos = orig_pos;
340
+ this.line_char_count = orig_line_char_count;
341
+ }
342
+ return content.length ? content.join('') : ['', 'TK_EOF'];
343
+ }
344
+
345
+ input_char = this.input.charAt(this.pos);
346
+ this.pos++;
347
+
348
+ if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space
349
+ space = true;
350
+ continue;
351
+ }
352
+
353
+ if (input_char === "'" || input_char === '"') {
354
+ input_char += this.get_unformatted(input_char);
355
+ space = true;
356
+
357
+ }
358
+
359
+ if (input_char === '=') { //no space before =
360
+ space = false;
361
+ }
362
+
363
+ if (content.length && content[content.length - 1] !== '=' && input_char !== '>' && space) {
364
+ //no space after = or before >
365
+ this.space_or_wrap(content);
366
+ space = false;
367
+ if (!first_attr && wrap_attributes === 'force' && input_char !== '/') {
368
+ this.print_newline(true, content);
369
+ this.print_indentation(content);
370
+ for (var count = 0; count < wrap_attributes_indent_size; count++) {
371
+ content.push(indent_character);
372
+ }
373
+ }
374
+ for (var i = 0; i < content.length; i++) {
375
+ if (content[i] === ' ') {
376
+ first_attr = false;
377
+ break;
378
+ }
379
+ }
380
+ }
381
+
382
+ if (indent_handlebars && tag_start_char === '<') {
383
+ // When inside an angle-bracket tag, put spaces around
384
+ // handlebars not inside of strings.
385
+ if ((input_char + this.input.charAt(this.pos)) === '{{') {
386
+ input_char += this.get_unformatted('}}');
387
+ if (content.length && content[content.length - 1] !== ' ' && content[content.length - 1] !== '<') {
388
+ input_char = ' ' + input_char;
389
+ }
390
+ space = true;
391
+ }
392
+ }
393
+
394
+ if (input_char === '<' && !tag_start_char) {
395
+ tag_start = this.pos - 1;
396
+ tag_start_char = '<';
397
+ }
398
+
399
+ if (indent_handlebars && !tag_start_char) {
400
+ if (content.length >= 2 && content[content.length - 1] === '{' && content[content.length - 2] === '{') {
401
+ if (input_char === '#' || input_char === '/' || input_char === '!') {
402
+ tag_start = this.pos - 3;
403
+ } else {
404
+ tag_start = this.pos - 2;
405
+ }
406
+ tag_start_char = '{';
407
+ }
408
+ }
409
+
410
+ this.line_char_count++;
411
+ content.push(input_char); //inserts character at-a-time (or string)
412
+
413
+ if (content[1] && (content[1] === '!' || content[1] === '?' || content[1] === '%')) { //if we're in a comment, do something special
414
+ // We treat all comments as literals, even more than preformatted tags
415
+ // we just look for the appropriate close tag
416
+ content = [this.get_comment(tag_start)];
417
+ break;
418
+ }
419
+
420
+ if (indent_handlebars && content[1] && content[1] === '{' && content[2] && content[2] === '!') { //if we're in a comment, do something special
421
+ // We treat all comments as literals, even more than preformatted tags
422
+ // we just look for the appropriate close tag
423
+ content = [this.get_comment(tag_start)];
424
+ break;
425
+ }
426
+
427
+ if (indent_handlebars && tag_start_char === '{' && content.length > 2 && content[content.length - 2] === '}' && content[content.length - 1] === '}') {
428
+ break;
429
+ }
430
+ } while (input_char !== '>');
431
+
432
+ var tag_complete = content.join('');
433
+ var tag_index;
434
+ var tag_offset;
435
+
436
+ if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends
437
+ tag_index = tag_complete.indexOf(' ');
438
+ } else if (tag_complete.charAt(0) === '{') {
439
+ tag_index = tag_complete.indexOf('}');
440
+ } else { //otherwise go with the tag ending
441
+ tag_index = tag_complete.indexOf('>');
442
+ }
443
+ if (tag_complete.charAt(0) === '<' || !indent_handlebars) {
444
+ tag_offset = 1;
445
+ } else {
446
+ tag_offset = tag_complete.charAt(2) === '#' ? 3 : 2;
447
+ }
448
+ var tag_check = tag_complete.substring(tag_offset, tag_index).toLowerCase();
449
+ if (tag_complete.charAt(tag_complete.length - 2) === '/' ||
450
+ this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /)
451
+ if (!peek) {
452
+ this.tag_type = 'SINGLE';
453
+ }
454
+ } else if (indent_handlebars && tag_complete.charAt(0) === '{' && tag_check === 'else') {
455
+ if (!peek) {
456
+ this.indent_to_tag('if');
457
+ this.tag_type = 'HANDLEBARS_ELSE';
458
+ this.indent_content = true;
459
+ this.traverse_whitespace();
460
+ }
461
+ } else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags
462
+ comment = this.get_unformatted('</' + tag_check + '>', tag_complete); //...delegate to get_unformatted function
463
+ content.push(comment);
464
+ tag_end = this.pos - 1;
465
+ this.tag_type = 'SINGLE';
466
+ } else if (tag_check === 'script' &&
467
+ (tag_complete.search('type') === -1 ||
468
+ (tag_complete.search('type') > -1 &&
469
+ tag_complete.search(/\b(text|application)\/(x-)?(javascript|ecmascript|jscript|livescript)/) > -1))) {
470
+ if (!peek) {
471
+ this.record_tag(tag_check);
472
+ this.tag_type = 'SCRIPT';
473
+ }
474
+ } else if (tag_check === 'style' &&
475
+ (tag_complete.search('type') === -1 ||
476
+ (tag_complete.search('type') > -1 && tag_complete.search('text/css') > -1))) {
477
+ if (!peek) {
478
+ this.record_tag(tag_check);
479
+ this.tag_type = 'STYLE';
480
+ }
481
+ } else if (tag_check.charAt(0) === '!') { //peek for <! comment
482
+ // for comments content is already correct.
483
+ if (!peek) {
484
+ this.tag_type = 'SINGLE';
485
+ this.traverse_whitespace();
486
+ }
487
+ } else if (!peek) {
488
+ if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending
489
+ this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
490
+ this.tag_type = 'END';
491
+ } else { //otherwise it's a start-tag
492
+ this.record_tag(tag_check); //push it on the tag stack
493
+ if (tag_check.toLowerCase() !== 'html') {
494
+ this.indent_content = true;
495
+ }
496
+ this.tag_type = 'START';
497
+ }
498
+
499
+ // Allow preserving of newlines after a start or end tag
500
+ if (this.traverse_whitespace()) {
501
+ this.space_or_wrap(content);
502
+ }
503
+
504
+ if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line
505
+ this.print_newline(false, this.output);
506
+ if (this.output.length && this.output[this.output.length - 2] !== '\n') {
507
+ this.print_newline(true, this.output);
508
+ }
509
+ }
510
+ }
511
+
512
+ if (peek) {
513
+ this.pos = orig_pos;
514
+ this.line_char_count = orig_line_char_count;
515
+ }
516
+
517
+ return content.join(''); //returns fully formatted tag
518
+ };
519
+
520
+ this.get_comment = function(start_pos) { //function to return comment content in its entirety
521
+ // this is will have very poor perf, but will work for now.
522
+ var comment = '',
523
+ delimiter = '>',
524
+ matched = false;
525
+
526
+ this.pos = start_pos;
527
+ input_char = this.input.charAt(this.pos);
528
+ this.pos++;
529
+
530
+ while (this.pos <= this.input.length) {
531
+ comment += input_char;
532
+
533
+ // only need to check for the delimiter if the last chars match
534
+ if (comment.charAt(comment.length - 1) === delimiter.charAt(delimiter.length - 1) &&
535
+ comment.indexOf(delimiter) !== -1) {
536
+ break;
537
+ }
538
+
539
+ // only need to search for custom delimiter for the first few characters
540
+ if (!matched && comment.length < 10) {
541
+ if (comment.indexOf('<![if') === 0) { //peek for <![if conditional comment
542
+ delimiter = '<![endif]>';
543
+ matched = true;
544
+ } else if (comment.indexOf('<![cdata[') === 0) { //if it's a <[cdata[ comment...
545
+ delimiter = ']]>';
546
+ matched = true;
547
+ } else if (comment.indexOf('<![') === 0) { // some other ![ comment? ...
548
+ delimiter = ']>';
549
+ matched = true;
550
+ } else if (comment.indexOf('<!--') === 0) { // <!-- comment ...
551
+ delimiter = '-->';
552
+ matched = true;
553
+ } else if (comment.indexOf('{{!') === 0) { // {{! handlebars comment
554
+ delimiter = '}}';
555
+ matched = true;
556
+ } else if (comment.indexOf('<?') === 0) { // {{! handlebars comment
557
+ delimiter = '?>';
558
+ matched = true;
559
+ } else if (comment.indexOf('<%') === 0) { // {{! handlebars comment
560
+ delimiter = '%>';
561
+ matched = true;
562
+ }
563
+ }
564
+
565
+ input_char = this.input.charAt(this.pos);
566
+ this.pos++;
567
+ }
568
+
569
+ return comment;
570
+ };
571
+
572
+ this.get_unformatted = function(delimiter, orig_tag) { //function to return unformatted content in its entirety
573
+
574
+ if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {
575
+ return '';
576
+ }
577
+ var input_char = '';
578
+ var content = '';
579
+ var min_index = 0;
580
+ var space = true;
581
+ do {
582
+
583
+ if (this.pos >= this.input.length) {
584
+ return content;
585
+ }
586
+
587
+ input_char = this.input.charAt(this.pos);
588
+ this.pos++;
589
+
590
+ if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
591
+ if (!space) {
592
+ this.line_char_count--;
593
+ continue;
594
+ }
595
+ if (input_char === '\n' || input_char === '\r') {
596
+ content += '\n';
597
+ /* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect <pre> tags if they are specified in the 'unformatted array'
598
+ for (var i=0; i<this.indent_level; i++) {
599
+ content += this.indent_string;
600
+ }
601
+ space = false; //...and make sure other indentation is erased
602
+ */
603
+ this.line_char_count = 0;
604
+ continue;
605
+ }
606
+ }
607
+ content += input_char;
608
+ this.line_char_count++;
609
+ space = true;
610
+
611
+ if (indent_handlebars && input_char === '{' && content.length && content.charAt(content.length - 2) === '{') {
612
+ // Handlebars expressions in strings should also be unformatted.
613
+ content += this.get_unformatted('}}');
614
+ // These expressions are opaque. Ignore delimiters found in them.
615
+ min_index = content.length;
616
+ }
617
+ } while (content.toLowerCase().indexOf(delimiter, min_index) === -1);
618
+ return content;
619
+ };
620
+
621
+ this.get_token = function() { //initial handler for token-retrieval
622
+ var token;
623
+
624
+ if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE') { //check if we need to format javascript
625
+ var type = this.last_token.substr(7);
626
+ token = this.get_contents_to(type);
627
+ if (typeof token !== 'string') {
628
+ return token;
629
+ }
630
+ return [token, 'TK_' + type];
631
+ }
632
+ if (this.current_mode === 'CONTENT') {
633
+ token = this.get_content();
634
+ if (typeof token !== 'string') {
635
+ return token;
636
+ } else {
637
+ return [token, 'TK_CONTENT'];
638
+ }
639
+ }
640
+
641
+ if (this.current_mode === 'TAG') {
642
+ token = this.get_tag();
643
+ if (typeof token !== 'string') {
644
+ return token;
645
+ } else {
646
+ var tag_name_type = 'TK_TAG_' + this.tag_type;
647
+ return [token, tag_name_type];
648
+ }
649
+ }
650
+ };
651
+
652
+ this.get_full_indent = function(level) {
653
+ level = this.indent_level + level || 0;
654
+ if (level < 1) {
655
+ return '';
656
+ }
657
+
658
+ return Array(level + 1).join(this.indent_string);
659
+ };
660
+
661
+ this.is_unformatted = function(tag_check, unformatted) {
662
+ //is this an HTML5 block-level link?
663
+ if (!this.Utils.in_array(tag_check, unformatted)) {
664
+ return false;
665
+ }
666
+
667
+ if (tag_check.toLowerCase() !== 'a' || !this.Utils.in_array('a', unformatted)) {
668
+ return true;
669
+ }
670
+
671
+ //at this point we have an tag; is its first child something we want to remain
672
+ //unformatted?
673
+ var next_tag = this.get_tag(true /* peek. */ );
674
+
675
+ // test next_tag to see if it is just html tag (no external content)
676
+ var tag = (next_tag || "").match(/^\s*<\s*\/?([a-z]*)\s*[^>]*>\s*$/);
677
+
678
+ // if next_tag comes back but is not an isolated tag, then
679
+ // let's treat the 'a' tag as having content
680
+ // and respect the unformatted option
681
+ if (!tag || this.Utils.in_array(tag, unformatted)) {
682
+ return true;
683
+ } else {
684
+ return false;
685
+ }
686
+ };
687
+
688
+ this.printer = function(js_source, indent_character, indent_size, wrap_line_length, brace_style) { //handles input/output and some other printing functions
689
+
690
+ this.input = js_source || ''; //gets the input for the Parser
691
+
692
+ // HACK: newline parsing inconsistent. This brute force normalizes the input.
693
+ this.input = this.input.replace(/\r\n|[\r\u2028\u2029]/g, '\n')
694
+
695
+ this.output = [];
696
+ this.indent_character = indent_character;
697
+ this.indent_string = '';
698
+ this.indent_size = indent_size;
699
+ this.brace_style = brace_style;
700
+ this.indent_level = 0;
701
+ this.wrap_line_length = wrap_line_length;
702
+ this.line_char_count = 0; //count to see if wrap_line_length was exceeded
703
+
704
+ for (var i = 0; i < this.indent_size; i++) {
705
+ this.indent_string += this.indent_character;
706
+ }
707
+
708
+ this.print_newline = function(force, arr) {
709
+ this.line_char_count = 0;
710
+ if (!arr || !arr.length) {
711
+ return;
712
+ }
713
+ if (force || (arr[arr.length - 1] !== '\n')) { //we might want the extra line
714
+ if ((arr[arr.length - 1] !== '\n')) {
715
+ arr[arr.length - 1] = rtrim(arr[arr.length - 1]);
716
+ }
717
+ arr.push('\n');
718
+ }
719
+ };
720
+
721
+ this.print_indentation = function(arr) {
722
+ for (var i = 0; i < this.indent_level; i++) {
723
+ arr.push(this.indent_string);
724
+ this.line_char_count += this.indent_string.length;
725
+ }
726
+ };
727
+
728
+ this.print_token = function(text) {
729
+ // Avoid printing initial whitespace.
730
+ if (this.is_whitespace(text) && !this.output.length) {
731
+ return;
732
+ }
733
+ if (text || text !== '') {
734
+ if (this.output.length && this.output[this.output.length - 1] === '\n') {
735
+ this.print_indentation(this.output);
736
+ text = ltrim(text);
737
+ }
738
+ }
739
+ this.print_token_raw(text);
740
+ };
741
+
742
+ this.print_token_raw = function(text) {
743
+ // If we are going to print newlines, truncate trailing
744
+ // whitespace, as the newlines will represent the space.
745
+ if (this.newlines > 0) {
746
+ text = rtrim(text);
747
+ }
748
+
749
+ if (text && text !== '') {
750
+ if (text.length > 1 && text.charAt(text.length - 1) === '\n') {
751
+ // unformatted tags can grab newlines as their last character
752
+ this.output.push(text.slice(0, -1));
753
+ this.print_newline(false, this.output);
754
+ } else {
755
+ this.output.push(text);
756
+ }
757
+ }
758
+
759
+ for (var n = 0; n < this.newlines; n++) {
760
+ this.print_newline(n > 0, this.output);
761
+ }
762
+ this.newlines = 0;
763
+ };
764
+
765
+ this.indent = function() {
766
+ this.indent_level++;
767
+ };
768
+
769
+ this.unindent = function() {
770
+ if (this.indent_level > 0) {
771
+ this.indent_level--;
772
+ }
773
+ };
774
+ };
775
+ return this;
776
+ }
777
+
778
+ /*_____________________--------------------_____________________*/
779
+
780
+ multi_parser = new Parser(); //wrapping functions Parser
781
+ multi_parser.printer(html_source, indent_character, indent_size, wrap_line_length, brace_style); //initialize starting values
782
+
783
+ while (true) {
784
+ var t = multi_parser.get_token();
785
+ multi_parser.token_text = t[0];
786
+ multi_parser.token_type = t[1];
787
+
788
+ if (multi_parser.token_type === 'TK_EOF') {
789
+ break;
790
+ }
791
+
792
+ switch (multi_parser.token_type) {
793
+ case 'TK_TAG_START':
794
+ multi_parser.print_newline(false, multi_parser.output);
795
+ multi_parser.print_token(multi_parser.token_text);
796
+ if (multi_parser.indent_content) {
797
+ multi_parser.indent();
798
+ multi_parser.indent_content = false;
799
+ }
800
+ multi_parser.current_mode = 'CONTENT';
801
+ break;
802
+ case 'TK_TAG_STYLE':
803
+ case 'TK_TAG_SCRIPT':
804
+ multi_parser.print_newline(false, multi_parser.output);
805
+ multi_parser.print_token(multi_parser.token_text);
806
+ multi_parser.current_mode = 'CONTENT';
807
+ break;
808
+ case 'TK_TAG_END':
809
+ //Print new line only if the tag has no content and has child
810
+ if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
811
+ var tag_name = multi_parser.token_text.match(/\w+/)[0];
812
+ var tag_extracted_from_last_output = null;
813
+ if (multi_parser.output.length) {
814
+ tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length - 1].match(/(?:<|{{#)\s*(\w+)/);
815
+ }
816
+ if (tag_extracted_from_last_output === null ||
817
+ (tag_extracted_from_last_output[1] !== tag_name && !multi_parser.Utils.in_array(tag_extracted_from_last_output[1], unformatted))) {
818
+ multi_parser.print_newline(false, multi_parser.output);
819
+ }
820
+ }
821
+ multi_parser.print_token(multi_parser.token_text);
822
+ multi_parser.current_mode = 'CONTENT';
823
+ break;
824
+ case 'TK_TAG_SINGLE':
825
+ // Don't add a newline before elements that should remain unformatted.
826
+ var tag_check = multi_parser.token_text.match(/^\s*<([a-z-]+)/i);
827
+ if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)) {
828
+ multi_parser.print_newline(false, multi_parser.output);
829
+ }
830
+ multi_parser.print_token(multi_parser.token_text);
831
+ multi_parser.current_mode = 'CONTENT';
832
+ break;
833
+ case 'TK_TAG_HANDLEBARS_ELSE':
834
+ multi_parser.print_token(multi_parser.token_text);
835
+ if (multi_parser.indent_content) {
836
+ multi_parser.indent();
837
+ multi_parser.indent_content = false;
838
+ }
839
+ multi_parser.current_mode = 'CONTENT';
840
+ break;
841
+ case 'TK_TAG_HANDLEBARS_COMMENT':
842
+ multi_parser.print_token(multi_parser.token_text);
843
+ multi_parser.current_mode = 'TAG';
844
+ break;
845
+ case 'TK_CONTENT':
846
+ multi_parser.print_token(multi_parser.token_text);
847
+ multi_parser.current_mode = 'TAG';
848
+ break;
849
+ case 'TK_STYLE':
850
+ case 'TK_SCRIPT':
851
+ if (multi_parser.token_text !== '') {
852
+ multi_parser.print_newline(false, multi_parser.output);
853
+ var text = multi_parser.token_text,
854
+ _beautifier,
855
+ script_indent_level = 1;
856
+ if (multi_parser.token_type === 'TK_SCRIPT') {
857
+ _beautifier = typeof js_beautify === 'function' && js_beautify;
858
+ } else if (multi_parser.token_type === 'TK_STYLE') {
859
+ _beautifier = typeof css_beautify === 'function' && css_beautify;
860
+ }
861
+
862
+ if (options.indent_scripts === "keep") {
863
+ script_indent_level = 0;
864
+ } else if (options.indent_scripts === "separate") {
865
+ script_indent_level = -multi_parser.indent_level;
866
+ }
867
+
868
+ var indentation = multi_parser.get_full_indent(script_indent_level);
869
+ if (_beautifier) {
870
+
871
+ // call the Beautifier if avaliable
872
+ var Child_options = function() {
873
+ this.eol = '\n';
874
+ };
875
+ Child_options.prototype = options;
876
+ var child_options = new Child_options();
877
+ text = _beautifier(text.replace(/^\s*/, indentation), child_options);
878
+ } else {
879
+ // simply indent the string otherwise
880
+ var white = text.match(/^\s*/)[0];
881
+ var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
882
+ var reindent = multi_parser.get_full_indent(script_indent_level - _level);
883
+ text = text.replace(/^\s*/, indentation)
884
+ .replace(/\r\n|\r|\n/g, '\n' + reindent)
885
+ .replace(/\s+$/, '');
886
+ }
887
+ if (text) {
888
+ multi_parser.print_token_raw(text);
889
+ multi_parser.print_newline(true, multi_parser.output);
890
+ }
891
+ }
892
+ multi_parser.current_mode = 'TAG';
893
+ break;
894
+ default:
895
+ // We should not be getting here but we don't want to drop input on the floor
896
+ // Just output the text and move on
897
+ if (multi_parser.token_text !== '') {
898
+ multi_parser.print_token(multi_parser.token_text);
899
+ }
900
+ break;
901
+ }
902
+ multi_parser.last_token = multi_parser.token_type;
903
+ multi_parser.last_text = multi_parser.token_text;
904
+ }
905
+ var sweet_code = multi_parser.output.join('').replace(/[\r\n\t ]+$/, '');
906
+
907
+ // establish end_with_newline
908
+ if (end_with_newline) {
909
+ sweet_code += '\n';
910
+ }
911
+
912
+ if (eol != '\n') {
913
+ sweet_code = sweet_code.replace(/[\n]/g, eol);
914
+ }
915
+
916
+ return sweet_code;
917
+ }
918
+
919
+ if (typeof define === "function" && define.amd) {
920
+ // Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
921
+ define(["require", "./beautify", "./beautify-css"], function(requireamd) {
922
+ var js_beautify = requireamd("./beautify");
923
+ var css_beautify = requireamd("./beautify-css");
924
+
925
+ return {
926
+ html_beautify: function(html_source, options) {
927
+ return style_html(html_source, options, js_beautify.js_beautify, css_beautify.css_beautify);
928
+ }
929
+ };
930
+ });
931
+ } else if (typeof exports !== "undefined") {
932
+ // Add support for CommonJS. Just put this file somewhere on your require.paths
933
+ // and you will be able to `var html_beautify = require("beautify").html_beautify`.
934
+ var js_beautify = require('./beautify.js');
935
+ var css_beautify = require('./beautify-css.js');
936
+
937
+ exports.html_beautify = function(html_source, options) {
938
+ return style_html(html_source, options, js_beautify.js_beautify, css_beautify.css_beautify);
939
+ };
940
+ } else if (typeof window !== "undefined") {
941
+ // If we're running a web page and don't have either of the above, add our one global
942
+ window.html_beautify = function(html_source, options) {
943
+ return style_html(html_source, options, window.js_beautify, window.css_beautify);
944
+ };
945
+ } else if (typeof global !== "undefined") {
946
+ // If we don't even have window, try global.
947
+ global.html_beautify = function(html_source, options) {
948
+ return style_html(html_source, options, global.js_beautify, global.css_beautify);
949
+ };
950
+ }
951
+
952
+ }());
js/tiny_mce/plugins/esites_editor/js/vendor/beautify/beautify.js ADDED
@@ -0,0 +1,2085 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
2
+ /*
3
+
4
+ The MIT License (MIT)
5
+
6
+ Copyright (c) 2007-2013 Einar Lielmanis and contributors.
7
+
8
+ Permission is hereby granted, free of charge, to any person
9
+ obtaining a copy of this software and associated documentation files
10
+ (the "Software"), to deal in the Software without restriction,
11
+ including without limitation the rights to use, copy, modify, merge,
12
+ publish, distribute, sublicense, and/or sell copies of the Software,
13
+ and to permit persons to whom the Software is furnished to do so,
14
+ subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ JS Beautifier
29
+ ---------------
30
+
31
+
32
+ Written by Einar Lielmanis, <einar@jsbeautifier.org>
33
+ http://jsbeautifier.org/
34
+
35
+ Originally converted to javascript by Vital, <vital76@gmail.com>
36
+ "End braces on own line" added by Chris J. Shull, <chrisjshull@gmail.com>
37
+ Parsing improvements for brace-less statements by Liam Newman <bitwiseman@gmail.com>
38
+
39
+
40
+ Usage:
41
+ js_beautify(js_source_text);
42
+ js_beautify(js_source_text, options);
43
+
44
+ The options are:
45
+ indent_size (default 4) - indentation size,
46
+ indent_char (default space) - character to indent with,
47
+ preserve_newlines (default true) - whether existing line breaks should be preserved,
48
+ max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk,
49
+
50
+ jslint_happy (default false) - if true, then jslint-stricter mode is enforced.
51
+
52
+ jslint_happy !jslint_happy
53
+ ---------------------------------
54
+ function () function()
55
+
56
+ switch () { switch() {
57
+ case 1: case 1:
58
+ break; break;
59
+ } }
60
+
61
+ space_after_anon_function (default false) - should the space before an anonymous function's parens be added, "function()" vs "function ()",
62
+ NOTE: This option is overriden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design)
63
+
64
+ brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none"
65
+ put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are.
66
+
67
+ space_before_conditional (default true) - should the space before conditional statement be added, "if(true)" vs "if (true)",
68
+
69
+ unescape_strings (default false) - should printable characters in strings encoded in \xNN notation be unescaped, "example" vs "\x65\x78\x61\x6d\x70\x6c\x65"
70
+
71
+ wrap_line_length (default unlimited) - lines should wrap at next opportunity after this number of characters.
72
+ NOTE: This is not a hard limit. Lines will continue until a point where a newline would
73
+ be preserved if it were present.
74
+
75
+ end_with_newline (default false) - end output with a newline
76
+
77
+
78
+ e.g
79
+
80
+ js_beautify(js_source_text, {
81
+ 'indent_size': 1,
82
+ 'indent_char': '\t'
83
+ });
84
+
85
+ */
86
+
87
+ (function() {
88
+
89
+ var acorn = {};
90
+ (function (exports) {
91
+ // This section of code is taken from acorn.
92
+ //
93
+ // Acorn was written by Marijn Haverbeke and released under an MIT
94
+ // license. The Unicode regexps (for identifiers and whitespace) were
95
+ // taken from [Esprima](http://esprima.org) by Ariya Hidayat.
96
+ //
97
+ // Git repositories for Acorn are available at
98
+ //
99
+ // http://marijnhaverbeke.nl/git/acorn
100
+ // https://github.com/marijnh/acorn.git
101
+
102
+ // ## Character categories
103
+
104
+ // Big ugly regular expressions that match characters in the
105
+ // whitespace, identifier, and identifier-start categories. These
106
+ // are only applied when a character is found to actually have a
107
+ // code point above 128.
108
+
109
+ var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
110
+ var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
111
+ var nonASCIIidentifierChars = "\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
112
+ var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
113
+ var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
114
+
115
+ // Whether a single character denotes a newline.
116
+
117
+ var newline = exports.newline = /[\n\r\u2028\u2029]/;
118
+
119
+ // Matches a whole line break (where CRLF is considered a single
120
+ // line break). Used to count lines.
121
+
122
+ var lineBreak = exports.lineBreak = /\r\n|[\n\r\u2028\u2029]/g;
123
+
124
+ // Test whether a given character code starts an identifier.
125
+
126
+ var isIdentifierStart = exports.isIdentifierStart = function(code) {
127
+ if (code < 65) return code === 36;
128
+ if (code < 91) return true;
129
+ if (code < 97) return code === 95;
130
+ if (code < 123)return true;
131
+ return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
132
+ };
133
+
134
+ // Test whether a given character is part of an identifier.
135
+
136
+ var isIdentifierChar = exports.isIdentifierChar = function(code) {
137
+ if (code < 48) return code === 36;
138
+ if (code < 58) return true;
139
+ if (code < 65) return false;
140
+ if (code < 91) return true;
141
+ if (code < 97) return code === 95;
142
+ if (code < 123)return true;
143
+ return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
144
+ };
145
+ })(acorn);
146
+
147
+ function in_array(what, arr) {
148
+ for (var i = 0; i < arr.length; i += 1) {
149
+ if (arr[i] === what) {
150
+ return true;
151
+ }
152
+ }
153
+ return false;
154
+ }
155
+
156
+ function trim(s) {
157
+ return s.replace(/^\s+|\s+$/g, '');
158
+ }
159
+
160
+ function ltrim(s) {
161
+ return s.replace(/^\s+/g, '');
162
+ }
163
+
164
+ function rtrim(s) {
165
+ return s.replace(/\s+$/g, '');
166
+ }
167
+
168
+ function js_beautify(js_source_text, options) {
169
+ "use strict";
170
+ var beautifier = new Beautifier(js_source_text, options);
171
+ return beautifier.beautify();
172
+ }
173
+
174
+ var MODE = {
175
+ BlockStatement: 'BlockStatement', // 'BLOCK'
176
+ Statement: 'Statement', // 'STATEMENT'
177
+ ObjectLiteral: 'ObjectLiteral', // 'OBJECT',
178
+ ArrayLiteral: 'ArrayLiteral', //'[EXPRESSION]',
179
+ ForInitializer: 'ForInitializer', //'(FOR-EXPRESSION)',
180
+ Conditional: 'Conditional', //'(COND-EXPRESSION)',
181
+ Expression: 'Expression' //'(EXPRESSION)'
182
+ };
183
+
184
+ function Beautifier(js_source_text, options) {
185
+ "use strict";
186
+ var output
187
+ var tokens = [], token_pos;
188
+ var Tokenizer;
189
+ var current_token;
190
+ var last_type, last_last_text, indent_string;
191
+ var flags, previous_flags, flag_store;
192
+ var prefix;
193
+
194
+ var handlers, opt;
195
+ var baseIndentString = '';
196
+
197
+ handlers = {
198
+ 'TK_START_EXPR': handle_start_expr,
199
+ 'TK_END_EXPR': handle_end_expr,
200
+ 'TK_START_BLOCK': handle_start_block,
201
+ 'TK_END_BLOCK': handle_end_block,
202
+ 'TK_WORD': handle_word,
203
+ 'TK_RESERVED': handle_word,
204
+ 'TK_SEMICOLON': handle_semicolon,
205
+ 'TK_STRING': handle_string,
206
+ 'TK_EQUALS': handle_equals,
207
+ 'TK_OPERATOR': handle_operator,
208
+ 'TK_COMMA': handle_comma,
209
+ 'TK_BLOCK_COMMENT': handle_block_comment,
210
+ 'TK_COMMENT': handle_comment,
211
+ 'TK_DOT': handle_dot,
212
+ 'TK_UNKNOWN': handle_unknown,
213
+ 'TK_EOF': handle_eof
214
+ };
215
+
216
+ function create_flags(flags_base, mode) {
217
+ var next_indent_level = 0;
218
+ if (flags_base) {
219
+ next_indent_level = flags_base.indentation_level;
220
+ if (!output.just_added_newline() &&
221
+ flags_base.line_indent_level > next_indent_level) {
222
+ next_indent_level = flags_base.line_indent_level;
223
+ }
224
+ }
225
+
226
+ var next_flags = {
227
+ mode: mode,
228
+ parent: flags_base,
229
+ last_text: flags_base ? flags_base.last_text : '', // last token text
230
+ last_word: flags_base ? flags_base.last_word : '', // last 'TK_WORD' passed
231
+ declaration_statement: false,
232
+ declaration_assignment: false,
233
+ multiline_frame: false,
234
+ if_block: false,
235
+ else_block: false,
236
+ do_block: false,
237
+ do_while: false,
238
+ in_case_statement: false, // switch(..){ INSIDE HERE }
239
+ in_case: false, // we're on the exact line with "case 0:"
240
+ case_body: false, // the indented case-action block
241
+ indentation_level: next_indent_level,
242
+ line_indent_level: flags_base ? flags_base.line_indent_level : next_indent_level,
243
+ start_line_index: output.get_line_number(),
244
+ ternary_depth: 0
245
+ };
246
+ return next_flags;
247
+ }
248
+
249
+ // Some interpreters have unexpected results with foo = baz || bar;
250
+ options = options ? options : {};
251
+ opt = {};
252
+
253
+ // compatibility
254
+ if (options.braces_on_own_line !== undefined) { //graceful handling of deprecated option
255
+ opt.brace_style = options.braces_on_own_line ? "expand" : "collapse";
256
+ }
257
+ opt.brace_style = options.brace_style ? options.brace_style : (opt.brace_style ? opt.brace_style : "collapse");
258
+
259
+ // graceful handling of deprecated option
260
+ if (opt.brace_style === "expand-strict") {
261
+ opt.brace_style = "expand";
262
+ }
263
+
264
+
265
+ opt.indent_size = options.indent_size ? parseInt(options.indent_size, 10) : 4;
266
+ opt.indent_char = options.indent_char ? options.indent_char : ' ';
267
+ opt.eol = options.eol ? options.eol : '\n';
268
+ opt.preserve_newlines = (options.preserve_newlines === undefined) ? true : options.preserve_newlines;
269
+ opt.break_chained_methods = (options.break_chained_methods === undefined) ? false : options.break_chained_methods;
270
+ opt.max_preserve_newlines = (options.max_preserve_newlines === undefined) ? 0 : parseInt(options.max_preserve_newlines, 10);
271
+ opt.space_in_paren = (options.space_in_paren === undefined) ? false : options.space_in_paren;
272
+ opt.space_in_empty_paren = (options.space_in_empty_paren === undefined) ? false : options.space_in_empty_paren;
273
+ opt.jslint_happy = (options.jslint_happy === undefined) ? false : options.jslint_happy;
274
+ opt.space_after_anon_function = (options.space_after_anon_function === undefined) ? false : options.space_after_anon_function;
275
+ opt.keep_array_indentation = (options.keep_array_indentation === undefined) ? false : options.keep_array_indentation;
276
+ opt.space_before_conditional = (options.space_before_conditional === undefined) ? true : options.space_before_conditional;
277
+ opt.unescape_strings = (options.unescape_strings === undefined) ? false : options.unescape_strings;
278
+ opt.wrap_line_length = (options.wrap_line_length === undefined) ? 0 : parseInt(options.wrap_line_length, 10);
279
+ opt.e4x = (options.e4x === undefined) ? false : options.e4x;
280
+ opt.end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
281
+ opt.comma_first = (options.comma_first === undefined) ? false : options.comma_first;
282
+
283
+ // For testing of beautify ignore:start directive
284
+ opt.test_output_raw = (options.test_output_raw === undefined) ? false : options.test_output_raw;
285
+
286
+ // force opt.space_after_anon_function to true if opt.jslint_happy
287
+ if(opt.jslint_happy) {
288
+ opt.space_after_anon_function = true;
289
+ }
290
+
291
+ if(options.indent_with_tabs){
292
+ opt.indent_char = '\t';
293
+ opt.indent_size = 1;
294
+ }
295
+
296
+ opt.eol = opt.eol.replace(/\\r/, '\r').replace(/\\n/, '\n')
297
+
298
+ //----------------------------------
299
+ indent_string = '';
300
+ while (opt.indent_size > 0) {
301
+ indent_string += opt.indent_char;
302
+ opt.indent_size -= 1;
303
+ }
304
+
305
+ var preindent_index = 0;
306
+ if(js_source_text && js_source_text.length) {
307
+ while ( (js_source_text.charAt(preindent_index) === ' ' ||
308
+ js_source_text.charAt(preindent_index) === '\t')) {
309
+ baseIndentString += js_source_text.charAt(preindent_index);
310
+ preindent_index += 1;
311
+ }
312
+ js_source_text = js_source_text.substring(preindent_index);
313
+ }
314
+
315
+ last_type = 'TK_START_BLOCK'; // last token type
316
+ last_last_text = ''; // pre-last token text
317
+ output = new Output(indent_string, baseIndentString);
318
+
319
+ // If testing the ignore directive, start with output disable set to true
320
+ output.raw = opt.test_output_raw;
321
+
322
+
323
+ // Stack of parsing/formatting states, including MODE.
324
+ // We tokenize, parse, and output in an almost purely a forward-only stream of token input
325
+ // and formatted output. This makes the beautifier less accurate than full parsers
326
+ // but also far more tolerant of syntax errors.
327
+ //
328
+ // For example, the default mode is MODE.BlockStatement. If we see a '{' we push a new frame of type
329
+ // MODE.BlockStatement on the the stack, even though it could be object literal. If we later
330
+ // encounter a ":", we'll switch to to MODE.ObjectLiteral. If we then see a ";",
331
+ // most full parsers would die, but the beautifier gracefully falls back to
332
+ // MODE.BlockStatement and continues on.
333
+ flag_store = [];
334
+ set_mode(MODE.BlockStatement);
335
+
336
+ this.beautify = function() {
337
+
338
+ /*jshint onevar:true */
339
+ var local_token, sweet_code;
340
+ Tokenizer = new tokenizer(js_source_text, opt, indent_string);
341
+ tokens = Tokenizer.tokenize();
342
+ token_pos = 0;
343
+
344
+ while (local_token = get_token()) {
345
+ for(var i = 0; i < local_token.comments_before.length; i++) {
346
+ // The cleanest handling of inline comments is to treat them as though they aren't there.
347
+ // Just continue formatting and the behavior should be logical.
348
+ // Also ignore unknown tokens. Again, this should result in better behavior.
349
+ handle_token(local_token.comments_before[i]);
350
+ }
351
+ handle_token(local_token);
352
+
353
+ last_last_text = flags.last_text;
354
+ last_type = local_token.type;
355
+ flags.last_text = local_token.text;
356
+
357
+ token_pos += 1;
358
+ }
359
+
360
+ sweet_code = output.get_code();
361
+ if (opt.end_with_newline) {
362
+ sweet_code += '\n';
363
+ }
364
+
365
+ if (opt.eol != '\n') {
366
+ sweet_code = sweet_code.replace(/[\n]/g, opt.eol);
367
+ }
368
+
369
+ return sweet_code;
370
+ };
371
+
372
+ function handle_token(local_token) {
373
+ var newlines = local_token.newlines;
374
+ var keep_whitespace = opt.keep_array_indentation && is_array(flags.mode);
375
+
376
+ if (keep_whitespace) {
377
+ for (i = 0; i < newlines; i += 1) {
378
+ print_newline(i > 0);
379
+ }
380
+ } else {
381
+ if (opt.max_preserve_newlines && newlines > opt.max_preserve_newlines) {
382
+ newlines = opt.max_preserve_newlines;
383
+ }
384
+
385
+ if (opt.preserve_newlines) {
386
+ if (local_token.newlines > 1) {
387
+ print_newline();
388
+ for (var i = 1; i < newlines; i += 1) {
389
+ print_newline(true);
390
+ }
391
+ }
392
+ }
393
+ }
394
+
395
+ current_token = local_token;
396
+ handlers[current_token.type]();
397
+ }
398
+
399
+ // we could use just string.split, but
400
+ // IE doesn't like returning empty strings
401
+ function split_newlines(s) {
402
+ //return s.split(/\x0d\x0a|\x0a/);
403
+
404
+ s = s.replace(/\x0d/g, '');
405
+ var out = [],
406
+ idx = s.indexOf("\n");
407
+ while (idx !== -1) {
408
+ out.push(s.substring(0, idx));
409
+ s = s.substring(idx + 1);
410
+ idx = s.indexOf("\n");
411
+ }
412
+ if (s.length) {
413
+ out.push(s);
414
+ }
415
+ return out;
416
+ }
417
+
418
+ function allow_wrap_or_preserved_newline(force_linewrap) {
419
+ force_linewrap = (force_linewrap === undefined) ? false : force_linewrap;
420
+
421
+ // Never wrap the first token on a line
422
+ if (output.just_added_newline()) {
423
+ return
424
+ }
425
+
426
+ if ((opt.preserve_newlines && current_token.wanted_newline) || force_linewrap) {
427
+ print_newline(false, true);
428
+ } else if (opt.wrap_line_length) {
429
+ var proposed_line_length = output.current_line.get_character_count() + current_token.text.length +
430
+ (output.space_before_token ? 1 : 0);
431
+ if (proposed_line_length >= opt.wrap_line_length) {
432
+ print_newline(false, true);
433
+ }
434
+ }
435
+ }
436
+
437
+ function print_newline(force_newline, preserve_statement_flags) {
438
+ if (!preserve_statement_flags) {
439
+ if (flags.last_text !== ';' && flags.last_text !== ',' && flags.last_text !== '=' && last_type !== 'TK_OPERATOR') {
440
+ while (flags.mode === MODE.Statement && !flags.if_block && !flags.do_block) {
441
+ restore_mode();
442
+ }
443
+ }
444
+ }
445
+
446
+ if (output.add_new_line(force_newline)) {
447
+ flags.multiline_frame = true;
448
+ }
449
+ }
450
+
451
+ function print_token_line_indentation() {
452
+ if (output.just_added_newline()) {
453
+ if (opt.keep_array_indentation && is_array(flags.mode) && current_token.wanted_newline) {
454
+ output.current_line.push(current_token.whitespace_before);
455
+ output.space_before_token = false;
456
+ } else if (output.set_indent(flags.indentation_level)) {
457
+ flags.line_indent_level = flags.indentation_level;
458
+ }
459
+ }
460
+ }
461
+
462
+ function print_token(printable_token) {
463
+ if (output.raw) {
464
+ output.add_raw_token(current_token)
465
+ return;
466
+ }
467
+
468
+ if (opt.comma_first && last_type === 'TK_COMMA'
469
+ && output.just_added_newline()) {
470
+ if(output.previous_line.last() === ',') {
471
+ output.previous_line.pop();
472
+ print_token_line_indentation();
473
+ output.add_token(',');
474
+ output.space_before_token = true;
475
+ }
476
+ }
477
+
478
+ printable_token = printable_token || current_token.text;
479
+ print_token_line_indentation();
480
+ output.add_token(printable_token);
481
+ }
482
+
483
+ function indent() {
484
+ flags.indentation_level += 1;
485
+ }
486
+
487
+ function deindent() {
488
+ if (flags.indentation_level > 0 &&
489
+ ((!flags.parent) || flags.indentation_level > flags.parent.indentation_level))
490
+ flags.indentation_level -= 1;
491
+ }
492
+
493
+ function set_mode(mode) {
494
+ if (flags) {
495
+ flag_store.push(flags);
496
+ previous_flags = flags;
497
+ } else {
498
+ previous_flags = create_flags(null, mode);
499
+ }
500
+
501
+ flags = create_flags(previous_flags, mode);
502
+ }
503
+
504
+ function is_array(mode) {
505
+ return mode === MODE.ArrayLiteral;
506
+ }
507
+
508
+ function is_expression(mode) {
509
+ return in_array(mode, [MODE.Expression, MODE.ForInitializer, MODE.Conditional]);
510
+ }
511
+
512
+ function restore_mode() {
513
+ if (flag_store.length > 0) {
514
+ previous_flags = flags;
515
+ flags = flag_store.pop();
516
+ if (previous_flags.mode === MODE.Statement) {
517
+ output.remove_redundant_indentation(previous_flags);
518
+ }
519
+ }
520
+ }
521
+
522
+ function start_of_object_property() {
523
+ return flags.parent.mode === MODE.ObjectLiteral && flags.mode === MODE.Statement && (
524
+ (flags.last_text === ':' && flags.ternary_depth === 0) || (last_type === 'TK_RESERVED' && in_array(flags.last_text, ['get', 'set'])));
525
+ }
526
+
527
+ function start_of_statement() {
528
+ if (
529
+ (last_type === 'TK_RESERVED' && in_array(flags.last_text, ['var', 'let', 'const']) && current_token.type === 'TK_WORD') ||
530
+ (last_type === 'TK_RESERVED' && flags.last_text === 'do') ||
531
+ (last_type === 'TK_RESERVED' && flags.last_text === 'return' && !current_token.wanted_newline) ||
532
+ (last_type === 'TK_RESERVED' && flags.last_text === 'else' && !(current_token.type === 'TK_RESERVED' && current_token.text === 'if')) ||
533
+ (last_type === 'TK_END_EXPR' && (previous_flags.mode === MODE.ForInitializer || previous_flags.mode === MODE.Conditional)) ||
534
+ (last_type === 'TK_WORD' && flags.mode === MODE.BlockStatement
535
+ && !flags.in_case
536
+ && !(current_token.text === '--' || current_token.text === '++')
537
+ && last_last_text !== 'function'
538
+ && current_token.type !== 'TK_WORD' && current_token.type !== 'TK_RESERVED') ||
539
+ (flags.mode === MODE.ObjectLiteral && (
540
+ (flags.last_text === ':' && flags.ternary_depth === 0) || (last_type === 'TK_RESERVED' && in_array(flags.last_text, ['get', 'set']))))
541
+ ) {
542
+
543
+ set_mode(MODE.Statement);
544
+ indent();
545
+
546
+ if (last_type === 'TK_RESERVED' && in_array(flags.last_text, ['var', 'let', 'const']) && current_token.type === 'TK_WORD') {
547
+ flags.declaration_statement = true;
548
+ }
549
+
550
+ // Issue #276:
551
+ // If starting a new statement with [if, for, while, do], push to a new line.
552
+ // if (a) if (b) if(c) d(); else e(); else f();
553
+ if (!start_of_object_property()) {
554
+ allow_wrap_or_preserved_newline(
555
+ current_token.type === 'TK_RESERVED' && in_array(current_token.text, ['do', 'for', 'if', 'while']));
556
+ }
557
+
558
+ return true;
559
+ }
560
+ return false;
561
+ }
562
+
563
+ function all_lines_start_with(lines, c) {
564
+ for (var i = 0; i < lines.length; i++) {
565
+ var line = trim(lines[i]);
566
+ if (line.charAt(0) !== c) {
567
+ return false;
568
+ }
569
+ }
570
+ return true;
571
+ }
572
+
573
+ function each_line_matches_indent(lines, indent) {
574
+ var i = 0,
575
+ len = lines.length,
576
+ line;
577
+ for (; i < len; i++) {
578
+ line = lines[i];
579
+ // allow empty lines to pass through
580
+ if (line && line.indexOf(indent) !== 0) {
581
+ return false;
582
+ }
583
+ }
584
+ return true;
585
+ }
586
+
587
+ function is_special_word(word) {
588
+ return in_array(word, ['case', 'return', 'do', 'if', 'throw', 'else']);
589
+ }
590
+
591
+ function get_token(offset) {
592
+ var index = token_pos + (offset || 0);
593
+ return (index < 0 || index >= tokens.length) ? null : tokens[index];
594
+ }
595
+
596
+ function handle_start_expr() {
597
+ if (start_of_statement()) {
598
+ // The conditional starts the statement if appropriate.
599
+ }
600
+
601
+ var next_mode = MODE.Expression;
602
+ if (current_token.text === '[') {
603
+
604
+ if (last_type === 'TK_WORD' || flags.last_text === ')') {
605
+ // this is array index specifier, break immediately
606
+ // a[x], fn()[x]
607
+ if (last_type === 'TK_RESERVED' && in_array(flags.last_text, Tokenizer.line_starters)) {
608
+ output.space_before_token = true;
609
+ }
610
+ set_mode(next_mode);
611
+ print_token();
612
+ indent();
613
+ if (opt.space_in_paren) {
614
+ output.space_before_token = true;
615
+ }
616
+ return;
617
+ }
618
+
619
+ next_mode = MODE.ArrayLiteral;
620
+ if (is_array(flags.mode)) {
621
+ if (flags.last_text === '[' ||
622
+ (flags.last_text === ',' && (last_last_text === ']' || last_last_text === '}'))) {
623
+ // ], [ goes to new line
624
+ // }, [ goes to new line
625
+ if (!opt.keep_array_indentation) {
626
+ print_newline();
627
+ }
628
+ }
629
+ }
630
+
631
+ } else {
632
+ if (last_type === 'TK_RESERVED' && flags.last_text === 'for') {
633
+ next_mode = MODE.ForInitializer;
634
+ } else if (last_type === 'TK_RESERVED' && in_array(flags.last_text, ['if', 'while'])) {
635
+ next_mode = MODE.Conditional;
636
+ } else {
637
+ // next_mode = MODE.Expression;
638
+ }
639
+ }
640
+
641
+ if (flags.last_text === ';' || last_type === 'TK_START_BLOCK') {
642
+ print_newline();
643
+ } else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR' || last_type === 'TK_END_BLOCK' || flags.last_text === '.') {
644
+ // TODO: Consider whether forcing this is required. Review failing tests when removed.
645
+ allow_wrap_or_preserved_newline(current_token.wanted_newline);
646
+ // do nothing on (( and )( and ][ and ]( and .(
647
+ } else if (!(last_type === 'TK_RESERVED' && current_token.text === '(') && last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR') {
648
+ output.space_before_token = true;
649
+ } else if ((last_type === 'TK_RESERVED' && (flags.last_word === 'function' || flags.last_word === 'typeof')) ||
650
+ (flags.last_text === '*' && last_last_text === 'function')) {
651
+ // function() vs function ()
652
+ if (opt.space_after_anon_function) {
653
+ output.space_before_token = true;
654
+ }
655
+ } else if (last_type === 'TK_RESERVED' && (in_array(flags.last_text, Tokenizer.line_starters) || flags.last_text === 'catch')) {
656
+ if (opt.space_before_conditional) {
657
+ output.space_before_token = true;
658
+ }
659
+ }
660
+
661
+ // Should be a space between await and an IIFE
662
+ if(current_token.text === '(' && last_type === 'TK_RESERVED' && flags.last_word === 'await'){
663
+ output.space_before_token = true;
664
+ }
665
+
666
+ // Support of this kind of newline preservation.
667
+ // a = (b &&
668
+ // (c || d));
669
+ if (current_token.text === '(') {
670
+ if (last_type === 'TK_EQUALS' || last_type === 'TK_OPERATOR') {
671
+ if (!start_of_object_property()) {
672
+ allow_wrap_or_preserved_newline();
673
+ }
674
+ }
675
+ }
676
+
677
+ set_mode(next_mode);
678
+ print_token();
679
+ if (opt.space_in_paren) {
680
+ output.space_before_token = true;
681
+ }
682
+
683
+ // In all cases, if we newline while inside an expression it should be indented.
684
+ indent();
685
+ }
686
+
687
+ function handle_end_expr() {
688
+ // statements inside expressions are not valid syntax, but...
689
+ // statements must all be closed when their container closes
690
+ while (flags.mode === MODE.Statement) {
691
+ restore_mode();
692
+ }
693
+
694
+ if (flags.multiline_frame) {
695
+ allow_wrap_or_preserved_newline(current_token.text === ']' && is_array(flags.mode) && !opt.keep_array_indentation);
696
+ }
697
+
698
+ if (opt.space_in_paren) {
699
+ if (last_type === 'TK_START_EXPR' && ! opt.space_in_empty_paren) {
700
+ // () [] no inner space in empty parens like these, ever, ref #320
701
+ output.trim();
702
+ output.space_before_token = false;
703
+ } else {
704
+ output.space_before_token = true;
705
+ }
706
+ }
707
+ if (current_token.text === ']' && opt.keep_array_indentation) {
708
+ print_token();
709
+ restore_mode();
710
+ } else {
711
+ restore_mode();
712
+ print_token();
713
+ }
714
+ output.remove_redundant_indentation(previous_flags);
715
+
716
+ // do {} while () // no statement required after
717
+ if (flags.do_while && previous_flags.mode === MODE.Conditional) {
718
+ previous_flags.mode = MODE.Expression;
719
+ flags.do_block = false;
720
+ flags.do_while = false;
721
+
722
+ }
723
+ }
724
+
725
+ function handle_start_block() {
726
+ // Check if this is should be treated as a ObjectLiteral
727
+ var next_token = get_token(1)
728
+ var second_token = get_token(2)
729
+ if (second_token && (
730
+ (second_token.text === ':' && in_array(next_token.type, ['TK_STRING', 'TK_WORD', 'TK_RESERVED']))
731
+ || (in_array(next_token.text, ['get', 'set']) && in_array(second_token.type, ['TK_WORD', 'TK_RESERVED']))
732
+ )) {
733
+ // We don't support TypeScript,but we didn't break it for a very long time.
734
+ // We'll try to keep not breaking it.
735
+ if (!in_array(last_last_text, ['class','interface'])) {
736
+ set_mode(MODE.ObjectLiteral);
737
+ } else {
738
+ set_mode(MODE.BlockStatement);
739
+ }
740
+ } else {
741
+ set_mode(MODE.BlockStatement);
742
+ }
743
+
744
+ var empty_braces = !next_token.comments_before.length && next_token.text === '}';
745
+ var empty_anonymous_function = empty_braces && flags.last_word === 'function' &&
746
+ last_type === 'TK_END_EXPR';
747
+
748
+ if (opt.brace_style === "expand" ||
749
+ (opt.brace_style === "none" && current_token.wanted_newline)) {
750
+ if (last_type !== 'TK_OPERATOR' &&
751
+ (empty_anonymous_function ||
752
+ last_type === 'TK_EQUALS' ||
753
+ (last_type === 'TK_RESERVED' && is_special_word(flags.last_text) && flags.last_text !== 'else'))) {
754
+ output.space_before_token = true;
755
+ } else {
756
+ print_newline(false, true);
757
+ }
758
+ } else { // collapse
759
+ if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') {
760
+ if (last_type === 'TK_START_BLOCK') {
761
+ print_newline();
762
+ } else {
763
+ output.space_before_token = true;
764
+ }
765
+ } else {
766
+ // if TK_OPERATOR or TK_START_EXPR
767
+ if (is_array(previous_flags.mode) && flags.last_text === ',') {
768
+ if (last_last_text === '}') {
769
+ // }, { in array context
770
+ output.space_before_token = true;
771
+ } else {
772
+ print_newline(); // [a, b, c, {
773
+ }
774
+ }
775
+ }
776
+ }
777
+ print_token();
778
+ indent();
779
+ }
780
+
781
+ function handle_end_block() {
782
+ // statements must all be closed when their container closes
783
+ while (flags.mode === MODE.Statement) {
784
+ restore_mode();
785
+ }
786
+ var empty_braces = last_type === 'TK_START_BLOCK';
787
+
788
+ if (opt.brace_style === "expand") {
789
+ if (!empty_braces) {
790
+ print_newline();
791
+ }
792
+ } else {
793
+ // skip {}
794
+ if (!empty_braces) {
795
+ if (is_array(flags.mode) && opt.keep_array_indentation) {
796
+ // we REALLY need a newline here, but newliner would skip that
797
+ opt.keep_array_indentation = false;
798
+ print_newline();
799
+ opt.keep_array_indentation = true;
800
+
801
+ } else {
802
+ print_newline();
803
+ }
804
+ }
805
+ }
806
+ restore_mode();
807
+ print_token();
808
+ }
809
+
810
+ function handle_word() {
811
+ if (current_token.type === 'TK_RESERVED' && flags.mode !== MODE.ObjectLiteral &&
812
+ in_array(current_token.text, ['set', 'get'])) {
813
+ current_token.type = 'TK_WORD';
814
+ }
815
+
816
+ if (current_token.type === 'TK_RESERVED' && flags.mode === MODE.ObjectLiteral) {
817
+ var next_token = get_token(1);
818
+ if (next_token.text == ':') {
819
+ current_token.type = 'TK_WORD';
820
+ }
821
+ }
822
+
823
+ if (start_of_statement()) {
824
+ // The conditional starts the statement if appropriate.
825
+ } else if (current_token.wanted_newline && !is_expression(flags.mode) &&
826
+ (last_type !== 'TK_OPERATOR' || (flags.last_text === '--' || flags.last_text === '++')) &&
827
+ last_type !== 'TK_EQUALS' &&
828
+ (opt.preserve_newlines || !(last_type === 'TK_RESERVED' && in_array(flags.last_text, ['var', 'let', 'const', 'set', 'get'])))) {
829
+
830
+ print_newline();
831
+ }
832
+
833
+ if (flags.do_block && !flags.do_while) {
834
+ if (current_token.type === 'TK_RESERVED' && current_token.text === 'while') {
835
+ // do {} ## while ()
836
+ output.space_before_token = true;
837
+ print_token();
838
+ output.space_before_token = true;
839
+ flags.do_while = true;
840
+ return;
841
+ } else {
842
+ // do {} should always have while as the next word.
843
+ // if we don't see the expected while, recover
844
+ print_newline();
845
+ flags.do_block = false;
846
+ }
847
+ }
848
+
849
+ // if may be followed by else, or not
850
+ // Bare/inline ifs are tricky
851
+ // Need to unwind the modes correctly: if (a) if (b) c(); else d(); else e();
852
+ if (flags.if_block) {
853
+ if (!flags.else_block && (current_token.type === 'TK_RESERVED' && current_token.text === 'else')) {
854
+ flags.else_block = true;
855
+ } else {
856
+ while (flags.mode === MODE.Statement) {
857
+ restore_mode();
858
+ }
859
+ flags.if_block = false;
860
+ flags.else_block = false;
861
+ }
862
+ }
863
+
864
+ if (current_token.type === 'TK_RESERVED' && (current_token.text === 'case' || (current_token.text === 'default' && flags.in_case_statement))) {
865
+ print_newline();
866
+ if (flags.case_body || opt.jslint_happy) {
867
+ // switch cases following one another
868
+ deindent();
869
+ flags.case_body = false;
870
+ }
871
+ print_token();
872
+ flags.in_case = true;
873
+ flags.in_case_statement = true;
874
+ return;
875
+ }
876
+
877
+ if (current_token.type === 'TK_RESERVED' && current_token.text === 'function') {
878
+ if (in_array(flags.last_text, ['}', ';']) || (output.just_added_newline() && ! in_array(flags.last_text, ['[', '{', ':', '=', ',']))) {
879
+ // make sure there is a nice clean space of at least one blank line
880
+ // before a new function definition
881
+ if ( !output.just_added_blankline() && !current_token.comments_before.length) {
882
+ print_newline();
883
+ print_newline(true);
884
+ }
885
+ }
886
+ if (last_type === 'TK_RESERVED' || last_type === 'TK_WORD') {
887
+ if (last_type === 'TK_RESERVED' && in_array(flags.last_text, ['get', 'set', 'new', 'return', 'export', 'async'])) {
888
+ output.space_before_token = true;
889
+ } else if (last_type === 'TK_RESERVED' && flags.last_text === 'default' && last_last_text === 'export') {
890
+ output.space_before_token = true;
891
+ } else {
892
+ print_newline();
893
+ }
894
+ } else if (last_type === 'TK_OPERATOR' || flags.last_text === '=') {
895
+ // foo = function
896
+ output.space_before_token = true;
897
+ } else if (!flags.multiline_frame && (is_expression(flags.mode) || is_array(flags.mode))) {
898
+ // (function
899
+ } else {
900
+ print_newline();
901
+ }
902
+ }
903
+
904
+ if (last_type === 'TK_COMMA' || last_type === 'TK_START_EXPR' || last_type === 'TK_EQUALS' || last_type === 'TK_OPERATOR') {
905
+ if (!start_of_object_property()) {
906
+ allow_wrap_or_preserved_newline();
907
+ }
908
+ }
909
+
910
+ if (current_token.type === 'TK_RESERVED' && in_array(current_token.text, ['function', 'get', 'set'])) {
911
+ print_token();
912
+ flags.last_word = current_token.text;
913
+ return;
914
+ }
915
+
916
+ prefix = 'NONE';
917
+
918
+ if (last_type === 'TK_END_BLOCK') {
919
+ if (!(current_token.type === 'TK_RESERVED' && in_array(current_token.text, ['else', 'catch', 'finally']))) {
920
+ prefix = 'NEWLINE';
921
+ } else {
922
+ if (opt.brace_style === "expand" ||
923
+ opt.brace_style === "end-expand" ||
924
+ (opt.brace_style === "none" && current_token.wanted_newline)) {
925
+ prefix = 'NEWLINE';
926
+ } else {
927
+ prefix = 'SPACE';
928
+ output.space_before_token = true;
929
+ }
930
+ }
931
+ } else if (last_type === 'TK_SEMICOLON' && flags.mode === MODE.BlockStatement) {
932
+ // TODO: Should this be for STATEMENT as well?
933
+ prefix = 'NEWLINE';
934
+ } else if (last_type === 'TK_SEMICOLON' && is_expression(flags.mode)) {
935
+ prefix = 'SPACE';
936
+ } else if (last_type === 'TK_STRING') {
937
+ prefix = 'NEWLINE';
938
+ } else if (last_type === 'TK_RESERVED' || last_type === 'TK_WORD' ||
939
+ (flags.last_text === '*' && last_last_text === 'function')) {
940
+ prefix = 'SPACE';
941
+ } else if (last_type === 'TK_START_BLOCK') {
942
+ prefix = 'NEWLINE';
943
+ } else if (last_type === 'TK_END_EXPR') {
944
+ output.space_before_token = true;
945
+ prefix = 'NEWLINE';
946
+ }
947
+
948
+ if (current_token.type === 'TK_RESERVED' && in_array(current_token.text, Tokenizer.line_starters) && flags.last_text !== ')') {
949
+ if (flags.last_text === 'else' || flags.last_text === 'export') {
950
+ prefix = 'SPACE';
951
+ } else {
952
+ prefix = 'NEWLINE';
953
+ }
954
+
955
+ }
956
+
957
+ if (current_token.type === 'TK_RESERVED' && in_array(current_token.text, ['else', 'catch', 'finally'])) {
958
+ if (last_type !== 'TK_END_BLOCK' ||
959
+ opt.brace_style === "expand" ||
960
+ opt.brace_style === "end-expand" ||
961
+ (opt.brace_style === "none" && current_token.wanted_newline)) {
962
+ print_newline();
963
+ } else {
964
+ output.trim(true);
965
+ var line = output.current_line;
966
+ // If we trimmed and there's something other than a close block before us
967
+ // put a newline back in. Handles '} // comment' scenario.
968
+ if (line.last() !== '}') {
969
+ print_newline();
970
+ }
971
+ output.space_before_token = true;
972
+ }
973
+ } else if (prefix === 'NEWLINE') {
974
+ if (last_type === 'TK_RESERVED' && is_special_word(flags.last_text)) {
975
+ // no newline between 'return nnn'
976
+ output.space_before_token = true;
977
+ } else if (last_type !== 'TK_END_EXPR') {
978
+ if ((last_type !== 'TK_START_EXPR' || !(current_token.type === 'TK_RESERVED' && in_array(current_token.text, ['var', 'let', 'const']))) && flags.last_text !== ':') {
979
+ // no need to force newline on 'var': for (var x = 0...)
980
+ if (current_token.type === 'TK_RESERVED' && current_token.text === 'if' && flags.last_text === 'else') {
981
+ // no newline for } else if {
982
+ output.space_before_token = true;
983
+ } else {
984
+ print_newline();
985
+ }
986
+ }
987
+ } else if (current_token.type === 'TK_RESERVED' && in_array(current_token.text, Tokenizer.line_starters) && flags.last_text !== ')') {
988
+ print_newline();
989
+ }
990
+ } else if (flags.multiline_frame && is_array(flags.mode) && flags.last_text === ',' && last_last_text === '}') {
991
+ print_newline(); // }, in lists get a newline treatment
992
+ } else if (prefix === 'SPACE') {
993
+ output.space_before_token = true;
994
+ }
995
+ print_token();
996
+ flags.last_word = current_token.text;
997
+
998
+ if (current_token.type === 'TK_RESERVED' && current_token.text === 'do') {
999
+ flags.do_block = true;
1000
+ }
1001
+
1002
+ if (current_token.type === 'TK_RESERVED' && current_token.text === 'if') {
1003
+ flags.if_block = true;
1004
+ }
1005
+ }
1006
+
1007
+ function handle_semicolon() {
1008
+ if (start_of_statement()) {
1009
+ // The conditional starts the statement if appropriate.
1010
+ // Semicolon can be the start (and end) of a statement
1011
+ output.space_before_token = false;
1012
+ }
1013
+ while (flags.mode === MODE.Statement && !flags.if_block && !flags.do_block) {
1014
+ restore_mode();
1015
+ }
1016
+ print_token();
1017
+ }
1018
+
1019
+ function handle_string() {
1020
+ if (start_of_statement()) {
1021
+ // The conditional starts the statement if appropriate.
1022
+ // One difference - strings want at least a space before
1023
+ output.space_before_token = true;
1024
+ } else if (last_type === 'TK_RESERVED' || last_type === 'TK_WORD') {
1025
+ output.space_before_token = true;
1026
+ } else if (last_type === 'TK_COMMA' || last_type === 'TK_START_EXPR' || last_type === 'TK_EQUALS' || last_type === 'TK_OPERATOR') {
1027
+ if (!start_of_object_property()) {
1028
+ allow_wrap_or_preserved_newline();
1029
+ }
1030
+ } else {
1031
+ print_newline();
1032
+ }
1033
+ print_token();
1034
+ }
1035
+
1036
+ function handle_equals() {
1037
+ if (start_of_statement()) {
1038
+ // The conditional starts the statement if appropriate.
1039
+ }
1040
+
1041
+ if (flags.declaration_statement) {
1042
+ // just got an '=' in a var-line, different formatting/line-breaking, etc will now be done
1043
+ flags.declaration_assignment = true;
1044
+ }
1045
+ output.space_before_token = true;
1046
+ print_token();
1047
+ output.space_before_token = true;
1048
+ }
1049
+
1050
+ function handle_comma() {
1051
+ if (flags.declaration_statement) {
1052
+ if (is_expression(flags.parent.mode)) {
1053
+ // do not break on comma, for(var a = 1, b = 2)
1054
+ flags.declaration_assignment = false;
1055
+ }
1056
+
1057
+ print_token();
1058
+
1059
+ if (flags.declaration_assignment) {
1060
+ flags.declaration_assignment = false;
1061
+ print_newline(false, true);
1062
+ } else {
1063
+ output.space_before_token = true;
1064
+ // for comma-first, we want to allow a newline before the comma
1065
+ // to turn into a newline after the comma, which we will fixup later
1066
+ if (opt.comma_first) {
1067
+ allow_wrap_or_preserved_newline();
1068
+ }
1069
+ }
1070
+ return;
1071
+ }
1072
+
1073
+ print_token();
1074
+ if (flags.mode === MODE.ObjectLiteral ||
1075
+ (flags.mode === MODE.Statement && flags.parent.mode === MODE.ObjectLiteral)) {
1076
+ if (flags.mode === MODE.Statement) {
1077
+ restore_mode();
1078
+ }
1079
+ print_newline();
1080
+ } else {
1081
+ // EXPR or DO_BLOCK
1082
+ output.space_before_token = true;
1083
+ // for comma-first, we want to allow a newline before the comma
1084
+ // to turn into a newline after the comma, which we will fixup later
1085
+ if (opt.comma_first) {
1086
+ allow_wrap_or_preserved_newline();
1087
+ }
1088
+ }
1089
+
1090
+ }
1091
+
1092
+ function handle_operator() {
1093
+ if (start_of_statement()) {
1094
+ // The conditional starts the statement if appropriate.
1095
+ }
1096
+
1097
+ if (last_type === 'TK_RESERVED' && is_special_word(flags.last_text)) {
1098
+ // "return" had a special handling in TK_WORD. Now we need to return the favor
1099
+ output.space_before_token = true;
1100
+ print_token();
1101
+ return;
1102
+ }
1103
+
1104
+ // hack for actionscript's import .*;
1105
+ if (current_token.text === '*' && last_type === 'TK_DOT') {
1106
+ print_token();
1107
+ return;
1108
+ }
1109
+
1110
+ if (current_token.text === ':' && flags.in_case) {
1111
+ flags.case_body = true;
1112
+ indent();
1113
+ print_token();
1114
+ print_newline();
1115
+ flags.in_case = false;
1116
+ return;
1117
+ }
1118
+
1119
+ if (current_token.text === '::') {
1120
+ // no spaces around exotic namespacing syntax operator
1121
+ print_token();
1122
+ return;
1123
+ }
1124
+
1125
+ // Allow line wrapping between operators
1126
+ if (last_type === 'TK_OPERATOR') {
1127
+ allow_wrap_or_preserved_newline();
1128
+ }
1129
+
1130
+ var space_before = true;
1131
+ var space_after = true;
1132
+
1133
+ if (in_array(current_token.text, ['--', '++', '!', '~']) || (in_array(current_token.text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']) || in_array(flags.last_text, Tokenizer.line_starters) || flags.last_text === ','))) {
1134
+ // unary operators (and binary +/- pretending to be unary) special cases
1135
+
1136
+ space_before = false;
1137
+ space_after = false;
1138
+
1139
+ // http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
1140
+ // if there is a newline between -- or ++ and anything else we should preserve it.
1141
+ if (current_token.wanted_newline && (current_token.text === '--' || current_token.text === '++')) {
1142
+ print_newline(false, true);
1143
+ }
1144
+
1145
+ if (flags.last_text === ';' && is_expression(flags.mode)) {
1146
+ // for (;; ++i)
1147
+ // ^^^
1148
+ space_before = true;
1149
+ }
1150
+
1151
+ if (last_type === 'TK_RESERVED') {
1152
+ space_before = true;
1153
+ } else if (last_type === 'TK_END_EXPR') {
1154
+ space_before = !(flags.last_text === ']' && (current_token.text === '--' || current_token.text === '++'));
1155
+ } else if (last_type === 'TK_OPERATOR') {
1156
+ // a++ + ++b;
1157
+ // a - -b
1158
+ space_before = in_array(current_token.text, ['--', '-', '++', '+']) && in_array(flags.last_text, ['--', '-', '++', '+']);
1159
+ // + and - are not unary when preceeded by -- or ++ operator
1160
+ // a-- + b
1161
+ // a * +b
1162
+ // a - -b
1163
+ if (in_array(current_token.text, ['+', '-']) && in_array(flags.last_text, ['--', '++'])) {
1164
+ space_after = true;
1165
+ }
1166
+ }
1167
+
1168
+ if ((flags.mode === MODE.BlockStatement || flags.mode === MODE.Statement) && (flags.last_text === '{' || flags.last_text === ';')) {
1169
+ // { foo; --i }
1170
+ // foo(); --bar;
1171
+ print_newline();
1172
+ }
1173
+ } else if (current_token.text === ':') {
1174
+ if (flags.ternary_depth === 0) {
1175
+ // Colon is invalid javascript outside of ternary and object, but do our best to guess what was meant.
1176
+ space_before = false;
1177
+ } else {
1178
+ flags.ternary_depth -= 1;
1179
+ }
1180
+ } else if (current_token.text === '?') {
1181
+ flags.ternary_depth += 1;
1182
+ } else if (current_token.text === '*' && last_type === 'TK_RESERVED' && flags.last_text === 'function') {
1183
+ space_before = false;
1184
+ space_after = false;
1185
+ }
1186
+ output.space_before_token = output.space_before_token || space_before;
1187
+ print_token();
1188
+ output.space_before_token = space_after;
1189
+ }
1190
+
1191
+ function handle_block_comment() {
1192
+ if (output.raw) {
1193
+ output.add_raw_token(current_token)
1194
+ if (current_token.directives && current_token.directives['preserve'] === 'end') {
1195
+ // If we're testing the raw output behavior, do not allow a directive to turn it off.
1196
+ if (!opt.test_output_raw) {
1197
+ output.raw = false;
1198
+ }
1199
+ }
1200
+ return;
1201
+ }
1202
+
1203
+ if (current_token.directives) {
1204
+ print_newline(false, true);
1205
+ print_token();
1206
+ if (current_token.directives['preserve'] === 'start') {
1207
+ output.raw = true;
1208
+ }
1209
+ print_newline(false, true);
1210
+ return;
1211
+ }
1212
+
1213
+ // inline block
1214
+ if (!acorn.newline.test(current_token.text) && !current_token.wanted_newline) {
1215
+ output.space_before_token = true;
1216
+ print_token();
1217
+ output.space_before_token = true;
1218
+ return;
1219
+ }
1220
+
1221
+ var lines = split_newlines(current_token.text);
1222
+ var j; // iterator for this case
1223
+ var javadoc = false;
1224
+ var starless = false;
1225
+ var lastIndent = current_token.whitespace_before;
1226
+ var lastIndentLength = lastIndent.length;
1227
+
1228
+ // block comment starts with a new line
1229
+ print_newline(false, true);
1230
+ if (lines.length > 1) {
1231
+ if (all_lines_start_with(lines.slice(1), '*')) {
1232
+ javadoc = true;
1233
+ }
1234
+ else if (each_line_matches_indent(lines.slice(1), lastIndent)) {
1235
+ starless = true;
1236
+ }
1237
+ }
1238
+
1239
+ // first line always indented
1240
+ print_token(lines[0]);
1241
+ for (j = 1; j < lines.length; j++) {
1242
+ print_newline(false, true);
1243
+ if (javadoc) {
1244
+ // javadoc: reformat and re-indent
1245
+ print_token(' ' + ltrim(lines[j]));
1246
+ } else if (starless && lines[j].length > lastIndentLength) {
1247
+ // starless: re-indent non-empty content, avoiding trim
1248
+ print_token(lines[j].substring(lastIndentLength));
1249
+ } else {
1250
+ // normal comments output raw
1251
+ output.add_token(lines[j]);
1252
+ }
1253
+ }
1254
+
1255
+ // for comments of more than one line, make sure there's a new line after
1256
+ print_newline(false, true);
1257
+ }
1258
+
1259
+ function handle_comment() {
1260
+ if (current_token.wanted_newline) {
1261
+ print_newline(false, true);
1262
+ } else {
1263
+ output.trim(true);
1264
+ }
1265
+
1266
+ output.space_before_token = true;
1267
+ print_token();
1268
+ print_newline(false, true);
1269
+ }
1270
+
1271
+ function handle_dot() {
1272
+ if (start_of_statement()) {
1273
+ // The conditional starts the statement if appropriate.
1274
+ }
1275
+
1276
+ if (last_type === 'TK_RESERVED' && is_special_word(flags.last_text)) {
1277
+ output.space_before_token = true;
1278
+ } else {
1279
+ // allow preserved newlines before dots in general
1280
+ // force newlines on dots after close paren when break_chained - for bar().baz()
1281
+ allow_wrap_or_preserved_newline(flags.last_text === ')' && opt.break_chained_methods);
1282
+ }
1283
+
1284
+ print_token();
1285
+ }
1286
+
1287
+ function handle_unknown() {
1288
+ print_token();
1289
+
1290
+ if (current_token.text[current_token.text.length - 1] === '\n') {
1291
+ print_newline();
1292
+ }
1293
+ }
1294
+
1295
+ function handle_eof() {
1296
+ // Unwind any open statements
1297
+ while (flags.mode === MODE.Statement) {
1298
+ restore_mode();
1299
+ }
1300
+ }
1301
+ }
1302
+
1303
+
1304
+ function OutputLine(parent) {
1305
+ var _character_count = 0;
1306
+ // use indent_count as a marker for lines that have preserved indentation
1307
+ var _indent_count = -1;
1308
+
1309
+ var _items = [];
1310
+ var _empty = true;
1311
+
1312
+ this.set_indent = function(level) {
1313
+ _character_count = parent.baseIndentLength + level * parent.indent_length
1314
+ _indent_count = level;
1315
+ }
1316
+
1317
+ this.get_character_count = function() {
1318
+ return _character_count;
1319
+ }
1320
+
1321
+ this.is_empty = function() {
1322
+ return _empty;
1323
+ }
1324
+
1325
+ this.last = function() {
1326
+ if (!this._empty) {
1327
+ return _items[_items.length - 1];
1328
+ } else {
1329
+ return null;
1330
+ }
1331
+ }
1332
+
1333
+ this.push = function(input) {
1334
+ _items.push(input);
1335
+ _character_count += input.length;
1336
+ _empty = false;
1337
+ }
1338
+
1339
+ this.pop = function() {
1340
+ var item = null;
1341
+ if (!_empty) {
1342
+ item = _items.pop();
1343
+ _character_count -= item.length;
1344
+ _empty = _items.length === 0;
1345
+ }
1346
+ return item;
1347
+ }
1348
+
1349
+ this.remove_indent = function() {
1350
+ if (_indent_count > 0) {
1351
+ _indent_count -= 1;
1352
+ _character_count -= parent.indent_length
1353
+ }
1354
+ }
1355
+
1356
+ this.trim = function() {
1357
+ while (this.last() === ' ') {
1358
+ var item = _items.pop();
1359
+ _character_count -= 1;
1360
+ }
1361
+ _empty = _items.length === 0;
1362
+ }
1363
+
1364
+ this.toString = function() {
1365
+ var result = '';
1366
+ if (!this._empty) {
1367
+ if (_indent_count >= 0) {
1368
+ result = parent.indent_cache[_indent_count];
1369
+ }
1370
+ result += _items.join('')
1371
+ }
1372
+ return result;
1373
+ }
1374
+ }
1375
+
1376
+ function Output(indent_string, baseIndentString) {
1377
+ baseIndentString = baseIndentString || '';
1378
+ this.indent_cache = [ baseIndentString ];
1379
+ this.baseIndentLength = baseIndentString.length;
1380
+ this.indent_length = indent_string.length;
1381
+ this.raw = false;
1382
+
1383
+ var lines =[];
1384
+ this.baseIndentString = baseIndentString;
1385
+ this.indent_string = indent_string;
1386
+ this.previous_line = null;
1387
+ this.current_line = null;
1388
+ this.space_before_token = false;
1389
+
1390
+ this.add_outputline = function() {
1391
+ this.previous_line = this.current_line;
1392
+ this.current_line = new OutputLine(this);
1393
+ lines.push(this.current_line);
1394
+ }
1395
+
1396
+ // initialize
1397
+ this.add_outputline();
1398
+
1399
+
1400
+ this.get_line_number = function() {
1401
+ return lines.length;
1402
+ }
1403
+
1404
+ // Using object instead of string to allow for later expansion of info about each line
1405
+ this.add_new_line = function(force_newline) {
1406
+ if (this.get_line_number() === 1 && this.just_added_newline()) {
1407
+ return false; // no newline on start of file
1408
+ }
1409
+
1410
+ if (force_newline || !this.just_added_newline()) {
1411
+ if (!this.raw) {
1412
+ this.add_outputline();
1413
+ }
1414
+ return true;
1415
+ }
1416
+
1417
+ return false;
1418
+ }
1419
+
1420
+ this.get_code = function() {
1421
+ var sweet_code = lines.join('\n').replace(/[\r\n\t ]+$/, '');
1422
+ return sweet_code;
1423
+ }
1424
+
1425
+ this.set_indent = function(level) {
1426
+ // Never indent your first output indent at the start of the file
1427
+ if (lines.length > 1) {
1428
+ while(level >= this.indent_cache.length) {
1429
+ this.indent_cache.push(this.indent_cache[this.indent_cache.length - 1] + this.indent_string);
1430
+ }
1431
+
1432
+ this.current_line.set_indent(level);
1433
+ return true;
1434
+ }
1435
+ this.current_line.set_indent(0);
1436
+ return false;
1437
+ }
1438
+
1439
+ this.add_raw_token = function(token) {
1440
+ for (var x = 0; x < token.newlines; x++) {
1441
+ this.add_outputline();
1442
+ }
1443
+ this.current_line.push(token.whitespace_before);
1444
+ this.current_line.push(token.text);
1445
+ this.space_before_token = false;
1446
+ }
1447
+
1448
+ this.add_token = function(printable_token) {
1449
+ this.add_space_before_token();
1450
+ this.current_line.push(printable_token);
1451
+ }
1452
+
1453
+ this.add_space_before_token = function() {
1454
+ if (this.space_before_token && !this.just_added_newline()) {
1455
+ this.current_line.push(' ');
1456
+ }
1457
+ this.space_before_token = false;
1458
+ }
1459
+
1460
+ this.remove_redundant_indentation = function (frame) {
1461
+ // This implementation is effective but has some issues:
1462
+ // - can cause line wrap to happen too soon due to indent removal
1463
+ // after wrap points are calculated
1464
+ // These issues are minor compared to ugly indentation.
1465
+
1466
+ if (frame.multiline_frame ||
1467
+ frame.mode === MODE.ForInitializer ||
1468
+ frame.mode === MODE.Conditional) {
1469
+ return;
1470
+ }
1471
+
1472
+ // remove one indent from each line inside this section
1473
+ var index = frame.start_line_index;
1474
+ var line;
1475
+
1476
+ var output_length = lines.length;
1477
+ while (index < output_length) {
1478
+ lines[index].remove_indent();
1479
+ index++;
1480
+ }
1481
+ }
1482
+
1483
+ this.trim = function(eat_newlines) {
1484
+ eat_newlines = (eat_newlines === undefined) ? false : eat_newlines;
1485
+
1486
+ this.current_line.trim(indent_string, baseIndentString);
1487
+
1488
+ while (eat_newlines && lines.length > 1 &&
1489
+ this.current_line.is_empty()) {
1490
+ lines.pop();
1491
+ this.current_line = lines[lines.length - 1]
1492
+ this.current_line.trim();
1493
+ }
1494
+
1495
+ this.previous_line = lines.length > 1 ? lines[lines.length - 2] : null;
1496
+ }
1497
+
1498
+ this.just_added_newline = function() {
1499
+ return this.current_line.is_empty();
1500
+ }
1501
+
1502
+ this.just_added_blankline = function() {
1503
+ if (this.just_added_newline()) {
1504
+ if (lines.length === 1) {
1505
+ return true; // start of the file and newline = blank
1506
+ }
1507
+
1508
+ var line = lines[lines.length - 2];
1509
+ return line.is_empty();
1510
+ }
1511
+ return false;
1512
+ }
1513
+ }
1514
+
1515
+
1516
+ var Token = function(type, text, newlines, whitespace_before, mode, parent) {
1517
+ this.type = type;
1518
+ this.text = text;
1519
+ this.comments_before = [];
1520
+ this.newlines = newlines || 0;
1521
+ this.wanted_newline = newlines > 0;
1522
+ this.whitespace_before = whitespace_before || '';
1523
+ this.parent = null;
1524
+ this.directives = null;
1525
+ }
1526
+
1527
+ function tokenizer(input, opts, indent_string) {
1528
+
1529
+ var whitespace = "\n\r\t ".split('');
1530
+ var digit = /[0-9]/;
1531
+ var digit_hex = /[0123456789abcdefABCDEF]/;
1532
+
1533
+ var punct = ('+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! ~ , : ? ^ ^= |= :: =>').split(' ');
1534
+ // words which should always start on new line.
1535
+ this.line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
1536
+ var reserved_words = this.line_starters.concat(['do', 'in', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await']);
1537
+
1538
+ // /* ... */ comment ends with nearest */ or end of file
1539
+ var block_comment_pattern = /([\s\S]*?)((?:\*\/)|$)/g;
1540
+
1541
+ // comment ends just before nearest linefeed or end of file
1542
+ var comment_pattern = /([^\n\r\u2028\u2029]*)/g;
1543
+
1544
+ var directives_block_pattern = /\/\* beautify( \w+[:]\w+)+ \*\//g;
1545
+ var directive_pattern = / (\w+)[:](\w+)/g;
1546
+ var directives_end_ignore_pattern = /([\s\S]*?)((?:\/\*\sbeautify\signore:end\s\*\/)|$)/g;
1547
+
1548
+ var template_pattern = /((<\?php|<\?=)[\s\S]*?\?>)|(<%[\s\S]*?%>)/g
1549
+
1550
+ var n_newlines, whitespace_before_token, in_html_comment, tokens, parser_pos;
1551
+ var input_length;
1552
+
1553
+ this.tokenize = function() {
1554
+ // cache the source's length.
1555
+ input_length = input.length
1556
+ parser_pos = 0;
1557
+ in_html_comment = false
1558
+ tokens = [];
1559
+
1560
+ var next, last;
1561
+ var token_values;
1562
+ var open = null;
1563
+ var open_stack = [];
1564
+ var comments = [];
1565
+
1566
+ while (!(last && last.type === 'TK_EOF')) {
1567
+ token_values = tokenize_next();
1568
+ next = new Token(token_values[1], token_values[0], n_newlines, whitespace_before_token);
1569
+ while(next.type === 'TK_COMMENT' || next.type === 'TK_BLOCK_COMMENT' || next.type === 'TK_UNKNOWN') {
1570
+ if (next.type === 'TK_BLOCK_COMMENT') {
1571
+ next.directives = token_values[2];
1572
+ }
1573
+ comments.push(next);
1574
+ token_values = tokenize_next();
1575
+ next = new Token(token_values[1], token_values[0], n_newlines, whitespace_before_token);
1576
+ }
1577
+
1578
+ if (comments.length) {
1579
+ next.comments_before = comments;
1580
+ comments = [];
1581
+ }
1582
+
1583
+ if (next.type === 'TK_START_BLOCK' || next.type === 'TK_START_EXPR') {
1584
+ next.parent = last;
1585
+ open_stack.push(open);
1586
+ open = next;
1587
+ } else if ((next.type === 'TK_END_BLOCK' || next.type === 'TK_END_EXPR') &&
1588
+ (open && (
1589
+ (next.text === ']' && open.text === '[') ||
1590
+ (next.text === ')' && open.text === '(') ||
1591
+ (next.text === '}' && open.text === '{')))) {
1592
+ next.parent = open.parent;
1593
+ open = open_stack.pop();
1594
+ }
1595
+
1596
+ tokens.push(next);
1597
+ last = next;
1598
+ }
1599
+
1600
+ return tokens;
1601
+ }
1602
+
1603
+ function get_directives (text) {
1604
+ if (!text.match(directives_block_pattern)) {
1605
+ return null;
1606
+ }
1607
+
1608
+ var directives = {};
1609
+ directive_pattern.lastIndex = 0;
1610
+ var directive_match = directive_pattern.exec(text);
1611
+
1612
+ while (directive_match) {
1613
+ directives[directive_match[1]] = directive_match[2];
1614
+ directive_match = directive_pattern.exec(text);
1615
+ }
1616
+
1617
+ return directives;
1618
+ }
1619
+
1620
+ function tokenize_next() {
1621
+ var i, resulting_string;
1622
+ var whitespace_on_this_line = [];
1623
+
1624
+ n_newlines = 0;
1625
+ whitespace_before_token = '';
1626
+
1627
+ if (parser_pos >= input_length) {
1628
+ return ['', 'TK_EOF'];
1629
+ }
1630
+
1631
+ var last_token;
1632
+ if (tokens.length) {
1633
+ last_token = tokens[tokens.length-1];
1634
+ } else {
1635
+ // For the sake of tokenizing we can pretend that there was on open brace to start
1636
+ last_token = new Token('TK_START_BLOCK', '{');
1637
+ }
1638
+
1639
+
1640
+ var c = input.charAt(parser_pos);
1641
+ parser_pos += 1;
1642
+
1643
+ while (in_array(c, whitespace)) {
1644
+
1645
+ if (acorn.newline.test(c)) {
1646
+ if (!(c === '\n' && input.charAt(parser_pos-2) === '\r')) {
1647
+ n_newlines += 1;
1648
+ whitespace_on_this_line = [];
1649
+ }
1650
+ } else {
1651
+ whitespace_on_this_line.push(c);
1652
+ }
1653
+
1654
+ if (parser_pos >= input_length) {
1655
+ return ['', 'TK_EOF'];
1656
+ }
1657
+
1658
+ c = input.charAt(parser_pos);
1659
+ parser_pos += 1;
1660
+ }
1661
+
1662
+ if(whitespace_on_this_line.length) {
1663
+ whitespace_before_token = whitespace_on_this_line.join('');
1664
+ }
1665
+
1666
+ if (digit.test(c)) {
1667
+ var allow_decimal = true;
1668
+ var allow_e = true;
1669
+ var local_digit = digit;
1670
+
1671
+ if (c === '0' && parser_pos < input_length && /[Xx]/.test(input.charAt(parser_pos))) {
1672
+ // switch to hex number, no decimal or e, just hex digits
1673
+ allow_decimal = false;
1674
+ allow_e = false;
1675
+ c += input.charAt(parser_pos);
1676
+ parser_pos += 1;
1677
+ local_digit = digit_hex
1678
+ } else {
1679
+ // we know this first loop will run. It keeps the logic simpler.
1680
+ c = '';
1681
+ parser_pos -= 1
1682
+ }
1683
+
1684
+ // Add the digits
1685
+ while (parser_pos < input_length && local_digit.test(input.charAt(parser_pos))) {
1686
+ c += input.charAt(parser_pos);
1687
+ parser_pos += 1;
1688
+
1689
+ if (allow_decimal && parser_pos < input_length && input.charAt(parser_pos) === '.') {
1690
+ c += input.charAt(parser_pos);
1691
+ parser_pos += 1;
1692
+ allow_decimal = false;
1693
+ }
1694
+
1695
+ if (allow_e && parser_pos < input_length && /[Ee]/.test(input.charAt(parser_pos))) {
1696
+ c += input.charAt(parser_pos);
1697
+ parser_pos += 1;
1698
+
1699
+ if (parser_pos < input_length && /[+-]/.test(input.charAt(parser_pos))) {
1700
+ c += input.charAt(parser_pos);
1701
+ parser_pos += 1;
1702
+ }
1703
+
1704
+ allow_e = false;
1705
+ allow_decimal = false;
1706
+ }
1707
+ }
1708
+
1709
+ return [c, 'TK_WORD'];
1710
+ }
1711
+
1712
+ if (acorn.isIdentifierStart(input.charCodeAt(parser_pos-1))) {
1713
+ if (parser_pos < input_length) {
1714
+ while (acorn.isIdentifierChar(input.charCodeAt(parser_pos))) {
1715
+ c += input.charAt(parser_pos);
1716
+ parser_pos += 1;
1717
+ if (parser_pos === input_length) {
1718
+ break;
1719
+ }
1720
+ }
1721
+ }
1722
+
1723
+ if (!(last_token.type === 'TK_DOT' ||
1724
+ (last_token.type === 'TK_RESERVED' && in_array(last_token.text, ['set', 'get'])))
1725
+ && in_array(c, reserved_words)) {
1726
+ if (c === 'in') { // hack for 'in' operator
1727
+ return [c, 'TK_OPERATOR'];
1728
+ }
1729
+ return [c, 'TK_RESERVED'];
1730
+ }
1731
+
1732
+ return [c, 'TK_WORD'];
1733
+ }
1734
+
1735
+ if (c === '(' || c === '[') {
1736
+ return [c, 'TK_START_EXPR'];
1737
+ }
1738
+
1739
+ if (c === ')' || c === ']') {
1740
+ return [c, 'TK_END_EXPR'];
1741
+ }
1742
+
1743
+ if (c === '{') {
1744
+ return [c, 'TK_START_BLOCK'];
1745
+ }
1746
+
1747
+ if (c === '}') {
1748
+ return [c, 'TK_END_BLOCK'];
1749
+ }
1750
+
1751
+ if (c === ';') {
1752
+ return [c, 'TK_SEMICOLON'];
1753
+ }
1754
+
1755
+ if (c === '/') {
1756
+ var comment = '';
1757
+ // peek for comment /* ... */
1758
+ if (input.charAt(parser_pos) === '*') {
1759
+ parser_pos += 1;
1760
+ block_comment_pattern.lastIndex = parser_pos;
1761
+ var comment_match = block_comment_pattern.exec(input);
1762
+ comment = '/*' + comment_match[0];
1763
+ parser_pos += comment_match[0].length;
1764
+ var directives = get_directives(comment);
1765
+ if (directives && directives['ignore'] === 'start') {
1766
+ directives_end_ignore_pattern.lastIndex = parser_pos;
1767
+ comment_match = directives_end_ignore_pattern.exec(input)
1768
+ comment += comment_match[0];
1769
+ parser_pos += comment_match[0].length;
1770
+ }
1771
+ comment = comment.replace(acorn.lineBreak, '\n');
1772
+ return [comment, 'TK_BLOCK_COMMENT', directives];
1773
+ }
1774
+ // peek for comment // ...
1775
+ if (input.charAt(parser_pos) === '/') {
1776
+ parser_pos += 1;
1777
+ comment_pattern.lastIndex = parser_pos;
1778
+ var comment_match = comment_pattern.exec(input);
1779
+ comment = '//' + comment_match[0];
1780
+ parser_pos += comment_match[0].length;
1781
+ return [comment, 'TK_COMMENT'];
1782
+ }
1783
+
1784
+ }
1785
+
1786
+ if (c === '`' || c === "'" || c === '"' || // string
1787
+ (
1788
+ (c === '/') || // regexp
1789
+ (opts.e4x && c === "<" && input.slice(parser_pos - 1).match(/^<([-a-zA-Z:0-9_.]+|{[^{}]*}|!\[CDATA\[[\s\S]*?\]\])(\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{.*?}))*\s*(\/?)\s*>/)) // xml
1790
+ ) && ( // regex and xml can only appear in specific locations during parsing
1791
+ (last_token.type === 'TK_RESERVED' && in_array(last_token.text , ['return', 'case', 'throw', 'else', 'do', 'typeof', 'yield'])) ||
1792
+ (last_token.type === 'TK_END_EXPR' && last_token.text === ')' &&
1793
+ last_token.parent && last_token.parent.type === 'TK_RESERVED' && in_array(last_token.parent.text, ['if', 'while', 'for'])) ||
1794
+ (in_array(last_token.type, ['TK_COMMENT', 'TK_START_EXPR', 'TK_START_BLOCK',
1795
+ 'TK_END_BLOCK', 'TK_OPERATOR', 'TK_EQUALS', 'TK_EOF', 'TK_SEMICOLON', 'TK_COMMA'
1796
+ ]))
1797
+ )) {
1798
+
1799
+ var sep = c,
1800
+ esc = false,
1801
+ has_char_escapes = false;
1802
+
1803
+ resulting_string = c;
1804
+
1805
+ if (sep === '/') {
1806
+ //
1807
+ // handle regexp
1808
+ //
1809
+ var in_char_class = false;
1810
+ while (parser_pos < input_length &&
1811
+ ((esc || in_char_class || input.charAt(parser_pos) !== sep) &&
1812
+ !acorn.newline.test(input.charAt(parser_pos)))) {
1813
+ resulting_string += input.charAt(parser_pos);
1814
+ if (!esc) {
1815
+ esc = input.charAt(parser_pos) === '\\';
1816
+ if (input.charAt(parser_pos) === '[') {
1817
+ in_char_class = true;
1818
+ } else if (input.charAt(parser_pos) === ']') {
1819
+ in_char_class = false;
1820
+ }
1821
+ } else {
1822
+ esc = false;
1823
+ }
1824
+ parser_pos += 1;
1825
+ }
1826
+ } else if (opts.e4x && sep === '<') {
1827
+ //
1828
+ // handle e4x xml literals
1829
+ //
1830
+ var xmlRegExp = /<(\/?)([-a-zA-Z:0-9_.]+|{[^{}]*}|!\[CDATA\[[\s\S]*?\]\])(\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{.*?}))*\s*(\/?)\s*>/g;
1831
+ var xmlStr = input.slice(parser_pos - 1);
1832
+ var match = xmlRegExp.exec(xmlStr);
1833
+ if (match && match.index === 0) {
1834
+ var rootTag = match[2];
1835
+ var depth = 0;
1836
+ while (match) {
1837
+ var isEndTag = !! match[1];
1838
+ var tagName = match[2];
1839
+ var isSingletonTag = ( !! match[match.length - 1]) || (tagName.slice(0, 8) === "![CDATA[");
1840
+ if (tagName === rootTag && !isSingletonTag) {
1841
+ if (isEndTag) {
1842
+ --depth;
1843
+ } else {
1844
+ ++depth;
1845
+ }
1846
+ }
1847
+ if (depth <= 0) {
1848
+ break;
1849
+ }
1850
+ match = xmlRegExp.exec(xmlStr);
1851
+ }
1852
+ var xmlLength = match ? match.index + match[0].length : xmlStr.length;
1853
+ xmlStr = xmlStr.slice(0, xmlLength);
1854
+ parser_pos += xmlLength - 1;
1855
+ xmlStr = xmlStr.replace(acorn.lineBreak, '\n');
1856
+ return [xmlStr, "TK_STRING"];
1857
+ }
1858
+ } else {
1859
+ //
1860
+ // handle string
1861
+ //
1862
+ // Template strings can travers lines without escape characters.
1863
+ // Other strings cannot
1864
+ while (parser_pos < input_length &&
1865
+ (esc || (input.charAt(parser_pos) !== sep &&
1866
+ (sep === '`' || !acorn.newline.test(input.charAt(parser_pos)))))) {
1867
+ // Handle \r\n linebreaks after escapes or in template strings
1868
+ if ((esc || sep === '`') && acorn.newline.test(input.charAt(parser_pos))) {
1869
+ if (input.charAt(parser_pos) === '\r' && input.charAt(parser_pos + 1) === '\n') {
1870
+ parser_pos += 1;
1871
+ }
1872
+ resulting_string += '\n';
1873
+ } else {
1874
+ resulting_string += input.charAt(parser_pos);
1875
+ }
1876
+ if (esc) {
1877
+ if (input.charAt(parser_pos) === 'x' || input.charAt(parser_pos) === 'u') {
1878
+ has_char_escapes = true;
1879
+ }
1880
+ esc = false;
1881
+ } else {
1882
+ esc = input.charAt(parser_pos) === '\\';
1883
+ }
1884
+ parser_pos += 1;
1885
+ }
1886
+
1887
+ }
1888
+
1889
+ if (has_char_escapes && opts.unescape_strings) {
1890
+ resulting_string = unescape_string(resulting_string);
1891
+ }
1892
+
1893
+ if (parser_pos < input_length && input.charAt(parser_pos) === sep) {
1894
+ resulting_string += sep;
1895
+ parser_pos += 1;
1896
+
1897
+ if (sep === '/') {
1898
+ // regexps may have modifiers /regexp/MOD , so fetch those, too
1899
+ // Only [gim] are valid, but if the user puts in garbage, do what we can to take it.
1900
+ while (parser_pos < input_length && acorn.isIdentifierStart(input.charCodeAt(parser_pos))) {
1901
+ resulting_string += input.charAt(parser_pos);
1902
+ parser_pos += 1;
1903
+ }
1904
+ }
1905
+ }
1906
+ return [resulting_string, 'TK_STRING'];
1907
+ }
1908
+
1909
+ if (c === '#') {
1910
+
1911
+ if (tokens.length === 0 && input.charAt(parser_pos) === '!') {
1912
+ // shebang
1913
+ resulting_string = c;
1914
+ while (parser_pos < input_length && c !== '\n') {
1915
+ c = input.charAt(parser_pos);
1916
+ resulting_string += c;
1917
+ parser_pos += 1;
1918
+ }
1919
+ return [trim(resulting_string) + '\n', 'TK_UNKNOWN'];
1920
+ }
1921
+
1922
+
1923
+
1924
+ // Spidermonkey-specific sharp variables for circular references
1925
+ // https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
1926
+ // http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935
1927
+ var sharp = '#';
1928
+ if (parser_pos < input_length && digit.test(input.charAt(parser_pos))) {
1929
+ do {
1930
+ c = input.charAt(parser_pos);
1931
+ sharp += c;
1932
+ parser_pos += 1;
1933
+ } while (parser_pos < input_length && c !== '#' && c !== '=');
1934
+ if (c === '#') {
1935
+ //
1936
+ } else if (input.charAt(parser_pos) === '[' && input.charAt(parser_pos + 1) === ']') {
1937
+ sharp += '[]';
1938
+ parser_pos += 2;
1939
+ } else if (input.charAt(parser_pos) === '{' && input.charAt(parser_pos + 1) === '}') {
1940
+ sharp += '{}';
1941
+ parser_pos += 2;
1942
+ }
1943
+ return [sharp, 'TK_WORD'];
1944
+ }
1945
+ }
1946
+
1947
+ if (c === '<' && (input.charAt(parser_pos) === '?' || input.charAt(parser_pos) === '%')) {
1948
+ template_pattern.lastIndex = parser_pos - 1;
1949
+ var template_match = template_pattern.exec(input);
1950
+ if(template_match) {
1951
+ c = template_match[0];
1952
+ parser_pos += c.length - 1;
1953
+ c = c.replace(acorn.lineBreak, '\n');
1954
+ return [c, 'TK_STRING'];
1955
+ }
1956
+ }
1957
+
1958
+ if (c === '<' && input.substring(parser_pos - 1, parser_pos + 3) === '<!--') {
1959
+ parser_pos += 3;
1960
+ c = '<!--';
1961
+ while (!acorn.newline.test(input.charAt(parser_pos)) && parser_pos < input_length) {
1962
+ c += input.charAt(parser_pos);
1963
+ parser_pos++;
1964
+ }
1965
+ in_html_comment = true;
1966
+ return [c, 'TK_COMMENT'];
1967
+ }
1968
+
1969
+ if (c === '-' && in_html_comment && input.substring(parser_pos - 1, parser_pos + 2) === '-->') {
1970
+ in_html_comment = false;
1971
+ parser_pos += 2;
1972
+ return ['-->', 'TK_COMMENT'];
1973
+ }
1974
+
1975
+ if (c === '.') {
1976
+ return [c, 'TK_DOT'];
1977
+ }
1978
+
1979
+ if (in_array(c, punct)) {
1980
+ while (parser_pos < input_length && in_array(c + input.charAt(parser_pos), punct)) {
1981
+ c += input.charAt(parser_pos);
1982
+ parser_pos += 1;
1983
+ if (parser_pos >= input_length) {
1984
+ break;
1985
+ }
1986
+ }
1987
+
1988
+ if (c === ',') {
1989
+ return [c, 'TK_COMMA'];
1990
+ } else if (c === '=') {
1991
+ return [c, 'TK_EQUALS'];
1992
+ } else {
1993
+ return [c, 'TK_OPERATOR'];
1994
+ }
1995
+ }
1996
+
1997
+ return [c, 'TK_UNKNOWN'];
1998
+ }
1999
+
2000
+
2001
+ function unescape_string(s) {
2002
+ var esc = false,
2003
+ out = '',
2004
+ pos = 0,
2005
+ s_hex = '',
2006
+ escaped = 0,
2007
+ c;
2008
+
2009
+ while (esc || pos < s.length) {
2010
+
2011
+ c = s.charAt(pos);
2012
+ pos++;
2013
+
2014
+ if (esc) {
2015
+ esc = false;
2016
+ if (c === 'x') {
2017
+ // simple hex-escape \x24
2018
+ s_hex = s.substr(pos, 2);
2019
+ pos += 2;
2020
+ } else if (c === 'u') {
2021
+ // unicode-escape, \u2134
2022
+ s_hex = s.substr(pos, 4);
2023
+ pos += 4;
2024
+ } else {
2025
+ // some common escape, e.g \n
2026
+ out += '\\' + c;
2027
+ continue;
2028
+ }
2029
+ if (!s_hex.match(/^[0123456789abcdefABCDEF]+$/)) {
2030
+ // some weird escaping, bail out,
2031
+ // leaving whole string intact
2032
+ return s;
2033
+ }
2034
+
2035
+ escaped = parseInt(s_hex, 16);
2036
+
2037
+ if (escaped >= 0x00 && escaped < 0x20) {
2038
+ // leave 0x00...0x1f escaped
2039
+ if (c === 'x') {
2040
+ out += '\\x' + s_hex;
2041
+ } else {
2042
+ out += '\\u' + s_hex;
2043
+ }
2044
+ continue;
2045
+ } else if (escaped === 0x22 || escaped === 0x27 || escaped === 0x5c) {
2046
+ // single-quote, apostrophe, backslash - escape these
2047
+ out += '\\' + String.fromCharCode(escaped);
2048
+ } else if (c === 'x' && escaped > 0x7e && escaped <= 0xff) {
2049
+ // we bail out on \x7f..\xff,
2050
+ // leaving whole string escaped,
2051
+ // as it's probably completely binary
2052
+ return s;
2053
+ } else {
2054
+ out += String.fromCharCode(escaped);
2055
+ }
2056
+ } else if (c === '\\') {
2057
+ esc = true;
2058
+ } else {
2059
+ out += c;
2060
+ }
2061
+ }
2062
+ return out;
2063
+ }
2064
+
2065
+ }
2066
+
2067
+
2068
+ if (typeof define === "function" && define.amd) {
2069
+ // Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
2070
+ define([], function() {
2071
+ return { js_beautify: js_beautify };
2072
+ });
2073
+ } else if (typeof exports !== "undefined") {
2074
+ // Add support for CommonJS. Just put this file somewhere on your require.paths
2075
+ // and you will be able to `var js_beautify = require("beautify").js_beautify`.
2076
+ exports.js_beautify = js_beautify;
2077
+ } else if (typeof window !== "undefined") {
2078
+ // If we're running a web page and don't have either of the above, add our one global
2079
+ window.js_beautify = js_beautify;
2080
+ } else if (typeof global !== "undefined") {
2081
+ // If we don't even have window, try global.
2082
+ global.js_beautify = js_beautify;
2083
+ }
2084
+
2085
+ }());
js/tiny_mce/plugins/esites_editor/js/vendor/codemirror/util/formatting.js DELETED
@@ -1,115 +0,0 @@
1
- (function(mod) {
2
- if (typeof exports == "object" && typeof module == "object") // CommonJS
3
- mod(require("../lib/codemirror"));
4
- else if (typeof define == "function" && define.amd) // AMD
5
- define(["../lib/codemirror"], mod);
6
- else // Plain browser env
7
- mod(CodeMirror);
8
- })(function(CodeMirror) {
9
-
10
- CodeMirror.extendMode("css", {
11
- commentStart: "/*",
12
- commentEnd: "*/",
13
- newlineAfterToken: function(type, content) {
14
- return /^[;{}]$/.test(content);
15
- }
16
- });
17
-
18
- CodeMirror.extendMode("javascript", {
19
- commentStart: "/*",
20
- commentEnd: "*/",
21
- // FIXME semicolons inside of for
22
- newlineAfterToken: function(type, content, textAfter, state) {
23
- if (this.jsonMode) {
24
- return /^[\[,{]$/.test(content) || /^}/.test(textAfter);
25
- } else {
26
- if (content == ";" && state.lexical && state.lexical.type == ")") return false;
27
- return /^[;{}]$/.test(content) && !/^;/.test(textAfter);
28
- }
29
- }
30
- });
31
-
32
- CodeMirror.extendMode("xml", {
33
- commentStart: "<!--",
34
- commentEnd: "-->",
35
- newlineAfterToken: function(type, content, textAfter) {
36
- return type == "tag" && />$/.test(content) || /^</.test(textAfter);
37
- }
38
- });
39
-
40
- // Comment/uncomment the specified range
41
- CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
42
- var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode;
43
- cm.operation(function() {
44
- if (isComment) { // Comment range
45
- cm.replaceRange(curMode.commentEnd, to);
46
- cm.replaceRange(curMode.commentStart, from);
47
- if (from.line == to.line && from.ch == to.ch) // An empty comment inserted - put cursor inside
48
- cm.setCursor(from.line, from.ch + curMode.commentStart.length);
49
- } else { // Uncomment range
50
- var selText = cm.getRange(from, to);
51
- var startIndex = selText.indexOf(curMode.commentStart);
52
- var endIndex = selText.lastIndexOf(curMode.commentEnd);
53
- if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
54
- // Take string till comment start
55
- selText = selText.substr(0, startIndex)
56
- // From comment start till comment end
57
- + selText.substring(startIndex + curMode.commentStart.length, endIndex)
58
- // From comment end till string end
59
- + selText.substr(endIndex + curMode.commentEnd.length);
60
- }
61
- cm.replaceRange(selText, from, to);
62
- }
63
- });
64
- });
65
-
66
- // Applies automatic mode-aware indentation to the specified range
67
- CodeMirror.defineExtension("autoIndentRange", function (from, to) {
68
- var cmInstance = this;
69
- this.operation(function () {
70
- for (var i = from.line; i <= to.line; i++) {
71
- cmInstance.indentLine(i, "smart");
72
- }
73
- });
74
- });
75
-
76
- // Applies automatic formatting to the specified range
77
- CodeMirror.defineExtension("autoFormatRange", function (from, to) {
78
- var cm = this;
79
- var outer = cm.getMode(), text = cm.getRange(from, to).split("\n");
80
- var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state);
81
- var tabSize = cm.getOption("tabSize");
82
-
83
- var out = "", lines = 0, atSol = from.ch == 0;
84
- function newline() {
85
- out += "\n";
86
- atSol = true;
87
- ++lines;
88
- }
89
-
90
- for (var i = 0; i < text.length; ++i) {
91
- var stream = new CodeMirror.StringStream(text[i], tabSize);
92
- while (!stream.eol()) {
93
- var inner = CodeMirror.innerMode(outer, state);
94
- var style = outer.token(stream, state), cur = stream.current();
95
- stream.start = stream.pos;
96
- if (!atSol || /\S/.test(cur)) {
97
- out += cur;
98
- atSol = false;
99
- }
100
- if (!atSol && inner.mode.newlineAfterToken &&
101
- inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i+1] || "", inner.state))
102
- newline();
103
- }
104
- if (!stream.pos && outer.blankLine) outer.blankLine(state);
105
- if (!atSol) newline();
106
- }
107
-
108
- cm.operation(function () {
109
- cm.replaceRange(out, from, to);
110
- for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur)
111
- cm.indentLine(cur, "smart");
112
- cm.setSelection(from, cm.getCursor(false));
113
- });
114
- });
115
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Esites_Editor</name>
4
- <version>0.2.4</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
  <channel>community</channel>
@@ -12,13 +12,13 @@
12
  Of course you can open up the default source editor and go from there. But you probably know that this will not be very pleasant as well, the code looks like a big bowl of tag soup and editing it can give you a real headache.&#xD;
13
  &#xD;
14
  This extension adds an additional editor to Magento's WYSIWYG editor that is similar to your favorite IDE. It offers several great features that will not only save you quite a bit of time but also makes editing HTML a lot easier.</description>
15
- <notes>Fixed an autoloading issue&#xD;
16
  &#xD;
17
  The GitHub repo can be found at: https://github.com/e-sites/magento-advanced-html-editor</notes>
18
  <authors><author><name>Boye Oomens</name><user>boye</user><email>github@e-sites.nl</email></author></authors>
19
- <date>2015-07-27</date>
20
- <time>15:46:46</time>
21
- <contents><target name="magelocal"><dir name="Esites"><dir name="Editor"><dir name="Helper"><file name="Data.php" hash="cd176392637a27912dbc252d677404df"/></dir><dir name="Model"><file name="Config.php" hash="e452ebb7a7b11a2bd9ce9b44dcf78202"/><file name="Observer.php" hash="f729901c9cafe572c3f5a845b92d8a56"/><dir name="Source"><file name="Status.php" hash="11f4bbfb91f7eb60192fe5dd314948bd"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Indentunit"><file name="Values.php" hash="6201a40c6cf6ff70a945d1f14e8a0c1c"/></dir><dir name="Keymap"><file name="Values.php" hash="439483ce69cbca9dd47265dcae8e14b2"/></dir><dir name="Theme"><file name="Values.php" hash="5a19d932e7d2ad93b2a328402c7bd2ce"/></dir></dir></dir></dir></dir><dir name="etc"><file name="config.xml" hash="84845613af9b02b78f7dce4b456810e8"/><file name="system.xml" hash="f421cb099f0f86a297d3e4ac405bcc19"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Esites_Editor.xml" hash="3898822a14ae51a3811da3e1e7b801ce"/></dir></target><target name="mageweb"><dir name="js"><dir name="tiny_mce"><dir name="plugins"><dir name="esites_editor"><dir name="css"><file name="styles.css" hash="494871d7e69ec65162a911ebdf0105b2"/></dir><file name="esites_editor.html" hash="4a7256de4f6df2cdbc638b2d13ba687a"/><file name="esites_editor_plugin.js" hash="8e08e89e75496899c0e9cbb70323b195"/><file name="esites_editor_plugin_src.js" hash="29b1c1ca6640e00f489677d5403fbdfe"/><dir name="img"><file name="icon-esites-editor.png" hash="44c722d1cfa0465a94d0244583240812"/></dir><dir name="js"><dir name="app"><file name="main.js" hash="d4aead541fbccce41d6a9e3299f20a51"/><dir name="module"><file name="editor.js" hash="a3ddcaa39a48312c2e69d1a470da876e"/><file name="popup.js" hash="8ef6238768f93c416e0cec2bef19e0ef"/><file name="util.js" hash="a6832b31d51390f156325e9276f448d4"/></dir><dir name="var"><file name="addons.js" hash="582c831afe3882c54499a8f6e27574ba"/><file name="cmOptions.js" hash="71984ddb399af1206bee9c3c2a8d5312"/><file name="deps.js" hash="b88685190c40730355f723b0dd4082de"/><file name="plugin.js" hash="413f3aa9f10ea8752980d4711d2f9dfb"/><file name="textarea.js" hash="ba1efdbacc078ce5fad017e7ad965678"/></dir></dir><file name="app.js" hash="63570f79b53e3d67b3831b5ac1301aaf"/><dir name="vendor"><dir name="codemirror"><dir name="addon"><dir name="comment"><file name="comment.js" hash="e1233ff2b2428c5078ecfafbea23b7a0"/><file name="continuecomment.js" hash="2bad52d5a0b57d8f43e0e5b90bb25725"/></dir><dir name="dialog"><file name="dialog.css" hash="c89dce10b44d2882a024e7befc2b63f5"/><file name="dialog.js" hash="3429ebaf286acb91f04b8d3433251c1d"/></dir><dir name="display"><file name="fullscreen.css" hash="1a278e72b51528270f8ce9ec991929a1"/><file name="fullscreen.js" hash="fb86184c4fb36398188f2199fd28f167"/><file name="panel.js" hash="56e9558f431d1dffd85bf18ff2c9cd8d"/><file name="placeholder.js" hash="a406cc1590d2683a0114de4784f5421d"/><file name="rulers.js" hash="ff4f724e824fe42d72404a4fe4a756fe"/></dir><dir name="edit"><file name="closebrackets.js" hash="135aee995c406ae952e50b374c545562"/><file name="closetag.js" hash="34bce5a9d67d751ab0e4a0309f6a8b73"/><file name="continuelist.js" hash="1f902d5931a4c5d75b3d2b13aff71168"/><file name="matchbrackets.js" hash="94c58e98823144e56932aa2611c51dff"/><file name="matchtags.js" hash="545127ffedea5d77c0f68c809c75c5b6"/><file name="trailingspace.js" hash="650f095b187881451b0166d16ffd4091"/></dir><dir name="fold"><file name="brace-fold.js" hash="13f986f14247d953551bdfe93b27699e"/><file name="comment-fold.js" hash="5e5bdebcd4acb30c3aed47164e2af6b3"/><file name="foldcode.js" hash="76c21fd4c3f14d1a61765324ec82266b"/><file name="foldgutter.css" hash="38bb68770b6f7ebaa7adea770a68e0b1"/><file name="foldgutter.js" hash="021b76e831daea34fb2dd2f300077be0"/><file name="indent-fold.js" hash="b17f35bdd388f737113271b9e9070ea3"/><file name="markdown-fold.js" hash="c8783b56c820030045a57f291660ea20"/><file name="xml-fold.js" hash="f173dec3ccb5d6df5f37b9a99ecc438a"/></dir><dir name="hint"><file name="anyword-hint.js" hash="00b7028e5978a14b543f99e04739fd10"/><file name="css-hint.js" hash="0331f17931864c79688b80c3a8fcf0bf"/><file name="html-hint.js" hash="6b398a6ef3473b9f889092495fcc1545"/><file name="javascript-hint.js" hash="8febf4d6664e133fac9da1da672564cd"/><file name="show-hint.css" hash="630e320a614e7732f6ce1bf37147f27f"/><file name="show-hint.js" hash="662c4c0a36f065a3851d947a33165db3"/><file name="sql-hint.js" hash="3320167f10ccb11e1fb6d43e10e0c4f8"/><file name="xml-hint.js" hash="21d019d58516804262957d8879576908"/></dir><dir name="lint"><file name="coffeescript-lint.js" hash="a867c61ab04b4309206ba371bdde9fb7"/><file name="css-lint.js" hash="fd09f81d97cf3eb681cc5742d76ec47f"/><file name="javascript-lint.js" hash="5576a5092afdae4e7990abcbc92d0425"/><file name="json-lint.js" hash="49afe4d1a791c115de21553c28f1a6cf"/><file name="lint.css" hash="5f5d243947ec3ae1b8f37d85f0fa2a2d"/><file name="lint.js" hash="4ddf18f1a8f1e743e0089773b37db7ef"/><file name="yaml-lint.js" hash="117815f724aa2c3d671801ccedaa86ac"/></dir><dir name="merge"><file name="merge.css" hash="842786722589d900ffaf32652e89dac9"/><file name="merge.js" hash="0a076a685071b988fc11c90799400ed4"/></dir><dir name="mode"><file name="loadmode.js" hash="bc3c29fecceff0785b086b6e1c6f6b7c"/><file name="multiplex.js" hash="2d862f9ff445de58743d57007dadf3a8"/><file name="multiplex_test.js" hash="6e9c20d5c89c34f9245e1e346edc027b"/><file name="overlay.js" hash="7abff7c501c40008fc541414e803d954"/><file name="simple.js" hash="b3f550bd7554a29d6929e20aba3456ac"/></dir><dir name="runmode"><file name="colorize.js" hash="b0d93d54ee9bf76b246ea7cae39d6e75"/><file name="runmode-standalone.js" hash="54b1bc5448bbdfb53fdb3cbdc6740ef7"/><file name="runmode.js" hash="3266201540178df80d191c73bbd88152"/><file name="runmode.node.js" hash="e0d6deb878b58ce2329eb676b1146a1d"/></dir><dir name="scroll"><file name="annotatescrollbar.js" hash="48c6d9945674a1f807d164190094090c"/><file name="scrollpastend.js" hash="68e06dd3d77a87661790bbb7ebe2f080"/><file name="simplescrollbars.css" hash="0352ba51fd6a422fe6cc44925e33ad88"/><file name="simplescrollbars.js" hash="3a02029c076fb34aac136dd8c745be94"/></dir><dir name="search"><file name="match-highlighter.js" hash="b59268b1e4b6872df69110776d7f7934"/><file name="matchesonscrollbar.css" hash="00ea2770c568a848190bcf52e4241276"/><file name="matchesonscrollbar.js" hash="2cece6de1e3ad73489c170c8f08dd561"/><file name="search.js" hash="c9f245200e0efa341e4180e86733bf5a"/><file name="searchcursor.js" hash="a11e9186f471515209a5583f1af6421c"/></dir><dir name="selection"><file name="active-line.js" hash="c7c0cb21951ca1ba74837a74bbcd4b47"/><file name="mark-selection.js" hash="49df440e41a6f54264bce4f7ed7d7d05"/><file name="selection-pointer.js" hash="394ed7c792ed1954c6473d72e17156f9"/></dir><dir name="tern"><file name="tern.css" hash="8f36b875b840601834dfed2b69de0078"/><file name="tern.js" hash="fff8e060e7f942c26e6ed70fcae47ca9"/><file name="worker.js" hash="d6b55f3e776aafc6b1d1cd5bdf148e1d"/></dir><dir name="wrap"><file name="hardwrap.js" hash="0c70cedbc3ecc9474b11a24e23fe7b16"/></dir></dir><dir name="keymap"><file name="emacs.js" hash="9f95a4ebee67bc15739d34c6ebf5f2cc"/><file name="sublime.js" hash="aed0301397ec5401808e3ce051bb83a7"/><file name="vim.js" hash="6ae9bc84b361ebf60778fa469cb26078"/></dir><dir name="lib"><file name="codemirror.css" hash="3bc68598b602fb4d93df6abaae6c34f0"/><file name="codemirror.js" hash="1c5918f6b8c21ecedfd1bd06e0013e6d"/></dir><dir name="mode"><dir name="css"><file name="css.js" hash="b68d20ce073c2a809415d5e3ea6c9c84"/></dir><dir name="htmlmixed"><file name="htmlmixed.js" hash="4c7ab27882547c9075bc3a92c6278fbb"/></dir><dir name="javascript"><file name="javascript.js" hash="51b0e74a915e10ed9498e6b0035ae4b3"/></dir><dir name="xml"><file name="xml.js" hash="4304a1cbddb1f976e42893f59de690a1"/></dir></dir><dir name="theme"><file name="3024-day.css" hash="894a32efb2cfa60e36c9cc768cc0098a"/><file name="3024-night.css" hash="f1a444a6a4b50deac6a39189954a301b"/><file name="ambiance-mobile.css" hash="256f2dd130b80c6afaa40fddf700d12a"/><file name="ambiance.css" hash="51c29d465f0cf05b700db7bb56de30ea"/><file name="base16-dark.css" hash="1fb9180ba997460d4d366f7f08c6fd4f"/><file name="base16-light.css" hash="f66849c18f3b37a6858a13ee1e35848e"/><file name="blackboard.css" hash="a8ab62c90ab85a9c37f0ec70b54fbe99"/><file name="cobalt.css" hash="78b4d41cb127c1bd68be016009abc403"/><file name="colorforth.css" hash="1c2ac3b8535beb8c8d72daefcf1f2e82"/><file name="eclipse.css" hash="7c2f7b4b44b33fc9a5f857f542d007ac"/><file name="elegant.css" hash="c98914a034be0b11803bd3c24fba25dd"/><file name="erlang-dark.css" hash="93e7bc00530872f75f2407f7765cf755"/><file name="lesser-dark.css" hash="32e03c52c65d99e8de86d621e8059663"/><file name="liquibyte.css" hash="e32c54ecb4723675927388e8527d6515"/><file name="mbo.css" hash="8337ba3e4b9452cfe4a810c18fb3990d"/><file name="mdn-like.css" hash="7beb83c3ff5dd949ebea5c6840dc9ef3"/><file name="midnight.css" hash="73ebc77d60adac9c1d61608c7dc1344e"/><file name="monokai.css" hash="4caf13aa81a21c285cd195b7c9b20fa7"/><file name="neat.css" hash="673552ecebac76569063801293e9c76c"/><file name="neo.css" hash="f65035d751bacec07f189e3477f50bda"/><file name="night.css" hash="6ab152690c686b5d60d6d3f27f56dd31"/><file name="paraiso-dark.css" hash="b35f03d48623abf2327776955dd7cb86"/><file name="paraiso-light.css" hash="bbd066b1fb000c8ea3c1ffdac1f6c81b"/><file name="pastel-on-dark.css" hash="06a23867d779a12d33ffdc2a4db14088"/><file name="rubyblue.css" hash="2012b905229fdc2535321b1df631391c"/><file name="solarized.css" hash="02827534862eabe50b6e323490b10695"/><file name="the-matrix.css" hash="78a2e1eb98e9b4fe66b4e0e62f20db35"/><file name="tomorrow-night-bright.css" hash="15536604543d76ec2e0d30f593363062"/><file name="tomorrow-night-eighties.css" hash="061bbc6ab97d3b88a44c559583d301cf"/><file name="ttcn.css" hash="71e8cf8f41b49c587a0678ab32f81f13"/><file name="twilight.css" hash="99c1f0abe436ef5b456a34f99e80e9bc"/><file name="vibrant-ink.css" hash="69156002e7897ad324441766e7ee99a5"/><file name="xq-dark.css" hash="285c0f80f69a0bca86ac22d69bd47e75"/><file name="xq-light.css" hash="481023ea9d2e1d4c1707a1867c500326"/><file name="zenburn.css" hash="8211c2d07e48ca8553f77756a8c35bfd"/></dir><dir name="util"><file name="formatting.js" hash="4c9124ad8ec751239cd934f57c9a418c"/></dir></dir><dir name="emmet"><file name="emmet.js" hash="20b8a23a66c4329d0498bea0bc3ab018"/></dir><dir name="requirejs"><file name="css.min.js" hash="e787572d95902ef09257cea1c5b33de2"/><file name="require.min.js" hash="7198d1fc16fe630bd9357819ee8b65ef"/></dir></dir></dir><dir name="langs"><file name="en.js" hash="fecd78b74204e7236827c75801dfc155"/></dir></dir></dir></dir></dir></target></contents>
22
  <compatible/>
23
  <dependencies><required><php><min>5.4.0</min><max>6.0.0</max></php></required></dependencies>
24
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Esites_Editor</name>
4
+ <version>0.3.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
  <channel>community</channel>
12
  Of course you can open up the default source editor and go from there. But you probably know that this will not be very pleasant as well, the code looks like a big bowl of tag soup and editing it can give you a real headache.&#xD;
13
  &#xD;
14
  This extension adds an additional editor to Magento's WYSIWYG editor that is similar to your favorite IDE. It offers several great features that will not only save you quite a bit of time but also makes editing HTML a lot easier.</description>
15
+ <notes>Landed support for transactional emails, added a new code beautifier and implemented HTML autocompletion.&#xD;
16
  &#xD;
17
  The GitHub repo can be found at: https://github.com/e-sites/magento-advanced-html-editor</notes>
18
  <authors><author><name>Boye Oomens</name><user>boye</user><email>github@e-sites.nl</email></author></authors>
19
+ <date>2015-07-31</date>
20
+ <time>15:26:09</time>
21
+ <contents><target name="magelocal"><dir name="Esites"><dir name="Editor"><dir name="Helper"><file name="Data.php" hash="cd176392637a27912dbc252d677404df"/></dir><dir name="Model"><file name="Config.php" hash="723641a31a6a022bab51996ccc92915d"/><file name="Observer.php" hash="f729901c9cafe572c3f5a845b92d8a56"/><dir name="Source"><file name="Status.php" hash="11f4bbfb91f7eb60192fe5dd314948bd"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Indentunit"><file name="Values.php" hash="6201a40c6cf6ff70a945d1f14e8a0c1c"/></dir><dir name="Keymap"><file name="Values.php" hash="439483ce69cbca9dd47265dcae8e14b2"/></dir><dir name="Theme"><file name="Values.php" hash="5a19d932e7d2ad93b2a328402c7bd2ce"/></dir></dir></dir></dir></dir><dir name="etc"><file name="config.xml" hash="d21882540da028dd0628b955d1227fd0"/><file name="system.xml" hash="39604c563125980fd66a0363dea2607d"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Esites_Editor.xml" hash="3898822a14ae51a3811da3e1e7b801ce"/></dir></target><target name="mageweb"><dir name="js"><dir name="tiny_mce"><dir name="plugins"><dir name="esites_editor"><dir name="css"><file name="styles.css" hash="494871d7e69ec65162a911ebdf0105b2"/></dir><file name="esites_editor.html" hash="4a7256de4f6df2cdbc638b2d13ba687a"/><file name="esites_editor_plugin.js" hash="d1abcf24fcfce69052251f8445c32934"/><file name="esites_editor_plugin_src.js" hash="5a627a3b4e80c53a54422b3b68dbb570"/><dir name="img"><file name="icon-esites-editor.png" hash="44c722d1cfa0465a94d0244583240812"/></dir><dir name="js"><dir name="app"><file name="main.js" hash="0205523c030ef7d45b448691a14f13e2"/><dir name="module"><file name="editor.js" hash="6d68259e5e9dceaef554bed53d50a37d"/><file name="popup.js" hash="8b81addc4d9805bbc6712839172e5160"/><file name="util.js" hash="3dbf3e610b473326520ee38586151041"/></dir><dir name="var"><file name="addons.js" hash="69fa2c02830d8e02e91635e005e2e677"/><file name="cmOptions.js" hash="48042cb268055222690517c760c247e7"/><file name="deps.js" hash="d55e678756fce3b17847f7ee3d1885af"/><file name="plugin.js" hash="413f3aa9f10ea8752980d4711d2f9dfb"/><file name="textarea.js" hash="ba1efdbacc078ce5fad017e7ad965678"/></dir></dir><file name="app.js" hash="63570f79b53e3d67b3831b5ac1301aaf"/><dir name="vendor"><dir name="beautify"><file name="beautify-css.js" hash="089b995a960dcba679e00ca9126b1485"/><file name="beautify-html.js" hash="da7b543b5e13a8a101709b26caf5c0bf"/><file name="beautify.js" hash="7db35ceb33c1453cfae1d4981079fe62"/></dir><dir name="codemirror"><dir name="addon"><dir name="comment"><file name="comment.js" hash="e1233ff2b2428c5078ecfafbea23b7a0"/><file name="continuecomment.js" hash="2bad52d5a0b57d8f43e0e5b90bb25725"/></dir><dir name="dialog"><file name="dialog.css" hash="c89dce10b44d2882a024e7befc2b63f5"/><file name="dialog.js" hash="3429ebaf286acb91f04b8d3433251c1d"/></dir><dir name="display"><file name="fullscreen.css" hash="1a278e72b51528270f8ce9ec991929a1"/><file name="fullscreen.js" hash="fb86184c4fb36398188f2199fd28f167"/><file name="panel.js" hash="56e9558f431d1dffd85bf18ff2c9cd8d"/><file name="placeholder.js" hash="a406cc1590d2683a0114de4784f5421d"/><file name="rulers.js" hash="ff4f724e824fe42d72404a4fe4a756fe"/></dir><dir name="edit"><file name="closebrackets.js" hash="135aee995c406ae952e50b374c545562"/><file name="closetag.js" hash="34bce5a9d67d751ab0e4a0309f6a8b73"/><file name="continuelist.js" hash="1f902d5931a4c5d75b3d2b13aff71168"/><file name="matchbrackets.js" hash="94c58e98823144e56932aa2611c51dff"/><file name="matchtags.js" hash="545127ffedea5d77c0f68c809c75c5b6"/><file name="trailingspace.js" hash="650f095b187881451b0166d16ffd4091"/></dir><dir name="fold"><file name="brace-fold.js" hash="13f986f14247d953551bdfe93b27699e"/><file name="comment-fold.js" hash="5e5bdebcd4acb30c3aed47164e2af6b3"/><file name="foldcode.js" hash="76c21fd4c3f14d1a61765324ec82266b"/><file name="foldgutter.css" hash="38bb68770b6f7ebaa7adea770a68e0b1"/><file name="foldgutter.js" hash="021b76e831daea34fb2dd2f300077be0"/><file name="indent-fold.js" hash="b17f35bdd388f737113271b9e9070ea3"/><file name="markdown-fold.js" hash="c8783b56c820030045a57f291660ea20"/><file name="xml-fold.js" hash="f173dec3ccb5d6df5f37b9a99ecc438a"/></dir><dir name="hint"><file name="anyword-hint.js" hash="00b7028e5978a14b543f99e04739fd10"/><file name="css-hint.js" hash="0331f17931864c79688b80c3a8fcf0bf"/><file name="html-hint.js" hash="6b398a6ef3473b9f889092495fcc1545"/><file name="javascript-hint.js" hash="8febf4d6664e133fac9da1da672564cd"/><file name="show-hint.css" hash="630e320a614e7732f6ce1bf37147f27f"/><file name="show-hint.js" hash="662c4c0a36f065a3851d947a33165db3"/><file name="sql-hint.js" hash="3320167f10ccb11e1fb6d43e10e0c4f8"/><file name="xml-hint.js" hash="21d019d58516804262957d8879576908"/></dir><dir name="lint"><file name="coffeescript-lint.js" hash="a867c61ab04b4309206ba371bdde9fb7"/><file name="css-lint.js" hash="fd09f81d97cf3eb681cc5742d76ec47f"/><file name="javascript-lint.js" hash="5576a5092afdae4e7990abcbc92d0425"/><file name="json-lint.js" hash="49afe4d1a791c115de21553c28f1a6cf"/><file name="lint.css" hash="5f5d243947ec3ae1b8f37d85f0fa2a2d"/><file name="lint.js" hash="4ddf18f1a8f1e743e0089773b37db7ef"/><file name="yaml-lint.js" hash="117815f724aa2c3d671801ccedaa86ac"/></dir><dir name="merge"><file name="merge.css" hash="842786722589d900ffaf32652e89dac9"/><file name="merge.js" hash="0a076a685071b988fc11c90799400ed4"/></dir><dir name="mode"><file name="loadmode.js" hash="bc3c29fecceff0785b086b6e1c6f6b7c"/><file name="multiplex.js" hash="2d862f9ff445de58743d57007dadf3a8"/><file name="multiplex_test.js" hash="6e9c20d5c89c34f9245e1e346edc027b"/><file name="overlay.js" hash="7abff7c501c40008fc541414e803d954"/><file name="simple.js" hash="b3f550bd7554a29d6929e20aba3456ac"/></dir><dir name="runmode"><file name="colorize.js" hash="b0d93d54ee9bf76b246ea7cae39d6e75"/><file name="runmode-standalone.js" hash="54b1bc5448bbdfb53fdb3cbdc6740ef7"/><file name="runmode.js" hash="3266201540178df80d191c73bbd88152"/><file name="runmode.node.js" hash="e0d6deb878b58ce2329eb676b1146a1d"/></dir><dir name="scroll"><file name="annotatescrollbar.js" hash="48c6d9945674a1f807d164190094090c"/><file name="scrollpastend.js" hash="68e06dd3d77a87661790bbb7ebe2f080"/><file name="simplescrollbars.css" hash="0352ba51fd6a422fe6cc44925e33ad88"/><file name="simplescrollbars.js" hash="3a02029c076fb34aac136dd8c745be94"/></dir><dir name="search"><file name="match-highlighter.js" hash="b59268b1e4b6872df69110776d7f7934"/><file name="matchesonscrollbar.css" hash="00ea2770c568a848190bcf52e4241276"/><file name="matchesonscrollbar.js" hash="2cece6de1e3ad73489c170c8f08dd561"/><file name="search.js" hash="c9f245200e0efa341e4180e86733bf5a"/><file name="searchcursor.js" hash="a11e9186f471515209a5583f1af6421c"/></dir><dir name="selection"><file name="active-line.js" hash="c7c0cb21951ca1ba74837a74bbcd4b47"/><file name="mark-selection.js" hash="49df440e41a6f54264bce4f7ed7d7d05"/><file name="selection-pointer.js" hash="394ed7c792ed1954c6473d72e17156f9"/></dir><dir name="tern"><file name="tern.css" hash="8f36b875b840601834dfed2b69de0078"/><file name="tern.js" hash="fff8e060e7f942c26e6ed70fcae47ca9"/><file name="worker.js" hash="d6b55f3e776aafc6b1d1cd5bdf148e1d"/></dir><dir name="wrap"><file name="hardwrap.js" hash="0c70cedbc3ecc9474b11a24e23fe7b16"/></dir></dir><dir name="keymap"><file name="emacs.js" hash="9f95a4ebee67bc15739d34c6ebf5f2cc"/><file name="sublime.js" hash="aed0301397ec5401808e3ce051bb83a7"/><file name="vim.js" hash="6ae9bc84b361ebf60778fa469cb26078"/></dir><dir name="lib"><file name="codemirror.css" hash="3bc68598b602fb4d93df6abaae6c34f0"/><file name="codemirror.js" hash="1c5918f6b8c21ecedfd1bd06e0013e6d"/></dir><dir name="mode"><dir name="css"><file name="css.js" hash="b68d20ce073c2a809415d5e3ea6c9c84"/></dir><dir name="htmlmixed"><file name="htmlmixed.js" hash="4c7ab27882547c9075bc3a92c6278fbb"/></dir><dir name="javascript"><file name="javascript.js" hash="51b0e74a915e10ed9498e6b0035ae4b3"/></dir><dir name="xml"><file name="xml.js" hash="4304a1cbddb1f976e42893f59de690a1"/></dir></dir><dir name="theme"><file name="3024-day.css" hash="894a32efb2cfa60e36c9cc768cc0098a"/><file name="3024-night.css" hash="f1a444a6a4b50deac6a39189954a301b"/><file name="ambiance-mobile.css" hash="256f2dd130b80c6afaa40fddf700d12a"/><file name="ambiance.css" hash="51c29d465f0cf05b700db7bb56de30ea"/><file name="base16-dark.css" hash="1fb9180ba997460d4d366f7f08c6fd4f"/><file name="base16-light.css" hash="f66849c18f3b37a6858a13ee1e35848e"/><file name="blackboard.css" hash="a8ab62c90ab85a9c37f0ec70b54fbe99"/><file name="cobalt.css" hash="78b4d41cb127c1bd68be016009abc403"/><file name="colorforth.css" hash="1c2ac3b8535beb8c8d72daefcf1f2e82"/><file name="eclipse.css" hash="7c2f7b4b44b33fc9a5f857f542d007ac"/><file name="elegant.css" hash="c98914a034be0b11803bd3c24fba25dd"/><file name="erlang-dark.css" hash="93e7bc00530872f75f2407f7765cf755"/><file name="lesser-dark.css" hash="32e03c52c65d99e8de86d621e8059663"/><file name="liquibyte.css" hash="e32c54ecb4723675927388e8527d6515"/><file name="mbo.css" hash="8337ba3e4b9452cfe4a810c18fb3990d"/><file name="mdn-like.css" hash="7beb83c3ff5dd949ebea5c6840dc9ef3"/><file name="midnight.css" hash="73ebc77d60adac9c1d61608c7dc1344e"/><file name="monokai.css" hash="4caf13aa81a21c285cd195b7c9b20fa7"/><file name="neat.css" hash="673552ecebac76569063801293e9c76c"/><file name="neo.css" hash="f65035d751bacec07f189e3477f50bda"/><file name="night.css" hash="6ab152690c686b5d60d6d3f27f56dd31"/><file name="paraiso-dark.css" hash="b35f03d48623abf2327776955dd7cb86"/><file name="paraiso-light.css" hash="bbd066b1fb000c8ea3c1ffdac1f6c81b"/><file name="pastel-on-dark.css" hash="06a23867d779a12d33ffdc2a4db14088"/><file name="rubyblue.css" hash="2012b905229fdc2535321b1df631391c"/><file name="solarized.css" hash="02827534862eabe50b6e323490b10695"/><file name="the-matrix.css" hash="78a2e1eb98e9b4fe66b4e0e62f20db35"/><file name="tomorrow-night-bright.css" hash="15536604543d76ec2e0d30f593363062"/><file name="tomorrow-night-eighties.css" hash="061bbc6ab97d3b88a44c559583d301cf"/><file name="ttcn.css" hash="71e8cf8f41b49c587a0678ab32f81f13"/><file name="twilight.css" hash="99c1f0abe436ef5b456a34f99e80e9bc"/><file name="vibrant-ink.css" hash="69156002e7897ad324441766e7ee99a5"/><file name="xq-dark.css" hash="285c0f80f69a0bca86ac22d69bd47e75"/><file name="xq-light.css" hash="481023ea9d2e1d4c1707a1867c500326"/><file name="zenburn.css" hash="8211c2d07e48ca8553f77756a8c35bfd"/></dir></dir><dir name="emmet"><file name="emmet.js" hash="20b8a23a66c4329d0498bea0bc3ab018"/></dir><dir name="requirejs"><file name="css.min.js" hash="e787572d95902ef09257cea1c5b33de2"/><file name="require.min.js" hash="7198d1fc16fe630bd9357819ee8b65ef"/></dir></dir></dir><dir name="langs"><file name="en.js" hash="fecd78b74204e7236827c75801dfc155"/></dir></dir></dir></dir></dir></target></contents>
22
  <compatible/>
23
  <dependencies><required><php><min>5.4.0</min><max>6.0.0</max></php></required></dependencies>
24
  </package>