├── .nvmrc ├── .gitignore ├── icons ├── icon16.png ├── icon48.png ├── static.png └── icon128.png ├── images ├── images 0.png ├── new_ui.png ├── old_ui.png ├── images 22.png ├── images │ └── 12.png ├── screenshot.png ├── format-demo.gif ├── format-demo2.gif └── dynamic_layout.png ├── .prettierrc ├── package.json ├── .eslintrc.json ├── content.js ├── manifest.json ├── README.md ├── script.js └── beautify.js /.nvmrc: -------------------------------------------------------------------------------- 1 | v20.10.0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Archive.zip 2 | .DS_Store 3 | .keys.json 4 | node_modules 5 | *.zip -------------------------------------------------------------------------------- /icons/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/icons/icon16.png -------------------------------------------------------------------------------- /icons/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/icons/icon48.png -------------------------------------------------------------------------------- /icons/static.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/icons/static.png -------------------------------------------------------------------------------- /icons/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/icons/icon128.png -------------------------------------------------------------------------------- /images/images 0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/images 0.png -------------------------------------------------------------------------------- /images/new_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/new_ui.png -------------------------------------------------------------------------------- /images/old_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/old_ui.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": true 6 | } -------------------------------------------------------------------------------- /images/images 22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/images 22.png -------------------------------------------------------------------------------- /images/images/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/images/12.png -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/screenshot.png -------------------------------------------------------------------------------- /images/format-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/format-demo.gif -------------------------------------------------------------------------------- /images/format-demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/format-demo2.gif -------------------------------------------------------------------------------- /images/dynamic_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madhur/leetcode-format-chrome-extension/HEAD/images/dynamic_layout.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leetcode-format-chrome", 3 | "version": "1.8", 4 | "description": "LeetCode Code Format Google Chrome Extension", 5 | "main": "content.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Madhur Ahuja", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "eslint": "^8.6.0", 13 | "prettier": "^2.2.1", 14 | "eslint-config-prettier": "^9.0.0", 15 | "prettier-plugin-java": "^1.0.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": false 7 | }, 8 | "parserOptions": { 9 | "ecmaFeatures": { 10 | "jsx": true 11 | }, 12 | "sourceType": "module" 13 | }, 14 | "globals": { 15 | "dartfmt": true, 16 | "prettier": true, 17 | "js_beautify": true, 18 | "monaco": true, 19 | "chrome": true 20 | 21 | }, 22 | "rules": { 23 | "no-const-assign": 2, 24 | "no-extra-semi": 0, 25 | "semi": 0, 26 | "no-fallthrough": 0, 27 | "no-empty": 0, 28 | "no-mixed-spaces-and-tabs": 0, 29 | "no-redeclare": 0, 30 | "no-this-before-super": 1, 31 | "no-undef": 1, 32 | "no-unreachable": 1, 33 | "no-unused-vars": 1, 34 | "no-use-before-define": 0, 35 | "constructor-super": 1, 36 | "curly": 0, 37 | "eqeqeq": 0, 38 | "func-names": 0, 39 | "valid-typeof": 1 40 | } 41 | } -------------------------------------------------------------------------------- /content.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | let s = document.createElement("script"); 4 | 5 | // Install beautify 6 | s.type = "module"; 7 | s.src = chrome.runtime.getURL("beautify.js"); 8 | (document.head || document.documentElement).appendChild(s); 9 | 10 | // install script.js 11 | s = document.createElement("script"); 12 | s.type = "module"; 13 | s.src = chrome.runtime.getURL("script.js"); 14 | (document.head || document.documentElement).appendChild(s); 15 | 16 | s = document.createElement("script"); 17 | s.src = chrome.runtime.getURL("standalone.js"); 18 | (document.head || document.documentElement).appendChild(s); 19 | 20 | s = document.createElement("script"); 21 | s.src = chrome.runtime.getURL("parser-babel.mjs"); 22 | s.type = "module"; 23 | (document.head || document.documentElement).appendChild(s); 24 | 25 | s = document.createElement("script"); 26 | s.src = chrome.runtime.getURL("parser-typescript.mjs"); 27 | s.type = "module"; 28 | (document.head || document.documentElement).appendChild(s); 29 | 30 | s = document.createElement("script"); 31 | s.src = chrome.runtime.getURL("parser-java.js"); 32 | s.type = "module"; 33 | (document.head || document.documentElement).appendChild(s); 34 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Leetcode format", 3 | "version": "1.9", 4 | "manifest_version": 3, 5 | "description": "Adds Format code button on leetcode to format the code using Prettier code formatter", 6 | "homepage_url": "https://github.com/madhur/leetcode-format-chrome-extension", 7 | "icons": { 8 | "16": "icons/icon16.png", 9 | "48": "icons/icon48.png", 10 | "128": "icons/icon128.png" 11 | }, 12 | "content_scripts": [ 13 | { 14 | "js": [ 15 | "content.js" 16 | ], 17 | "matches": [ 18 | "https://*.leetcode.com/*", 19 | "https://*.leetcode.cn/*" 20 | ] 21 | } 22 | ], 23 | "web_accessible_resources": [ 24 | { 25 | "resources": [ 26 | "dart-style.js", 27 | "standalone.js", 28 | "parser-babel.mjs", 29 | "parser-typescript.mjs", 30 | "parser-java.js", 31 | "beautify.js", 32 | "script.js" 33 | ], 34 | "matches": [ 35 | "https://*.leetcode.com/*", 36 | "https://*.leetcode.cn/*" 37 | ] 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LeetCode Code Format Google Chrome Extension 2 | 3 | This extension adds the Format button to the [LeetCode](https://leetcode.com/) code editor. Available for [Google Chrome](https://chrome.google.com/webstore/detail/leetcode-format/imogghebhifnnlgogigikjecilkicfpp) and [Firefox](https://addons.mozilla.org/en-US/firefox/addon/leetcode-format/). 4 | 5 | 6 | The format button formats the code as per the [Prettier 7 | formatter](https://prettier.io/) and using [Dart style](https://github.com/dart-lang/dart_style) for Dart language 8 | 9 | Currently, following languages are supported, with plans to add more: 10 | * Java 11 | * C++ 12 | * JavaScript 13 | * TypeScript 14 | * Dart 15 | 16 | ## KeyBindings 17 | 18 | Use CTRL + ALT + F to trigger the format action through keyboard 19 | 20 | ## Contributors 21 | * [@alushpranav](https://github.com/alushpranav) - added support for Dart language 22 | * [@prabaljainn](https://github.com/prabaljainn) - added support for new Leetcode UI 23 | * [@imsoumya18](https://github.com/imsoumya18) - added hotkey support (CTRL + ALT + F) 24 | 25 | Send your feedback and any bug reports [here](https://github.com/madhur/leetcode-format-chrome-extension/issues) 26 | 27 | ### Demo GIF 28 | 29 | 30 | 31 | ### Dynamic layout 32 | 33 | 34 | 35 | ### New UI 36 | 37 | 38 | 39 | ### Old UI 40 | 41 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | import parserBabel from './parser-babel.mjs'; 2 | import parserTypeScript from './parser-typescript.mjs'; 3 | import prettierFormat_formatCode from './parser-java.js'; 4 | import './dart-style.js'; 5 | 6 | /*Old UI Variables */ 7 | const codeMirrorDOM = '.CodeMirror'; 8 | let codeMirror = null; 9 | /* Old UI Variables End */ 10 | 11 | /* New UI Variables */ 12 | let btn = null; 13 | const supportedLanguages = ['JAVA', 'JAVASCRIPT', 'TYPESCRIPT', 'C++', 'DART', "CPP"]; 14 | let theme = null; 15 | const lightTextColor = '#000000'; 16 | const darkTextColor = '#eff1f6ff'; 17 | /* New UI Variables END */ 18 | 19 | /* Common Variables */ 20 | let activeLanguage = null; 21 | /* Common Variables End */ 22 | 23 | let uiVersion = -1; 24 | 25 | window.addEventListener('load', startLoading, false); 26 | window.addEventListener('locationchange', function (event) { 27 | // Log the state data to the console 28 | console.log(event); 29 | if (document.getElementById('button-format') !== null) { 30 | console.debug('Button present'); 31 | } else { 32 | console.debug('Button not present'); 33 | } 34 | }); 35 | 36 | function startLoading() { 37 | let codeMirrorSelector = document.querySelector(codeMirrorDOM); 38 | if (codeMirrorSelector === undefined || codeMirrorSelector === null) { 39 | // codemirror not found on page 40 | // Check for new UI 41 | checkAndLoadNewUI(); 42 | return; 43 | } 44 | codeMirror = codeMirrorSelector.CodeMirror; 45 | if (codeMirror === undefined) { 46 | // codeMirror not found 47 | // this should not happen 48 | console.debug('FATAL: CodeMirror not found'); 49 | return; 50 | } 51 | 52 | activeLanguage = document.querySelector( 53 | '.ant-select-selection-selected-value' 54 | ); 55 | 56 | if (!activeLanguage || !activeLanguage.title) { 57 | // Dom not loaded yet 58 | return; 59 | } 60 | 61 | if (document.getElementById('format-button') !== null) { 62 | return; 63 | } else { 64 | console.debug('installing button'); 65 | } 66 | 67 | let button = getFormatButton(); 68 | uiVersion = 0; 69 | console.debug("Ui version is 0"); 70 | addShortcutBinding(formatCodeMirror); 71 | button.addEventListener('click', function () { 72 | formatCodeMirror(); 73 | }); 74 | 75 | activeLanguage.parentElement.parentElement.parentElement.parentElement.parentElement.appendChild( 76 | button 77 | ); 78 | } 79 | 80 | function checkAndLoadNewUI() { 81 | const buttonLocation = '.mr-auto.flex.flex-nowrap.items-center.gap-3'; 82 | 83 | if (!document.querySelector(buttonLocation)) { 84 | checkAndLoadNewUIv2(); 85 | return; 86 | } 87 | 88 | if ( 89 | !document.querySelector('.tool-button') && 90 | document.querySelector(buttonLocation) 91 | ) { 92 | uiVersion = 1; 93 | console.debug("Ui version is 1"); 94 | btn = getFormatButtonNew(); 95 | document.querySelector(buttonLocation).appendChild(btn); 96 | addShortcutBinding(formatCodeMonaco); 97 | setupLanguageObserver(); 98 | } 99 | } 100 | 101 | function checkAndLoadNewUIv2() { 102 | 103 | 104 | let buttonLocation = 'div.flex.flex-nowrap.items-center'; 105 | 106 | if ( 107 | !document.querySelector('.tool-button') && 108 | document.querySelector(buttonLocation) 109 | ) { 110 | uiVersion = 2; 111 | console.debug("Ui version is 2"); 112 | btn = getFormatButtonNew(); 113 | document.querySelector(buttonLocation).appendChild(btn); 114 | addShortcutBinding(formatCodeMonacov2); 115 | setupLanguageObserverv2(); 116 | } 117 | 118 | } 119 | 120 | 121 | function setupLanguageObserver() { 122 | const languageObserver = '.relative.notranslate'; 123 | const languageSelector = '.relative.notranslate div div'; 124 | const targetNode = document.querySelector(languageObserver); 125 | 126 | // Options for the observer (which mutations to observe) 127 | const config = { attributes: true, childList: true, subtree: true }; 128 | 129 | // Callback function to execute when mutations are observed 130 | const callback = (mutationList, observer) => { 131 | activeLanguage = document.querySelector(languageSelector).innerText; 132 | console.debug(activeLanguage); 133 | if (supportedLanguages.includes(activeLanguage.toUpperCase())) { 134 | btn.style.visibility = 'visible'; 135 | } else { 136 | btn.style.visibility = 'hidden'; 137 | } 138 | setButtonTheme(btn); 139 | }; 140 | 141 | // Create an observer instance linked to the callback function 142 | const observer = new MutationObserver(callback); 143 | 144 | // Start observing the target node for configured mutations 145 | observer.observe(targetNode, config); 146 | } 147 | 148 | 149 | function setupLanguageObserverv2() { 150 | const languageObserver = '[data-mode-id]'; 151 | const targetNode = document.querySelector(languageObserver); 152 | 153 | // Options for the observer (which mutations to observe) 154 | const config = { attributes: true, childList: false, subtree: false }; 155 | 156 | // Callback function to execute when mutations are observed 157 | const callback = (mutationList, observer) => { 158 | let d = document.querySelector('[data-mode-id]'); 159 | let activeLanguage = d.getAttribute('data-mode-id'); 160 | console.debug(activeLanguage); 161 | if (supportedLanguages.includes(activeLanguage.toUpperCase())) { 162 | btn.style.visibility = 'visible'; 163 | } else { 164 | btn.style.visibility = 'hidden'; 165 | } 166 | setButtonTheme(btn); 167 | }; 168 | 169 | // Create an observer instance linked to the callback function 170 | const observer = new MutationObserver(callback); 171 | 172 | // Start observing the target node for configured mutations 173 | observer.observe(targetNode, config); 174 | } 175 | 176 | const getFormatButtonNew = function () { 177 | var button = document.createElement('button'); 178 | button.innerHTML = 'Format'; 179 | button.className = 'tool-button'; 180 | button.id = 'format-button'; 181 | button.setAttribute('icon', 'information'); 182 | button.setAttribute('data-no-border', 'true'); 183 | button.setAttribute('type', 'ghost'); 184 | button.style.marginRight = '10px'; 185 | button.style.marginLeft = '10px'; 186 | button.style.border = 'none'; 187 | setButtonTheme(button); 188 | button.style.borderImage = 'none'; 189 | button.style.outline = 'none'; 190 | button.style.cursor = 'pointer'; 191 | button.title = 'Ctrl + Alt + F'; 192 | button.style.padding = '4px 20px'; 193 | button.style.fontWeight = '600'; 194 | button.style.borderRadius = '3px'; 195 | 196 | if (uiVersion == 1){ 197 | button.addEventListener('click', formatCodeMonaco); 198 | } 199 | else if (uiVersion == 2) { 200 | button.addEventListener('click', formatCodeMonacov2); 201 | } 202 | else { 203 | console.error("uiVersion variable not set", uiVersion); 204 | } 205 | return button; 206 | }; 207 | 208 | function addShortcutBinding(func) { 209 | window.addEventListener('keyup', (event) => { 210 | if (event.ctrlKey && event.altKey && event.key == 'f') 211 | func(); 212 | }); 213 | } 214 | 215 | const getFormatButton = function () { 216 | var button = document.createElement('button'); 217 | button.innerHTML = '▤'; 218 | button.className = 'tool-button'; 219 | button.id = 'format-button'; 220 | button.setAttribute('icon', 'information'); 221 | button.setAttribute('data-no-border', 'true'); 222 | button.setAttribute('type', 'ghost'); 223 | button.style.marginRight = '10px'; 224 | button.style.border = 'none'; 225 | button.style.backgroundColor = 'transparent'; 226 | button.style.borderImage = 'none'; 227 | button.style.outline = 'none'; 228 | button.style.cursor = 'pointer'; 229 | button.title = 'Ctrl + Alt + F'; 230 | return button; 231 | }; 232 | 233 | const formatCodeMirror = function () { 234 | let language = getLanguage(); 235 | let codeText = codeMirror.getValue(); 236 | const formattedCode = formatCode(codeText, language); 237 | if (formattedCode) { 238 | codeMirror.setValue(formattedCode); 239 | console.debug(`Code formatted for ${language}`); 240 | } 241 | }; 242 | 243 | const formatCodeMonaco = function () { 244 | let language = getLanguage(); 245 | 246 | let codeText = getCode(); 247 | const formattedCode = formatCode(codeText, language); 248 | if (formattedCode) { 249 | insertCode(formattedCode); 250 | console.debug(`Code formatted for ${language}`); 251 | } 252 | }; 253 | 254 | const formatCodeMonacov2 = function () { 255 | let language = getLanguage(); 256 | 257 | let codeText = getCodev2(); 258 | const formattedCode = formatCode(codeText, language); 259 | if (formattedCode) { 260 | insertCodev2(formattedCode); 261 | console.debug(`Code formatted for ${language}`); 262 | } 263 | }; 264 | 265 | function getLanguage() { 266 | if (uiVersion == 1) { 267 | return document.querySelector('.relative.notranslate').innerText; 268 | } 269 | else if (uiVersion == 2) { 270 | let d = document.querySelector('[data-mode-id]'); 271 | return d.getAttribute('data-mode-id'); 272 | } 273 | else if (uiVersion == 0) { 274 | return document.querySelector( 275 | '.ant-select-selection-selected-value' 276 | ).title; 277 | 278 | } 279 | } 280 | 281 | 282 | function insertCode(code) { 283 | if (code) { 284 | let model = monaco.editor.getModels()[0]; 285 | model.setValue(code); 286 | } 287 | } 288 | 289 | function insertCodev2(code) { 290 | if (code) { 291 | let model = findMonaco(); 292 | model.setValue(code); 293 | } 294 | } 295 | 296 | 297 | function getCode() { 298 | const model = monaco.editor.getModels()[0]; 299 | const code = model.getValue(); 300 | 301 | return code; 302 | } 303 | 304 | function getCodev2() { 305 | const model = findMonaco(); 306 | if (model == null) { 307 | console.error("Could not found instance of monaco editor"); 308 | return; 309 | } 310 | const code = model.getValue(); 311 | 312 | return code; 313 | } 314 | 315 | function findMonaco() { 316 | let models = monaco.editor.getModels(); 317 | const filter = function(m) { 318 | return m._languageId != "plaintext"; 319 | } 320 | if (models && models.length >= 1) { 321 | return models.find(filter); 322 | } 323 | 324 | } 325 | 326 | const formatCode = function (codeText, language) { 327 | if (language === undefined) { 328 | return; 329 | } 330 | if (codeText === undefined) { 331 | return; 332 | } 333 | let formattedCode = null; 334 | if (language.toUpperCase() === 'JavaScript'.toUpperCase()) { 335 | formattedCode = prettier.format(codeText, { 336 | parser: 'babel', 337 | plugins: [parserBabel], 338 | }); 339 | } else if (language.toUpperCase() === 'TypeScript'.toUpperCase()) { 340 | formattedCode = prettier.format(codeText, { 341 | parser: 'typescript', 342 | plugins: [parserTypeScript], 343 | }); 344 | } else if (language.toUpperCase() === 'Java'.toUpperCase()) { 345 | formattedCode = prettierFormat_formatCode.formatCode(codeText, { 346 | printWidth: 200, 347 | tabWidth: 4, 348 | }); 349 | } else if (language.toUpperCase() === 'C++'.toUpperCase() || language.toUpperCase() === "cpp".toUpperCase()) { 350 | formattedCode = js_beautify(codeText, { 351 | indent_size: 4, 352 | brace_style: 'expand', 353 | }); 354 | formattedCode = applyCustomRules(formattedCode); 355 | } else if (language.toUpperCase() === 'Dart'.toUpperCase()) { 356 | formattedCode = dartfmt.formatCode(codeText).code; 357 | } else { 358 | console.debug( 359 | `Formatter not available for ${language}` 360 | ); 361 | return; 362 | } 363 | 364 | return formattedCode; 365 | }; 366 | 367 | const applyCustomRules = function (formatted) { 368 | return formatted 369 | .replace(/\}\r\n/g, '}\n\n') 370 | .replace(/\<\s([a-zA-Z0-9_,: *&<>]+)\s>/g, '<$1>') 371 | .replace(/\<\s([a-zA-Z0-9_,: *&<>]+)>/g, '<$1>') 372 | .replace(/\<([a-zA-Z0-9_:*]+)\s>/g, '<$1>') 373 | .replace(/iterator\s?;:"'`!@#$%^&*()\[\]{}_+=|\\-]+)#include/g, 394 | '$1\r\n#include' 395 | ) 396 | .replace(/vector /g, '->') 406 | .replace(/\(\s+{\s+/g, '({ ') 407 | .replace(/\s+\}\)/g, ' })') 408 | .replace(/\tpublic_colon/g, 'public:') 409 | .replace(/\tprivate_colon/g, 'private:') 410 | .replace(/\tprotected_colon/g, 'protected:') 411 | 412 | .replace(/^#define(.*)$/, '#define') 413 | 414 | .replace(/xxxx/g, 'const') 415 | .replace(/\*(\s+)const/g, '*const') 416 | 417 | .replace(/operator (\W+) /g, 'operator$1') 418 | .replace(/operator<= >/g, 'operator<=>') 419 | .replace(/=(\s+)default/g, '= default') 420 | .replace(/; \}/g, ';\n}') 421 | .replace(/{\n\t\t\t/g, '{ ') 422 | .replace(/= { {/g, '= {\n\t\t{') 423 | .replace(/} };/g, '}\n\t};') 424 | 425 | .replace(/(\W+)\* /g, '$1*') 426 | .replace(/;\*/g, '; *') 427 | .replace(/(\w+) \*(\w+);/g, '$1 * $2;') 428 | .replace(/(\w+) \*(\w+)\)/g, '$1 * $2)') 429 | .replace(/(\w+) \*(\w+)\(/g, '$1 * $2(') 430 | .replace(/(\w+)(\s*)\*(\w+)(\s*)\/g, '$1 * $3 >') 432 | .replace(/(\w+)(\s*)\*(\w+)(\s*)\=/g, '$1 * $3 =') 433 | .replace(/(\d+)(\s*)\*(\d+)/g, '$1 * $3') 434 | 435 | .replace(/(\W) \* (\w)/g, '$1 *$2') 436 | .replace(/->\* /g, '->*') 437 | .replace(/ \[ &/g, ' [&') 438 | .replace(/\r\n\r\nusing/g, '\r\nusing') 439 | .replace(/\n\nusing/g, '\nusing') 440 | .replace(/\s,\s/g, ', ') 441 | .replace(/> ::/g, '>::') 442 | 443 | .replace(/(\s+)&\s+/g, '$1&') 444 | .replace(/\s\[/g, '[') 445 | .replace(/\(\s/g, '(') 446 | .replace(/\s\)/g, ')') 447 | 448 | .replace(/int \* /g, 'int *') 449 | .replace(/char \* /g, 'char *') 450 | .replace(/double \* /g, 'double *') 451 | .replace(/float \* /g, 'float *') 452 | .replace(/bool \* /g, 'bool *') 453 | .replace(/void \* /g, 'void *') 454 | .replace(/wchar_t \* /g, 'wchar_t *') 455 | 456 | .replace(/(\w+) \*\* /g, '$1 **') 457 | 458 | .replace(/\((\w+) \*\)/g, '($1*)') 459 | .replace(/(\w+) \*\>/g, '$1*>') 460 | 461 | .replace(/(\s)\<= /g, '$1 <= ') 462 | 463 | .replace(/\((\w+) &(\w+)\)/g, '($1 & $2)') 464 | .replace(/\[(\w+) &(\w+)\]/g, '[$1 & $2]') 465 | 466 | .replace(/\s<\s/g, '<') 467 | .replace(/\s<([^<])/g, '<$1') 468 | .replace( 469 | /([A-Za-z0-9_,\.\(\)\[\]\-\>]+)<([A-Za-z0-9_,\.\(\)\[\]\-\>]+)([\s\;\)])/g, 470 | '$1 < $2$3' 471 | ) 472 | 473 | .replace(/<(\s+)const/g, ' /g, '$1 > ') 478 | .replace(/(\w)\>= /g, '$1 >= ') 479 | .replace(/\s+{}/g, ' {}') 480 | .replace(/\s+{\s+}/g, ' {}') 481 | 482 | .replace(/\s\<\s(\w+)\s\*,/g, '<$1*,') 483 | .replace(/\[ \*/g, '[*') 484 | 485 | .replace(/\<(\w+)\s\>/g, '<$1>') 486 | .replace(/, (\w+)\s\>/g, ', $1>') 487 | 488 | .replace(/\/\/TEMPLATE/g, 'template <') 489 | .replace(/\[ = \]/g, '[=]') 490 | .replace(/\}\n\n}/g, '}\n}') 491 | .replace(/\}\n\n(\s*)\}/g, '}\n$1}') 492 | .replace(/\}\n\n(\s+)\}/g, '}\n$1}') 493 | 494 | .replace(/\}\n\n(\s+)else/g, '}\n$1else') 495 | 496 | .replace(/\n\}\)\;/g, '\n\t});') 497 | .replace(/\,\[/g, ', [') 498 | 499 | .replace(/\;\n\n(\s+)\}/g, ';\n$1}') 500 | 501 | .replace(/(\s+)\{([ \t]+)(\w+)/g, '$1{$1\t$3') 502 | .replace(/(\s+)\{([ \t]+)\/\//g, '$1{$1$2//') 503 | .replace(/=\s{(\s+)/g, '= { ') 504 | 505 | .replace(/\{\r\n\s+([0-9,-\s.]+)\r\n\s+\}/g, '{ $1 }') 506 | .replace(/\{\n\s+([0-9,-\s.]+)\n\s+\}/g, '{ $1 }') 507 | .replace(/\{ \{/g, '{\n\t\t{') 508 | .replace(/ \/\//g, '\t//') 509 | 510 | .replace(/(['"])(\s+)\}/g, '$1 }') 511 | .replace(/(\w+) \* (\w+) =/g, '$1 *$2 =') 512 | .replace(/(\w+) \* (\w+)\)/g, '$1 *$2)') 513 | .replace(/(\w+) \* (\w+)\(/g, '$1* $2(') 514 | 515 | .replace(/(\w+) \*\& (\w+)/g, '$1* &$2') 516 | 517 | .replace(/\s\<\s(\w+)\s\>/g, '<$1>') 518 | .replace(/\s\<\s(\w+)\,/g, '<$1,') 519 | .replace(/\{\}~/g, '{}\n\t~') 520 | .replace(/_cast \s+\{\s*([A-Za-z0-9 ,-.\"]+)\s+\}\;/g, '> { $1 };'); 523 | }; 524 | 525 | const setButtonTheme = function (btn) { 526 | theme = document.getElementsByTagName('html')[0].getAttribute('data-theme'); 527 | if (theme === 'dark') { 528 | btn.style.color = darkTextColor; 529 | } else if (theme === 'light') { 530 | btn.style.color = lightTextColor; 531 | } 532 | }; 533 | 534 | setTimeout(startLoading, 5000); 535 | -------------------------------------------------------------------------------- /beautify.js: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED. DO NOT MODIFY. */ 2 | /* 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, 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, 33 | https://beautifier.io/ 34 | 35 | Originally converted to javascript by Vital, 36 | "End braces on own line" added by Chris J. Shull, 37 | Parsing improvements for brace-less statements by Liam Newman 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" | any of the former + ",preserve-inline" 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 | preserve-inline will try to preserve inline blocks of curly braces 67 | 68 | space_before_conditional (default true) - should the space before conditional statement be added, "if(true)" vs "if (true)", 69 | 70 | unescape_strings (default false) - should printable characters in strings encoded in \xNN notation be unescaped, "example" vs "\x65\x78\x61\x6d\x70\x6c\x65" 71 | 72 | wrap_line_length (default unlimited) - lines should wrap at next opportunity after this number of characters. 73 | NOTE: This is not a hard limit. Lines will continue until a point where a newline would 74 | be preserved if it were present. 75 | 76 | end_with_newline (default false) - end output with a newline 77 | 78 | 79 | e.g 80 | 81 | js_beautify(js_source_text, { 82 | 'indent_size': 1, 83 | 'indent_char': '\t' 84 | }); 85 | 86 | */ 87 | 88 | (function() { 89 | 90 | /* GENERATED_BUILD_OUTPUT */ 91 | var legacy_beautify_js; 92 | /******/ (function() { // webpackBootstrap 93 | /******/ "use strict"; 94 | /******/ var __webpack_modules__ = ([ 95 | /* 0 */ 96 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 97 | 98 | /*jshint node:true */ 99 | /* 100 | 101 | The MIT License (MIT) 102 | 103 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 104 | 105 | Permission is hereby granted, free of charge, to any person 106 | obtaining a copy of this software and associated documentation files 107 | (the "Software"), to deal in the Software without restriction, 108 | including without limitation the rights to use, copy, modify, merge, 109 | publish, distribute, sublicense, and/or sell copies of the Software, 110 | and to permit persons to whom the Software is furnished to do so, 111 | subject to the following conditions: 112 | 113 | The above copyright notice and this permission notice shall be 114 | included in all copies or substantial portions of the Software. 115 | 116 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 117 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 118 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 119 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 120 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 121 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 122 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 123 | SOFTWARE. 124 | */ 125 | 126 | 127 | 128 | var Beautifier = __webpack_require__(1).Beautifier, 129 | Options = __webpack_require__(5).Options; 130 | 131 | function js_beautify(js_source_text, options) { 132 | var beautifier = new Beautifier(js_source_text, options); 133 | return beautifier.beautify(); 134 | } 135 | 136 | module.exports = js_beautify; 137 | module.exports.defaultOptions = function() { 138 | return new Options(); 139 | }; 140 | 141 | 142 | /***/ }), 143 | /* 1 */ 144 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 145 | 146 | /*jshint node:true */ 147 | /* 148 | 149 | The MIT License (MIT) 150 | 151 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 152 | 153 | Permission is hereby granted, free of charge, to any person 154 | obtaining a copy of this software and associated documentation files 155 | (the "Software"), to deal in the Software without restriction, 156 | including without limitation the rights to use, copy, modify, merge, 157 | publish, distribute, sublicense, and/or sell copies of the Software, 158 | and to permit persons to whom the Software is furnished to do so, 159 | subject to the following conditions: 160 | 161 | The above copyright notice and this permission notice shall be 162 | included in all copies or substantial portions of the Software. 163 | 164 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 165 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 166 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 167 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 168 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 169 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 170 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 171 | SOFTWARE. 172 | */ 173 | 174 | 175 | 176 | var Output = __webpack_require__(2).Output; 177 | var Token = __webpack_require__(3).Token; 178 | var acorn = __webpack_require__(4); 179 | var Options = __webpack_require__(5).Options; 180 | var Tokenizer = __webpack_require__(7).Tokenizer; 181 | var line_starters = __webpack_require__(7).line_starters; 182 | var positionable_operators = __webpack_require__(7).positionable_operators; 183 | var TOKEN = __webpack_require__(7).TOKEN; 184 | 185 | 186 | function in_array(what, arr) { 187 | return arr.indexOf(what) !== -1; 188 | } 189 | 190 | function ltrim(s) { 191 | return s.replace(/^\s+/g, ''); 192 | } 193 | 194 | function generateMapFromStrings(list) { 195 | var result = {}; 196 | for (var x = 0; x < list.length; x++) { 197 | // make the mapped names underscored instead of dash 198 | result[list[x].replace(/-/g, '_')] = list[x]; 199 | } 200 | return result; 201 | } 202 | 203 | function reserved_word(token, word) { 204 | return token && token.type === TOKEN.RESERVED && token.text === word; 205 | } 206 | 207 | function reserved_array(token, words) { 208 | return token && token.type === TOKEN.RESERVED && in_array(token.text, words); 209 | } 210 | // Unsure of what they mean, but they work. Worth cleaning up in future. 211 | var special_words = ['case', 'return', 'do', 'if', 'throw', 'else', 'await', 'break', 'continue', 'async']; 212 | 213 | var validPositionValues = ['before-newline', 'after-newline', 'preserve-newline']; 214 | 215 | // Generate map from array 216 | var OPERATOR_POSITION = generateMapFromStrings(validPositionValues); 217 | 218 | var OPERATOR_POSITION_BEFORE_OR_PRESERVE = [OPERATOR_POSITION.before_newline, OPERATOR_POSITION.preserve_newline]; 219 | 220 | var MODE = { 221 | BlockStatement: 'BlockStatement', // 'BLOCK' 222 | Statement: 'Statement', // 'STATEMENT' 223 | ObjectLiteral: 'ObjectLiteral', // 'OBJECT', 224 | ArrayLiteral: 'ArrayLiteral', //'[EXPRESSION]', 225 | ForInitializer: 'ForInitializer', //'(FOR-EXPRESSION)', 226 | Conditional: 'Conditional', //'(COND-EXPRESSION)', 227 | Expression: 'Expression' //'(EXPRESSION)' 228 | }; 229 | 230 | function remove_redundant_indentation(output, frame) { 231 | // This implementation is effective but has some issues: 232 | // - can cause line wrap to happen too soon due to indent removal 233 | // after wrap points are calculated 234 | // These issues are minor compared to ugly indentation. 235 | 236 | if (frame.multiline_frame || 237 | frame.mode === MODE.ForInitializer || 238 | frame.mode === MODE.Conditional) { 239 | return; 240 | } 241 | 242 | // remove one indent from each line inside this section 243 | output.remove_indent(frame.start_line_index); 244 | } 245 | 246 | // we could use just string.split, but 247 | // IE doesn't like returning empty strings 248 | function split_linebreaks(s) { 249 | //return s.split(/\x0d\x0a|\x0a/); 250 | 251 | s = s.replace(acorn.allLineBreaks, '\n'); 252 | var out = [], 253 | idx = s.indexOf("\n"); 254 | while (idx !== -1) { 255 | out.push(s.substring(0, idx)); 256 | s = s.substring(idx + 1); 257 | idx = s.indexOf("\n"); 258 | } 259 | if (s.length) { 260 | out.push(s); 261 | } 262 | return out; 263 | } 264 | 265 | function is_array(mode) { 266 | return mode === MODE.ArrayLiteral; 267 | } 268 | 269 | function is_expression(mode) { 270 | return in_array(mode, [MODE.Expression, MODE.ForInitializer, MODE.Conditional]); 271 | } 272 | 273 | function all_lines_start_with(lines, c) { 274 | for (var i = 0; i < lines.length; i++) { 275 | var line = lines[i].trim(); 276 | if (line.charAt(0) !== c) { 277 | return false; 278 | } 279 | } 280 | return true; 281 | } 282 | 283 | function each_line_matches_indent(lines, indent) { 284 | var i = 0, 285 | len = lines.length, 286 | line; 287 | for (; i < len; i++) { 288 | line = lines[i]; 289 | // allow empty lines to pass through 290 | if (line && line.indexOf(indent) !== 0) { 291 | return false; 292 | } 293 | } 294 | return true; 295 | } 296 | 297 | 298 | function Beautifier(source_text, options) { 299 | options = options || {}; 300 | this._source_text = source_text || ''; 301 | 302 | this._output = null; 303 | this._tokens = null; 304 | this._last_last_text = null; 305 | this._flags = null; 306 | this._previous_flags = null; 307 | 308 | this._flag_store = null; 309 | this._options = new Options(options); 310 | } 311 | 312 | Beautifier.prototype.create_flags = function(flags_base, mode) { 313 | var next_indent_level = 0; 314 | if (flags_base) { 315 | next_indent_level = flags_base.indentation_level; 316 | if (!this._output.just_added_newline() && 317 | flags_base.line_indent_level > next_indent_level) { 318 | next_indent_level = flags_base.line_indent_level; 319 | } 320 | } 321 | 322 | var next_flags = { 323 | mode: mode, 324 | parent: flags_base, 325 | last_token: flags_base ? flags_base.last_token : new Token(TOKEN.START_BLOCK, ''), // last token text 326 | last_word: flags_base ? flags_base.last_word : '', // last TOKEN.WORD passed 327 | declaration_statement: false, 328 | declaration_assignment: false, 329 | multiline_frame: false, 330 | inline_frame: false, 331 | if_block: false, 332 | else_block: false, 333 | do_block: false, 334 | do_while: false, 335 | import_block: false, 336 | in_case_statement: false, // switch(..){ INSIDE HERE } 337 | in_case: false, // we're on the exact line with "case 0:" 338 | case_body: false, // the indented case-action block 339 | indentation_level: next_indent_level, 340 | alignment: 0, 341 | line_indent_level: flags_base ? flags_base.line_indent_level : next_indent_level, 342 | start_line_index: this._output.get_line_number(), 343 | ternary_depth: 0 344 | }; 345 | return next_flags; 346 | }; 347 | 348 | Beautifier.prototype._reset = function(source_text) { 349 | var baseIndentString = source_text.match(/^[\t ]*/)[0]; 350 | 351 | this._last_last_text = ''; // pre-last token text 352 | this._output = new Output(this._options, baseIndentString); 353 | 354 | // If testing the ignore directive, start with output disable set to true 355 | this._output.raw = this._options.test_output_raw; 356 | 357 | 358 | // Stack of parsing/formatting states, including MODE. 359 | // We tokenize, parse, and output in an almost purely a forward-only stream of token input 360 | // and formatted output. This makes the beautifier less accurate than full parsers 361 | // but also far more tolerant of syntax errors. 362 | // 363 | // For example, the default mode is MODE.BlockStatement. If we see a '{' we push a new frame of type 364 | // MODE.BlockStatement on the the stack, even though it could be object literal. If we later 365 | // encounter a ":", we'll switch to to MODE.ObjectLiteral. If we then see a ";", 366 | // most full parsers would die, but the beautifier gracefully falls back to 367 | // MODE.BlockStatement and continues on. 368 | this._flag_store = []; 369 | this.set_mode(MODE.BlockStatement); 370 | var tokenizer = new Tokenizer(source_text, this._options); 371 | this._tokens = tokenizer.tokenize(); 372 | return source_text; 373 | }; 374 | 375 | Beautifier.prototype.beautify = function() { 376 | // if disabled, return the input unchanged. 377 | if (this._options.disabled) { 378 | return this._source_text; 379 | } 380 | 381 | var sweet_code; 382 | var source_text = this._reset(this._source_text); 383 | 384 | var eol = this._options.eol; 385 | if (this._options.eol === 'auto') { 386 | eol = '\n'; 387 | if (source_text && acorn.lineBreak.test(source_text || '')) { 388 | eol = source_text.match(acorn.lineBreak)[0]; 389 | } 390 | } 391 | 392 | var current_token = this._tokens.next(); 393 | while (current_token) { 394 | this.handle_token(current_token); 395 | 396 | this._last_last_text = this._flags.last_token.text; 397 | this._flags.last_token = current_token; 398 | 399 | current_token = this._tokens.next(); 400 | } 401 | 402 | sweet_code = this._output.get_code(eol); 403 | 404 | return sweet_code; 405 | }; 406 | 407 | Beautifier.prototype.handle_token = function(current_token, preserve_statement_flags) { 408 | if (current_token.type === TOKEN.START_EXPR) { 409 | this.handle_start_expr(current_token); 410 | } else if (current_token.type === TOKEN.END_EXPR) { 411 | this.handle_end_expr(current_token); 412 | } else if (current_token.type === TOKEN.START_BLOCK) { 413 | this.handle_start_block(current_token); 414 | } else if (current_token.type === TOKEN.END_BLOCK) { 415 | this.handle_end_block(current_token); 416 | } else if (current_token.type === TOKEN.WORD) { 417 | this.handle_word(current_token); 418 | } else if (current_token.type === TOKEN.RESERVED) { 419 | this.handle_word(current_token); 420 | } else if (current_token.type === TOKEN.SEMICOLON) { 421 | this.handle_semicolon(current_token); 422 | } else if (current_token.type === TOKEN.STRING) { 423 | this.handle_string(current_token); 424 | } else if (current_token.type === TOKEN.EQUALS) { 425 | this.handle_equals(current_token); 426 | } else if (current_token.type === TOKEN.OPERATOR) { 427 | this.handle_operator(current_token); 428 | } else if (current_token.type === TOKEN.COMMA) { 429 | this.handle_comma(current_token); 430 | } else if (current_token.type === TOKEN.BLOCK_COMMENT) { 431 | this.handle_block_comment(current_token, preserve_statement_flags); 432 | } else if (current_token.type === TOKEN.COMMENT) { 433 | this.handle_comment(current_token, preserve_statement_flags); 434 | } else if (current_token.type === TOKEN.DOT) { 435 | this.handle_dot(current_token); 436 | } else if (current_token.type === TOKEN.EOF) { 437 | this.handle_eof(current_token); 438 | } else if (current_token.type === TOKEN.UNKNOWN) { 439 | this.handle_unknown(current_token, preserve_statement_flags); 440 | } else { 441 | this.handle_unknown(current_token, preserve_statement_flags); 442 | } 443 | }; 444 | 445 | Beautifier.prototype.handle_whitespace_and_comments = function(current_token, preserve_statement_flags) { 446 | var newlines = current_token.newlines; 447 | var keep_whitespace = this._options.keep_array_indentation && is_array(this._flags.mode); 448 | 449 | if (current_token.comments_before) { 450 | var comment_token = current_token.comments_before.next(); 451 | while (comment_token) { 452 | // The cleanest handling of inline comments is to treat them as though they aren't there. 453 | // Just continue formatting and the behavior should be logical. 454 | // Also ignore unknown tokens. Again, this should result in better behavior. 455 | this.handle_whitespace_and_comments(comment_token, preserve_statement_flags); 456 | this.handle_token(comment_token, preserve_statement_flags); 457 | comment_token = current_token.comments_before.next(); 458 | } 459 | } 460 | 461 | if (keep_whitespace) { 462 | for (var i = 0; i < newlines; i += 1) { 463 | this.print_newline(i > 0, preserve_statement_flags); 464 | } 465 | } else { 466 | if (this._options.max_preserve_newlines && newlines > this._options.max_preserve_newlines) { 467 | newlines = this._options.max_preserve_newlines; 468 | } 469 | 470 | if (this._options.preserve_newlines) { 471 | if (newlines > 1) { 472 | this.print_newline(false, preserve_statement_flags); 473 | for (var j = 1; j < newlines; j += 1) { 474 | this.print_newline(true, preserve_statement_flags); 475 | } 476 | } 477 | } 478 | } 479 | 480 | }; 481 | 482 | var newline_restricted_tokens = ['async', 'break', 'continue', 'return', 'throw', 'yield']; 483 | 484 | Beautifier.prototype.allow_wrap_or_preserved_newline = function(current_token, force_linewrap) { 485 | force_linewrap = (force_linewrap === undefined) ? false : force_linewrap; 486 | 487 | // Never wrap the first token on a line 488 | if (this._output.just_added_newline()) { 489 | return; 490 | } 491 | 492 | var shouldPreserveOrForce = (this._options.preserve_newlines && current_token.newlines) || force_linewrap; 493 | var operatorLogicApplies = in_array(this._flags.last_token.text, positionable_operators) || 494 | in_array(current_token.text, positionable_operators); 495 | 496 | if (operatorLogicApplies) { 497 | var shouldPrintOperatorNewline = ( 498 | in_array(this._flags.last_token.text, positionable_operators) && 499 | in_array(this._options.operator_position, OPERATOR_POSITION_BEFORE_OR_PRESERVE) 500 | ) || 501 | in_array(current_token.text, positionable_operators); 502 | shouldPreserveOrForce = shouldPreserveOrForce && shouldPrintOperatorNewline; 503 | } 504 | 505 | if (shouldPreserveOrForce) { 506 | this.print_newline(false, true); 507 | } else if (this._options.wrap_line_length) { 508 | if (reserved_array(this._flags.last_token, newline_restricted_tokens)) { 509 | // These tokens should never have a newline inserted 510 | // between them and the following expression. 511 | return; 512 | } 513 | this._output.set_wrap_point(); 514 | } 515 | }; 516 | 517 | Beautifier.prototype.print_newline = function(force_newline, preserve_statement_flags) { 518 | if (!preserve_statement_flags) { 519 | if (this._flags.last_token.text !== ';' && this._flags.last_token.text !== ',' && this._flags.last_token.text !== '=' && (this._flags.last_token.type !== TOKEN.OPERATOR || this._flags.last_token.text === '--' || this._flags.last_token.text === '++')) { 520 | var next_token = this._tokens.peek(); 521 | while (this._flags.mode === MODE.Statement && 522 | !(this._flags.if_block && reserved_word(next_token, 'else')) && 523 | !this._flags.do_block) { 524 | this.restore_mode(); 525 | } 526 | } 527 | } 528 | 529 | if (this._output.add_new_line(force_newline)) { 530 | this._flags.multiline_frame = true; 531 | } 532 | }; 533 | 534 | Beautifier.prototype.print_token_line_indentation = function(current_token) { 535 | if (this._output.just_added_newline()) { 536 | if (this._options.keep_array_indentation && 537 | current_token.newlines && 538 | (current_token.text === '[' || is_array(this._flags.mode))) { 539 | this._output.current_line.set_indent(-1); 540 | this._output.current_line.push(current_token.whitespace_before); 541 | this._output.space_before_token = false; 542 | } else if (this._output.set_indent(this._flags.indentation_level, this._flags.alignment)) { 543 | this._flags.line_indent_level = this._flags.indentation_level; 544 | } 545 | } 546 | }; 547 | 548 | Beautifier.prototype.print_token = function(current_token) { 549 | if (this._output.raw) { 550 | this._output.add_raw_token(current_token); 551 | return; 552 | } 553 | 554 | if (this._options.comma_first && current_token.previous && current_token.previous.type === TOKEN.COMMA && 555 | this._output.just_added_newline()) { 556 | if (this._output.previous_line.last() === ',') { 557 | var popped = this._output.previous_line.pop(); 558 | // if the comma was already at the start of the line, 559 | // pull back onto that line and reprint the indentation 560 | if (this._output.previous_line.is_empty()) { 561 | this._output.previous_line.push(popped); 562 | this._output.trim(true); 563 | this._output.current_line.pop(); 564 | this._output.trim(); 565 | } 566 | 567 | // add the comma in front of the next token 568 | this.print_token_line_indentation(current_token); 569 | this._output.add_token(','); 570 | this._output.space_before_token = true; 571 | } 572 | } 573 | 574 | this.print_token_line_indentation(current_token); 575 | this._output.non_breaking_space = true; 576 | this._output.add_token(current_token.text); 577 | if (this._output.previous_token_wrapped) { 578 | this._flags.multiline_frame = true; 579 | } 580 | }; 581 | 582 | Beautifier.prototype.indent = function() { 583 | this._flags.indentation_level += 1; 584 | this._output.set_indent(this._flags.indentation_level, this._flags.alignment); 585 | }; 586 | 587 | Beautifier.prototype.deindent = function() { 588 | if (this._flags.indentation_level > 0 && 589 | ((!this._flags.parent) || this._flags.indentation_level > this._flags.parent.indentation_level)) { 590 | this._flags.indentation_level -= 1; 591 | this._output.set_indent(this._flags.indentation_level, this._flags.alignment); 592 | } 593 | }; 594 | 595 | Beautifier.prototype.set_mode = function(mode) { 596 | if (this._flags) { 597 | this._flag_store.push(this._flags); 598 | this._previous_flags = this._flags; 599 | } else { 600 | this._previous_flags = this.create_flags(null, mode); 601 | } 602 | 603 | this._flags = this.create_flags(this._previous_flags, mode); 604 | this._output.set_indent(this._flags.indentation_level, this._flags.alignment); 605 | }; 606 | 607 | 608 | Beautifier.prototype.restore_mode = function() { 609 | if (this._flag_store.length > 0) { 610 | this._previous_flags = this._flags; 611 | this._flags = this._flag_store.pop(); 612 | if (this._previous_flags.mode === MODE.Statement) { 613 | remove_redundant_indentation(this._output, this._previous_flags); 614 | } 615 | this._output.set_indent(this._flags.indentation_level, this._flags.alignment); 616 | } 617 | }; 618 | 619 | Beautifier.prototype.start_of_object_property = function() { 620 | return this._flags.parent.mode === MODE.ObjectLiteral && this._flags.mode === MODE.Statement && ( 621 | (this._flags.last_token.text === ':' && this._flags.ternary_depth === 0) || (reserved_array(this._flags.last_token, ['get', 'set']))); 622 | }; 623 | 624 | Beautifier.prototype.start_of_statement = function(current_token) { 625 | var start = false; 626 | start = start || reserved_array(this._flags.last_token, ['var', 'let', 'const']) && current_token.type === TOKEN.WORD; 627 | start = start || reserved_word(this._flags.last_token, 'do'); 628 | start = start || (!(this._flags.parent.mode === MODE.ObjectLiteral && this._flags.mode === MODE.Statement)) && reserved_array(this._flags.last_token, newline_restricted_tokens) && !current_token.newlines; 629 | start = start || reserved_word(this._flags.last_token, 'else') && 630 | !(reserved_word(current_token, 'if') && !current_token.comments_before); 631 | start = start || (this._flags.last_token.type === TOKEN.END_EXPR && (this._previous_flags.mode === MODE.ForInitializer || this._previous_flags.mode === MODE.Conditional)); 632 | start = start || (this._flags.last_token.type === TOKEN.WORD && this._flags.mode === MODE.BlockStatement && 633 | !this._flags.in_case && 634 | !(current_token.text === '--' || current_token.text === '++') && 635 | this._last_last_text !== 'function' && 636 | current_token.type !== TOKEN.WORD && current_token.type !== TOKEN.RESERVED); 637 | start = start || (this._flags.mode === MODE.ObjectLiteral && ( 638 | (this._flags.last_token.text === ':' && this._flags.ternary_depth === 0) || reserved_array(this._flags.last_token, ['get', 'set']))); 639 | 640 | if (start) { 641 | this.set_mode(MODE.Statement); 642 | this.indent(); 643 | 644 | this.handle_whitespace_and_comments(current_token, true); 645 | 646 | // Issue #276: 647 | // If starting a new statement with [if, for, while, do], push to a new line. 648 | // if (a) if (b) if(c) d(); else e(); else f(); 649 | if (!this.start_of_object_property()) { 650 | this.allow_wrap_or_preserved_newline(current_token, 651 | reserved_array(current_token, ['do', 'for', 'if', 'while'])); 652 | } 653 | return true; 654 | } 655 | return false; 656 | }; 657 | 658 | Beautifier.prototype.handle_start_expr = function(current_token) { 659 | // The conditional starts the statement if appropriate. 660 | if (!this.start_of_statement(current_token)) { 661 | this.handle_whitespace_and_comments(current_token); 662 | } 663 | 664 | var next_mode = MODE.Expression; 665 | if (current_token.text === '[') { 666 | 667 | if (this._flags.last_token.type === TOKEN.WORD || this._flags.last_token.text === ')') { 668 | // this is array index specifier, break immediately 669 | // a[x], fn()[x] 670 | if (reserved_array(this._flags.last_token, line_starters)) { 671 | this._output.space_before_token = true; 672 | } 673 | this.print_token(current_token); 674 | this.set_mode(next_mode); 675 | this.indent(); 676 | if (this._options.space_in_paren) { 677 | this._output.space_before_token = true; 678 | } 679 | return; 680 | } 681 | 682 | next_mode = MODE.ArrayLiteral; 683 | if (is_array(this._flags.mode)) { 684 | if (this._flags.last_token.text === '[' || 685 | (this._flags.last_token.text === ',' && (this._last_last_text === ']' || this._last_last_text === '}'))) { 686 | // ], [ goes to new line 687 | // }, [ goes to new line 688 | if (!this._options.keep_array_indentation) { 689 | this.print_newline(); 690 | } 691 | } 692 | } 693 | 694 | if (!in_array(this._flags.last_token.type, [TOKEN.START_EXPR, TOKEN.END_EXPR, TOKEN.WORD, TOKEN.OPERATOR, TOKEN.DOT])) { 695 | this._output.space_before_token = true; 696 | } 697 | } else { 698 | if (this._flags.last_token.type === TOKEN.RESERVED) { 699 | if (this._flags.last_token.text === 'for') { 700 | this._output.space_before_token = this._options.space_before_conditional; 701 | next_mode = MODE.ForInitializer; 702 | } else if (in_array(this._flags.last_token.text, ['if', 'while', 'switch'])) { 703 | this._output.space_before_token = this._options.space_before_conditional; 704 | next_mode = MODE.Conditional; 705 | } else if (in_array(this._flags.last_word, ['await', 'async'])) { 706 | // Should be a space between await and an IIFE, or async and an arrow function 707 | this._output.space_before_token = true; 708 | } else if (this._flags.last_token.text === 'import' && current_token.whitespace_before === '') { 709 | this._output.space_before_token = false; 710 | } else if (in_array(this._flags.last_token.text, line_starters) || this._flags.last_token.text === 'catch') { 711 | this._output.space_before_token = true; 712 | } 713 | } else if (this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) { 714 | // Support of this kind of newline preservation. 715 | // a = (b && 716 | // (c || d)); 717 | if (!this.start_of_object_property()) { 718 | this.allow_wrap_or_preserved_newline(current_token); 719 | } 720 | } else if (this._flags.last_token.type === TOKEN.WORD) { 721 | this._output.space_before_token = false; 722 | 723 | // function name() vs function name () 724 | // function* name() vs function* name () 725 | // async name() vs async name () 726 | // In ES6, you can also define the method properties of an object 727 | // var obj = {a: function() {}} 728 | // It can be abbreviated 729 | // var obj = {a() {}} 730 | // var obj = { a() {}} vs var obj = { a () {}} 731 | // var obj = { * a() {}} vs var obj = { * a () {}} 732 | var peek_back_two = this._tokens.peek(-3); 733 | if (this._options.space_after_named_function && peek_back_two) { 734 | // peek starts at next character so -1 is current token 735 | var peek_back_three = this._tokens.peek(-4); 736 | if (reserved_array(peek_back_two, ['async', 'function']) || 737 | (peek_back_two.text === '*' && reserved_array(peek_back_three, ['async', 'function']))) { 738 | this._output.space_before_token = true; 739 | } else if (this._flags.mode === MODE.ObjectLiteral) { 740 | if ((peek_back_two.text === '{' || peek_back_two.text === ',') || 741 | (peek_back_two.text === '*' && (peek_back_three.text === '{' || peek_back_three.text === ','))) { 742 | this._output.space_before_token = true; 743 | } 744 | } 745 | } 746 | } else { 747 | // Support preserving wrapped arrow function expressions 748 | // a.b('c', 749 | // () => d.e 750 | // ) 751 | this.allow_wrap_or_preserved_newline(current_token); 752 | } 753 | 754 | // function() vs function () 755 | // yield*() vs yield* () 756 | // function*() vs function* () 757 | if ((this._flags.last_token.type === TOKEN.RESERVED && (this._flags.last_word === 'function' || this._flags.last_word === 'typeof')) || 758 | (this._flags.last_token.text === '*' && 759 | (in_array(this._last_last_text, ['function', 'yield']) || 760 | (this._flags.mode === MODE.ObjectLiteral && in_array(this._last_last_text, ['{', ',']))))) { 761 | this._output.space_before_token = this._options.space_after_anon_function; 762 | } 763 | } 764 | 765 | if (this._flags.last_token.text === ';' || this._flags.last_token.type === TOKEN.START_BLOCK) { 766 | this.print_newline(); 767 | } else if (this._flags.last_token.type === TOKEN.END_EXPR || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.END_BLOCK || this._flags.last_token.text === '.' || this._flags.last_token.type === TOKEN.COMMA) { 768 | // do nothing on (( and )( and ][ and ]( and .( 769 | // TODO: Consider whether forcing this is required. Review failing tests when removed. 770 | this.allow_wrap_or_preserved_newline(current_token, current_token.newlines); 771 | } 772 | 773 | this.print_token(current_token); 774 | this.set_mode(next_mode); 775 | if (this._options.space_in_paren) { 776 | this._output.space_before_token = true; 777 | } 778 | 779 | // In all cases, if we newline while inside an expression it should be indented. 780 | this.indent(); 781 | }; 782 | 783 | Beautifier.prototype.handle_end_expr = function(current_token) { 784 | // statements inside expressions are not valid syntax, but... 785 | // statements must all be closed when their container closes 786 | while (this._flags.mode === MODE.Statement) { 787 | this.restore_mode(); 788 | } 789 | 790 | this.handle_whitespace_and_comments(current_token); 791 | 792 | if (this._flags.multiline_frame) { 793 | this.allow_wrap_or_preserved_newline(current_token, 794 | current_token.text === ']' && is_array(this._flags.mode) && !this._options.keep_array_indentation); 795 | } 796 | 797 | if (this._options.space_in_paren) { 798 | if (this._flags.last_token.type === TOKEN.START_EXPR && !this._options.space_in_empty_paren) { 799 | // () [] no inner space in empty parens like these, ever, ref #320 800 | this._output.trim(); 801 | this._output.space_before_token = false; 802 | } else { 803 | this._output.space_before_token = true; 804 | } 805 | } 806 | this.deindent(); 807 | this.print_token(current_token); 808 | this.restore_mode(); 809 | 810 | remove_redundant_indentation(this._output, this._previous_flags); 811 | 812 | // do {} while () // no statement required after 813 | if (this._flags.do_while && this._previous_flags.mode === MODE.Conditional) { 814 | this._previous_flags.mode = MODE.Expression; 815 | this._flags.do_block = false; 816 | this._flags.do_while = false; 817 | 818 | } 819 | }; 820 | 821 | Beautifier.prototype.handle_start_block = function(current_token) { 822 | this.handle_whitespace_and_comments(current_token); 823 | 824 | // Check if this is should be treated as a ObjectLiteral 825 | var next_token = this._tokens.peek(); 826 | var second_token = this._tokens.peek(1); 827 | if (this._flags.last_word === 'switch' && this._flags.last_token.type === TOKEN.END_EXPR) { 828 | this.set_mode(MODE.BlockStatement); 829 | this._flags.in_case_statement = true; 830 | } else if (this._flags.case_body) { 831 | this.set_mode(MODE.BlockStatement); 832 | } else if (second_token && ( 833 | (in_array(second_token.text, [':', ',']) && in_array(next_token.type, [TOKEN.STRING, TOKEN.WORD, TOKEN.RESERVED])) || 834 | (in_array(next_token.text, ['get', 'set', '...']) && in_array(second_token.type, [TOKEN.WORD, TOKEN.RESERVED])) 835 | )) { 836 | // We don't support TypeScript,but we didn't break it for a very long time. 837 | // We'll try to keep not breaking it. 838 | if (!in_array(this._last_last_text, ['class', 'interface'])) { 839 | this.set_mode(MODE.ObjectLiteral); 840 | } else { 841 | this.set_mode(MODE.BlockStatement); 842 | } 843 | } else if (this._flags.last_token.type === TOKEN.OPERATOR && this._flags.last_token.text === '=>') { 844 | // arrow function: (param1, paramN) => { statements } 845 | this.set_mode(MODE.BlockStatement); 846 | } else if (in_array(this._flags.last_token.type, [TOKEN.EQUALS, TOKEN.START_EXPR, TOKEN.COMMA, TOKEN.OPERATOR]) || 847 | reserved_array(this._flags.last_token, ['return', 'throw', 'import', 'default']) 848 | ) { 849 | // Detecting shorthand function syntax is difficult by scanning forward, 850 | // so check the surrounding context. 851 | // If the block is being returned, imported, export default, passed as arg, 852 | // assigned with = or assigned in a nested object, treat as an ObjectLiteral. 853 | this.set_mode(MODE.ObjectLiteral); 854 | } else { 855 | this.set_mode(MODE.BlockStatement); 856 | } 857 | 858 | var empty_braces = !next_token.comments_before && next_token.text === '}'; 859 | var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' && 860 | this._flags.last_token.type === TOKEN.END_EXPR; 861 | 862 | if (this._options.brace_preserve_inline) // check for inline, set inline_frame if so 863 | { 864 | // search forward for a newline wanted inside this block 865 | var index = 0; 866 | var check_token = null; 867 | this._flags.inline_frame = true; 868 | do { 869 | index += 1; 870 | check_token = this._tokens.peek(index - 1); 871 | if (check_token.newlines) { 872 | this._flags.inline_frame = false; 873 | break; 874 | } 875 | } while (check_token.type !== TOKEN.EOF && 876 | !(check_token.type === TOKEN.END_BLOCK && check_token.opened === current_token)); 877 | } 878 | 879 | if ((this._options.brace_style === "expand" || 880 | (this._options.brace_style === "none" && current_token.newlines)) && 881 | !this._flags.inline_frame) { 882 | if (this._flags.last_token.type !== TOKEN.OPERATOR && 883 | (empty_anonymous_function || 884 | this._flags.last_token.type === TOKEN.EQUALS || 885 | (reserved_array(this._flags.last_token, special_words) && this._flags.last_token.text !== 'else'))) { 886 | this._output.space_before_token = true; 887 | } else { 888 | this.print_newline(false, true); 889 | } 890 | } else { // collapse || inline_frame 891 | if (is_array(this._previous_flags.mode) && (this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.COMMA)) { 892 | if (this._flags.last_token.type === TOKEN.COMMA || this._options.space_in_paren) { 893 | this._output.space_before_token = true; 894 | } 895 | 896 | if (this._flags.last_token.type === TOKEN.COMMA || (this._flags.last_token.type === TOKEN.START_EXPR && this._flags.inline_frame)) { 897 | this.allow_wrap_or_preserved_newline(current_token); 898 | this._previous_flags.multiline_frame = this._previous_flags.multiline_frame || this._flags.multiline_frame; 899 | this._flags.multiline_frame = false; 900 | } 901 | } 902 | if (this._flags.last_token.type !== TOKEN.OPERATOR && this._flags.last_token.type !== TOKEN.START_EXPR) { 903 | if (this._flags.last_token.type === TOKEN.START_BLOCK && !this._flags.inline_frame) { 904 | this.print_newline(); 905 | } else { 906 | this._output.space_before_token = true; 907 | } 908 | } 909 | } 910 | this.print_token(current_token); 911 | this.indent(); 912 | 913 | // Except for specific cases, open braces are followed by a new line. 914 | if (!empty_braces && !(this._options.brace_preserve_inline && this._flags.inline_frame)) { 915 | this.print_newline(); 916 | } 917 | }; 918 | 919 | Beautifier.prototype.handle_end_block = function(current_token) { 920 | // statements must all be closed when their container closes 921 | this.handle_whitespace_and_comments(current_token); 922 | 923 | while (this._flags.mode === MODE.Statement) { 924 | this.restore_mode(); 925 | } 926 | 927 | var empty_braces = this._flags.last_token.type === TOKEN.START_BLOCK; 928 | 929 | if (this._flags.inline_frame && !empty_braces) { // try inline_frame (only set if this._options.braces-preserve-inline) first 930 | this._output.space_before_token = true; 931 | } else if (this._options.brace_style === "expand") { 932 | if (!empty_braces) { 933 | this.print_newline(); 934 | } 935 | } else { 936 | // skip {} 937 | if (!empty_braces) { 938 | if (is_array(this._flags.mode) && this._options.keep_array_indentation) { 939 | // we REALLY need a newline here, but newliner would skip that 940 | this._options.keep_array_indentation = false; 941 | this.print_newline(); 942 | this._options.keep_array_indentation = true; 943 | 944 | } else { 945 | this.print_newline(); 946 | } 947 | } 948 | } 949 | this.restore_mode(); 950 | this.print_token(current_token); 951 | }; 952 | 953 | Beautifier.prototype.handle_word = function(current_token) { 954 | if (current_token.type === TOKEN.RESERVED) { 955 | if (in_array(current_token.text, ['set', 'get']) && this._flags.mode !== MODE.ObjectLiteral) { 956 | current_token.type = TOKEN.WORD; 957 | } else if (current_token.text === 'import' && this._tokens.peek().text === '(') { 958 | current_token.type = TOKEN.WORD; 959 | } else if (in_array(current_token.text, ['as', 'from']) && !this._flags.import_block) { 960 | current_token.type = TOKEN.WORD; 961 | } else if (this._flags.mode === MODE.ObjectLiteral) { 962 | var next_token = this._tokens.peek(); 963 | if (next_token.text === ':') { 964 | current_token.type = TOKEN.WORD; 965 | } 966 | } 967 | } 968 | 969 | if (this.start_of_statement(current_token)) { 970 | // The conditional starts the statement if appropriate. 971 | if (reserved_array(this._flags.last_token, ['var', 'let', 'const']) && current_token.type === TOKEN.WORD) { 972 | this._flags.declaration_statement = true; 973 | } 974 | } else if (current_token.newlines && !is_expression(this._flags.mode) && 975 | (this._flags.last_token.type !== TOKEN.OPERATOR || (this._flags.last_token.text === '--' || this._flags.last_token.text === '++')) && 976 | this._flags.last_token.type !== TOKEN.EQUALS && 977 | (this._options.preserve_newlines || !reserved_array(this._flags.last_token, ['var', 'let', 'const', 'set', 'get']))) { 978 | this.handle_whitespace_and_comments(current_token); 979 | this.print_newline(); 980 | } else { 981 | this.handle_whitespace_and_comments(current_token); 982 | } 983 | 984 | if (this._flags.do_block && !this._flags.do_while) { 985 | if (reserved_word(current_token, 'while')) { 986 | // do {} ## while () 987 | this._output.space_before_token = true; 988 | this.print_token(current_token); 989 | this._output.space_before_token = true; 990 | this._flags.do_while = true; 991 | return; 992 | } else { 993 | // do {} should always have while as the next word. 994 | // if we don't see the expected while, recover 995 | this.print_newline(); 996 | this._flags.do_block = false; 997 | } 998 | } 999 | 1000 | // if may be followed by else, or not 1001 | // Bare/inline ifs are tricky 1002 | // Need to unwind the modes correctly: if (a) if (b) c(); else d(); else e(); 1003 | if (this._flags.if_block) { 1004 | if (!this._flags.else_block && reserved_word(current_token, 'else')) { 1005 | this._flags.else_block = true; 1006 | } else { 1007 | while (this._flags.mode === MODE.Statement) { 1008 | this.restore_mode(); 1009 | } 1010 | this._flags.if_block = false; 1011 | this._flags.else_block = false; 1012 | } 1013 | } 1014 | 1015 | if (this._flags.in_case_statement && reserved_array(current_token, ['case', 'default'])) { 1016 | this.print_newline(); 1017 | if (this._flags.last_token.type !== TOKEN.END_BLOCK && (this._flags.case_body || this._options.jslint_happy)) { 1018 | // switch cases following one another 1019 | this.deindent(); 1020 | } 1021 | this._flags.case_body = false; 1022 | 1023 | this.print_token(current_token); 1024 | this._flags.in_case = true; 1025 | return; 1026 | } 1027 | 1028 | if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) { 1029 | if (!this.start_of_object_property()) { 1030 | this.allow_wrap_or_preserved_newline(current_token); 1031 | } 1032 | } 1033 | 1034 | if (reserved_word(current_token, 'function')) { 1035 | if (in_array(this._flags.last_token.text, ['}', ';']) || 1036 | (this._output.just_added_newline() && !(in_array(this._flags.last_token.text, ['(', '[', '{', ':', '=', ',']) || this._flags.last_token.type === TOKEN.OPERATOR))) { 1037 | // make sure there is a nice clean space of at least one blank line 1038 | // before a new function definition 1039 | if (!this._output.just_added_blankline() && !current_token.comments_before) { 1040 | this.print_newline(); 1041 | this.print_newline(true); 1042 | } 1043 | } 1044 | if (this._flags.last_token.type === TOKEN.RESERVED || this._flags.last_token.type === TOKEN.WORD) { 1045 | if (reserved_array(this._flags.last_token, ['get', 'set', 'new', 'export']) || 1046 | reserved_array(this._flags.last_token, newline_restricted_tokens)) { 1047 | this._output.space_before_token = true; 1048 | } else if (reserved_word(this._flags.last_token, 'default') && this._last_last_text === 'export') { 1049 | this._output.space_before_token = true; 1050 | } else if (this._flags.last_token.text === 'declare') { 1051 | // accomodates Typescript declare function formatting 1052 | this._output.space_before_token = true; 1053 | } else { 1054 | this.print_newline(); 1055 | } 1056 | } else if (this._flags.last_token.type === TOKEN.OPERATOR || this._flags.last_token.text === '=') { 1057 | // foo = function 1058 | this._output.space_before_token = true; 1059 | } else if (!this._flags.multiline_frame && (is_expression(this._flags.mode) || is_array(this._flags.mode))) { 1060 | // (function 1061 | } else { 1062 | this.print_newline(); 1063 | } 1064 | 1065 | this.print_token(current_token); 1066 | this._flags.last_word = current_token.text; 1067 | return; 1068 | } 1069 | 1070 | var prefix = 'NONE'; 1071 | 1072 | if (this._flags.last_token.type === TOKEN.END_BLOCK) { 1073 | 1074 | if (this._previous_flags.inline_frame) { 1075 | prefix = 'SPACE'; 1076 | } else if (!reserved_array(current_token, ['else', 'catch', 'finally', 'from'])) { 1077 | prefix = 'NEWLINE'; 1078 | } else { 1079 | if (this._options.brace_style === "expand" || 1080 | this._options.brace_style === "end-expand" || 1081 | (this._options.brace_style === "none" && current_token.newlines)) { 1082 | prefix = 'NEWLINE'; 1083 | } else { 1084 | prefix = 'SPACE'; 1085 | this._output.space_before_token = true; 1086 | } 1087 | } 1088 | } else if (this._flags.last_token.type === TOKEN.SEMICOLON && this._flags.mode === MODE.BlockStatement) { 1089 | // TODO: Should this be for STATEMENT as well? 1090 | prefix = 'NEWLINE'; 1091 | } else if (this._flags.last_token.type === TOKEN.SEMICOLON && is_expression(this._flags.mode)) { 1092 | prefix = 'SPACE'; 1093 | } else if (this._flags.last_token.type === TOKEN.STRING) { 1094 | prefix = 'NEWLINE'; 1095 | } else if (this._flags.last_token.type === TOKEN.RESERVED || this._flags.last_token.type === TOKEN.WORD || 1096 | (this._flags.last_token.text === '*' && 1097 | (in_array(this._last_last_text, ['function', 'yield']) || 1098 | (this._flags.mode === MODE.ObjectLiteral && in_array(this._last_last_text, ['{', ',']))))) { 1099 | prefix = 'SPACE'; 1100 | } else if (this._flags.last_token.type === TOKEN.START_BLOCK) { 1101 | if (this._flags.inline_frame) { 1102 | prefix = 'SPACE'; 1103 | } else { 1104 | prefix = 'NEWLINE'; 1105 | } 1106 | } else if (this._flags.last_token.type === TOKEN.END_EXPR) { 1107 | this._output.space_before_token = true; 1108 | prefix = 'NEWLINE'; 1109 | } 1110 | 1111 | if (reserved_array(current_token, line_starters) && this._flags.last_token.text !== ')') { 1112 | if (this._flags.inline_frame || this._flags.last_token.text === 'else' || this._flags.last_token.text === 'export') { 1113 | prefix = 'SPACE'; 1114 | } else { 1115 | prefix = 'NEWLINE'; 1116 | } 1117 | 1118 | } 1119 | 1120 | if (reserved_array(current_token, ['else', 'catch', 'finally'])) { 1121 | if ((!(this._flags.last_token.type === TOKEN.END_BLOCK && this._previous_flags.mode === MODE.BlockStatement) || 1122 | this._options.brace_style === "expand" || 1123 | this._options.brace_style === "end-expand" || 1124 | (this._options.brace_style === "none" && current_token.newlines)) && 1125 | !this._flags.inline_frame) { 1126 | this.print_newline(); 1127 | } else { 1128 | this._output.trim(true); 1129 | var line = this._output.current_line; 1130 | // If we trimmed and there's something other than a close block before us 1131 | // put a newline back in. Handles '} // comment' scenario. 1132 | if (line.last() !== '}') { 1133 | this.print_newline(); 1134 | } 1135 | this._output.space_before_token = true; 1136 | } 1137 | } else if (prefix === 'NEWLINE') { 1138 | if (reserved_array(this._flags.last_token, special_words)) { 1139 | // no newline between 'return nnn' 1140 | this._output.space_before_token = true; 1141 | } else if (this._flags.last_token.text === 'declare' && reserved_array(current_token, ['var', 'let', 'const'])) { 1142 | // accomodates Typescript declare formatting 1143 | this._output.space_before_token = true; 1144 | } else if (this._flags.last_token.type !== TOKEN.END_EXPR) { 1145 | if ((this._flags.last_token.type !== TOKEN.START_EXPR || !reserved_array(current_token, ['var', 'let', 'const'])) && this._flags.last_token.text !== ':') { 1146 | // no need to force newline on 'var': for (var x = 0...) 1147 | if (reserved_word(current_token, 'if') && reserved_word(current_token.previous, 'else')) { 1148 | // no newline for } else if { 1149 | this._output.space_before_token = true; 1150 | } else { 1151 | this.print_newline(); 1152 | } 1153 | } 1154 | } else if (reserved_array(current_token, line_starters) && this._flags.last_token.text !== ')') { 1155 | this.print_newline(); 1156 | } 1157 | } else if (this._flags.multiline_frame && is_array(this._flags.mode) && this._flags.last_token.text === ',' && this._last_last_text === '}') { 1158 | this.print_newline(); // }, in lists get a newline treatment 1159 | } else if (prefix === 'SPACE') { 1160 | this._output.space_before_token = true; 1161 | } 1162 | if (current_token.previous && (current_token.previous.type === TOKEN.WORD || current_token.previous.type === TOKEN.RESERVED)) { 1163 | this._output.space_before_token = true; 1164 | } 1165 | this.print_token(current_token); 1166 | this._flags.last_word = current_token.text; 1167 | 1168 | if (current_token.type === TOKEN.RESERVED) { 1169 | if (current_token.text === 'do') { 1170 | this._flags.do_block = true; 1171 | } else if (current_token.text === 'if') { 1172 | this._flags.if_block = true; 1173 | } else if (current_token.text === 'import') { 1174 | this._flags.import_block = true; 1175 | } else if (this._flags.import_block && reserved_word(current_token, 'from')) { 1176 | this._flags.import_block = false; 1177 | } 1178 | } 1179 | }; 1180 | 1181 | Beautifier.prototype.handle_semicolon = function(current_token) { 1182 | if (this.start_of_statement(current_token)) { 1183 | // The conditional starts the statement if appropriate. 1184 | // Semicolon can be the start (and end) of a statement 1185 | this._output.space_before_token = false; 1186 | } else { 1187 | this.handle_whitespace_and_comments(current_token); 1188 | } 1189 | 1190 | var next_token = this._tokens.peek(); 1191 | while (this._flags.mode === MODE.Statement && 1192 | !(this._flags.if_block && reserved_word(next_token, 'else')) && 1193 | !this._flags.do_block) { 1194 | this.restore_mode(); 1195 | } 1196 | 1197 | // hacky but effective for the moment 1198 | if (this._flags.import_block) { 1199 | this._flags.import_block = false; 1200 | } 1201 | this.print_token(current_token); 1202 | }; 1203 | 1204 | Beautifier.prototype.handle_string = function(current_token) { 1205 | if (current_token.text.startsWith("`") && current_token.newlines === 0 && current_token.whitespace_before === '' && (current_token.previous.text === ')' || this._flags.last_token.type === TOKEN.WORD)) { 1206 | //Conditional for detectign backtick strings 1207 | } else if (this.start_of_statement(current_token)) { 1208 | // The conditional starts the statement if appropriate. 1209 | // One difference - strings want at least a space before 1210 | this._output.space_before_token = true; 1211 | } else { 1212 | this.handle_whitespace_and_comments(current_token); 1213 | if (this._flags.last_token.type === TOKEN.RESERVED || this._flags.last_token.type === TOKEN.WORD || this._flags.inline_frame) { 1214 | this._output.space_before_token = true; 1215 | } else if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) { 1216 | if (!this.start_of_object_property()) { 1217 | this.allow_wrap_or_preserved_newline(current_token); 1218 | } 1219 | } else if ((current_token.text.startsWith("`") && this._flags.last_token.type === TOKEN.END_EXPR && (current_token.previous.text === ']' || current_token.previous.text === ')') && current_token.newlines === 0)) { 1220 | this._output.space_before_token = true; 1221 | } else { 1222 | this.print_newline(); 1223 | } 1224 | } 1225 | this.print_token(current_token); 1226 | }; 1227 | 1228 | Beautifier.prototype.handle_equals = function(current_token) { 1229 | if (this.start_of_statement(current_token)) { 1230 | // The conditional starts the statement if appropriate. 1231 | } else { 1232 | this.handle_whitespace_and_comments(current_token); 1233 | } 1234 | 1235 | if (this._flags.declaration_statement) { 1236 | // just got an '=' in a var-line, different formatting/line-breaking, etc will now be done 1237 | this._flags.declaration_assignment = true; 1238 | } 1239 | this._output.space_before_token = true; 1240 | this.print_token(current_token); 1241 | this._output.space_before_token = true; 1242 | }; 1243 | 1244 | Beautifier.prototype.handle_comma = function(current_token) { 1245 | this.handle_whitespace_and_comments(current_token, true); 1246 | 1247 | this.print_token(current_token); 1248 | this._output.space_before_token = true; 1249 | if (this._flags.declaration_statement) { 1250 | if (is_expression(this._flags.parent.mode)) { 1251 | // do not break on comma, for(var a = 1, b = 2) 1252 | this._flags.declaration_assignment = false; 1253 | } 1254 | 1255 | if (this._flags.declaration_assignment) { 1256 | this._flags.declaration_assignment = false; 1257 | this.print_newline(false, true); 1258 | } else if (this._options.comma_first) { 1259 | // for comma-first, we want to allow a newline before the comma 1260 | // to turn into a newline after the comma, which we will fixup later 1261 | this.allow_wrap_or_preserved_newline(current_token); 1262 | } 1263 | } else if (this._flags.mode === MODE.ObjectLiteral || 1264 | (this._flags.mode === MODE.Statement && this._flags.parent.mode === MODE.ObjectLiteral)) { 1265 | if (this._flags.mode === MODE.Statement) { 1266 | this.restore_mode(); 1267 | } 1268 | 1269 | if (!this._flags.inline_frame) { 1270 | this.print_newline(); 1271 | } 1272 | } else if (this._options.comma_first) { 1273 | // EXPR or DO_BLOCK 1274 | // for comma-first, we want to allow a newline before the comma 1275 | // to turn into a newline after the comma, which we will fixup later 1276 | this.allow_wrap_or_preserved_newline(current_token); 1277 | } 1278 | }; 1279 | 1280 | Beautifier.prototype.handle_operator = function(current_token) { 1281 | var isGeneratorAsterisk = current_token.text === '*' && 1282 | (reserved_array(this._flags.last_token, ['function', 'yield']) || 1283 | (in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.COMMA, TOKEN.END_BLOCK, TOKEN.SEMICOLON])) 1284 | ); 1285 | var isUnary = in_array(current_token.text, ['-', '+']) && ( 1286 | in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.START_EXPR, TOKEN.EQUALS, TOKEN.OPERATOR]) || 1287 | in_array(this._flags.last_token.text, line_starters) || 1288 | this._flags.last_token.text === ',' 1289 | ); 1290 | 1291 | if (this.start_of_statement(current_token)) { 1292 | // The conditional starts the statement if appropriate. 1293 | } else { 1294 | var preserve_statement_flags = !isGeneratorAsterisk; 1295 | this.handle_whitespace_and_comments(current_token, preserve_statement_flags); 1296 | } 1297 | 1298 | if (reserved_array(this._flags.last_token, special_words)) { 1299 | // "return" had a special handling in TK_WORD. Now we need to return the favor 1300 | this._output.space_before_token = true; 1301 | this.print_token(current_token); 1302 | return; 1303 | } 1304 | 1305 | // hack for actionscript's import .*; 1306 | if (current_token.text === '*' && this._flags.last_token.type === TOKEN.DOT) { 1307 | this.print_token(current_token); 1308 | return; 1309 | } 1310 | 1311 | if (current_token.text === '::') { 1312 | // no spaces around exotic namespacing syntax operator 1313 | this.print_token(current_token); 1314 | return; 1315 | } 1316 | 1317 | // Allow line wrapping between operators when operator_position is 1318 | // set to before or preserve 1319 | if (this._flags.last_token.type === TOKEN.OPERATOR && in_array(this._options.operator_position, OPERATOR_POSITION_BEFORE_OR_PRESERVE)) { 1320 | this.allow_wrap_or_preserved_newline(current_token); 1321 | } 1322 | 1323 | if (current_token.text === ':' && this._flags.in_case) { 1324 | this.print_token(current_token); 1325 | 1326 | this._flags.in_case = false; 1327 | this._flags.case_body = true; 1328 | if (this._tokens.peek().type !== TOKEN.START_BLOCK) { 1329 | this.indent(); 1330 | this.print_newline(); 1331 | } else { 1332 | this._output.space_before_token = true; 1333 | } 1334 | return; 1335 | } 1336 | 1337 | var space_before = true; 1338 | var space_after = true; 1339 | var in_ternary = false; 1340 | if (current_token.text === ':') { 1341 | if (this._flags.ternary_depth === 0) { 1342 | // Colon is invalid javascript outside of ternary and object, but do our best to guess what was meant. 1343 | space_before = false; 1344 | } else { 1345 | this._flags.ternary_depth -= 1; 1346 | in_ternary = true; 1347 | } 1348 | } else if (current_token.text === '?') { 1349 | this._flags.ternary_depth += 1; 1350 | } 1351 | 1352 | // let's handle the operator_position option prior to any conflicting logic 1353 | if (!isUnary && !isGeneratorAsterisk && this._options.preserve_newlines && in_array(current_token.text, positionable_operators)) { 1354 | var isColon = current_token.text === ':'; 1355 | var isTernaryColon = (isColon && in_ternary); 1356 | var isOtherColon = (isColon && !in_ternary); 1357 | 1358 | switch (this._options.operator_position) { 1359 | case OPERATOR_POSITION.before_newline: 1360 | // if the current token is : and it's not a ternary statement then we set space_before to false 1361 | this._output.space_before_token = !isOtherColon; 1362 | 1363 | this.print_token(current_token); 1364 | 1365 | if (!isColon || isTernaryColon) { 1366 | this.allow_wrap_or_preserved_newline(current_token); 1367 | } 1368 | 1369 | this._output.space_before_token = true; 1370 | return; 1371 | 1372 | case OPERATOR_POSITION.after_newline: 1373 | // if the current token is anything but colon, or (via deduction) it's a colon and in a ternary statement, 1374 | // then print a newline. 1375 | 1376 | this._output.space_before_token = true; 1377 | 1378 | if (!isColon || isTernaryColon) { 1379 | if (this._tokens.peek().newlines) { 1380 | this.print_newline(false, true); 1381 | } else { 1382 | this.allow_wrap_or_preserved_newline(current_token); 1383 | } 1384 | } else { 1385 | this._output.space_before_token = false; 1386 | } 1387 | 1388 | this.print_token(current_token); 1389 | 1390 | this._output.space_before_token = true; 1391 | return; 1392 | 1393 | case OPERATOR_POSITION.preserve_newline: 1394 | if (!isOtherColon) { 1395 | this.allow_wrap_or_preserved_newline(current_token); 1396 | } 1397 | 1398 | // if we just added a newline, or the current token is : and it's not a ternary statement, 1399 | // then we set space_before to false 1400 | space_before = !(this._output.just_added_newline() || isOtherColon); 1401 | 1402 | this._output.space_before_token = space_before; 1403 | this.print_token(current_token); 1404 | this._output.space_before_token = true; 1405 | return; 1406 | } 1407 | } 1408 | 1409 | if (isGeneratorAsterisk) { 1410 | this.allow_wrap_or_preserved_newline(current_token); 1411 | space_before = false; 1412 | var next_token = this._tokens.peek(); 1413 | space_after = next_token && in_array(next_token.type, [TOKEN.WORD, TOKEN.RESERVED]); 1414 | } else if (current_token.text === '...') { 1415 | this.allow_wrap_or_preserved_newline(current_token); 1416 | space_before = this._flags.last_token.type === TOKEN.START_BLOCK; 1417 | space_after = false; 1418 | } else if (in_array(current_token.text, ['--', '++', '!', '~']) || isUnary) { 1419 | // unary operators (and binary +/- pretending to be unary) special cases 1420 | if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR) { 1421 | this.allow_wrap_or_preserved_newline(current_token); 1422 | } 1423 | 1424 | space_before = false; 1425 | space_after = false; 1426 | 1427 | // http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1 1428 | // if there is a newline between -- or ++ and anything else we should preserve it. 1429 | if (current_token.newlines && (current_token.text === '--' || current_token.text === '++')) { 1430 | this.print_newline(false, true); 1431 | } 1432 | 1433 | if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) { 1434 | // for (;; ++i) 1435 | // ^^^ 1436 | space_before = true; 1437 | } 1438 | 1439 | if (this._flags.last_token.type === TOKEN.RESERVED) { 1440 | space_before = true; 1441 | } else if (this._flags.last_token.type === TOKEN.END_EXPR) { 1442 | space_before = !(this._flags.last_token.text === ']' && (current_token.text === '--' || current_token.text === '++')); 1443 | } else if (this._flags.last_token.type === TOKEN.OPERATOR) { 1444 | // a++ + ++b; 1445 | // a - -b 1446 | space_before = in_array(current_token.text, ['--', '-', '++', '+']) && in_array(this._flags.last_token.text, ['--', '-', '++', '+']); 1447 | // + and - are not unary when preceeded by -- or ++ operator 1448 | // a-- + b 1449 | // a * +b 1450 | // a - -b 1451 | if (in_array(current_token.text, ['+', '-']) && in_array(this._flags.last_token.text, ['--', '++'])) { 1452 | space_after = true; 1453 | } 1454 | } 1455 | 1456 | 1457 | if (((this._flags.mode === MODE.BlockStatement && !this._flags.inline_frame) || this._flags.mode === MODE.Statement) && 1458 | (this._flags.last_token.text === '{' || this._flags.last_token.text === ';')) { 1459 | // { foo; --i } 1460 | // foo(); --bar; 1461 | this.print_newline(); 1462 | } 1463 | } 1464 | 1465 | this._output.space_before_token = this._output.space_before_token || space_before; 1466 | this.print_token(current_token); 1467 | this._output.space_before_token = space_after; 1468 | }; 1469 | 1470 | Beautifier.prototype.handle_block_comment = function(current_token, preserve_statement_flags) { 1471 | if (this._output.raw) { 1472 | this._output.add_raw_token(current_token); 1473 | if (current_token.directives && current_token.directives.preserve === 'end') { 1474 | // If we're testing the raw output behavior, do not allow a directive to turn it off. 1475 | this._output.raw = this._options.test_output_raw; 1476 | } 1477 | return; 1478 | } 1479 | 1480 | if (current_token.directives) { 1481 | this.print_newline(false, preserve_statement_flags); 1482 | this.print_token(current_token); 1483 | if (current_token.directives.preserve === 'start') { 1484 | this._output.raw = true; 1485 | } 1486 | this.print_newline(false, true); 1487 | return; 1488 | } 1489 | 1490 | // inline block 1491 | if (!acorn.newline.test(current_token.text) && !current_token.newlines) { 1492 | this._output.space_before_token = true; 1493 | this.print_token(current_token); 1494 | this._output.space_before_token = true; 1495 | return; 1496 | } else { 1497 | this.print_block_commment(current_token, preserve_statement_flags); 1498 | } 1499 | }; 1500 | 1501 | Beautifier.prototype.print_block_commment = function(current_token, preserve_statement_flags) { 1502 | var lines = split_linebreaks(current_token.text); 1503 | var j; // iterator for this case 1504 | var javadoc = false; 1505 | var starless = false; 1506 | var lastIndent = current_token.whitespace_before; 1507 | var lastIndentLength = lastIndent.length; 1508 | 1509 | // block comment starts with a new line 1510 | this.print_newline(false, preserve_statement_flags); 1511 | 1512 | // first line always indented 1513 | this.print_token_line_indentation(current_token); 1514 | this._output.add_token(lines[0]); 1515 | this.print_newline(false, preserve_statement_flags); 1516 | 1517 | 1518 | if (lines.length > 1) { 1519 | lines = lines.slice(1); 1520 | javadoc = all_lines_start_with(lines, '*'); 1521 | starless = each_line_matches_indent(lines, lastIndent); 1522 | 1523 | if (javadoc) { 1524 | this._flags.alignment = 1; 1525 | } 1526 | 1527 | for (j = 0; j < lines.length; j++) { 1528 | if (javadoc) { 1529 | // javadoc: reformat and re-indent 1530 | this.print_token_line_indentation(current_token); 1531 | this._output.add_token(ltrim(lines[j])); 1532 | } else if (starless && lines[j]) { 1533 | // starless: re-indent non-empty content, avoiding trim 1534 | this.print_token_line_indentation(current_token); 1535 | this._output.add_token(lines[j].substring(lastIndentLength)); 1536 | } else { 1537 | // normal comments output raw 1538 | this._output.current_line.set_indent(-1); 1539 | this._output.add_token(lines[j]); 1540 | } 1541 | 1542 | // for comments on their own line or more than one line, make sure there's a new line after 1543 | this.print_newline(false, preserve_statement_flags); 1544 | } 1545 | 1546 | this._flags.alignment = 0; 1547 | } 1548 | }; 1549 | 1550 | 1551 | Beautifier.prototype.handle_comment = function(current_token, preserve_statement_flags) { 1552 | if (current_token.newlines) { 1553 | this.print_newline(false, preserve_statement_flags); 1554 | } else { 1555 | this._output.trim(true); 1556 | } 1557 | 1558 | this._output.space_before_token = true; 1559 | this.print_token(current_token); 1560 | this.print_newline(false, preserve_statement_flags); 1561 | }; 1562 | 1563 | Beautifier.prototype.handle_dot = function(current_token) { 1564 | if (this.start_of_statement(current_token)) { 1565 | // The conditional starts the statement if appropriate. 1566 | } else { 1567 | this.handle_whitespace_and_comments(current_token, true); 1568 | } 1569 | 1570 | if (reserved_array(this._flags.last_token, special_words)) { 1571 | this._output.space_before_token = false; 1572 | } else { 1573 | // allow preserved newlines before dots in general 1574 | // force newlines on dots after close paren when break_chained - for bar().baz() 1575 | this.allow_wrap_or_preserved_newline(current_token, 1576 | this._flags.last_token.text === ')' && this._options.break_chained_methods); 1577 | } 1578 | 1579 | // Only unindent chained method dot if this dot starts a new line. 1580 | // Otherwise the automatic extra indentation removal will handle the over indent 1581 | if (this._options.unindent_chained_methods && this._output.just_added_newline()) { 1582 | this.deindent(); 1583 | } 1584 | 1585 | this.print_token(current_token); 1586 | }; 1587 | 1588 | Beautifier.prototype.handle_unknown = function(current_token, preserve_statement_flags) { 1589 | this.print_token(current_token); 1590 | 1591 | if (current_token.text[current_token.text.length - 1] === '\n') { 1592 | this.print_newline(false, preserve_statement_flags); 1593 | } 1594 | }; 1595 | 1596 | Beautifier.prototype.handle_eof = function(current_token) { 1597 | // Unwind any open statements 1598 | while (this._flags.mode === MODE.Statement) { 1599 | this.restore_mode(); 1600 | } 1601 | this.handle_whitespace_and_comments(current_token); 1602 | }; 1603 | 1604 | module.exports.Beautifier = Beautifier; 1605 | 1606 | 1607 | /***/ }), 1608 | /* 2 */ 1609 | /***/ (function(module) { 1610 | 1611 | /*jshint node:true */ 1612 | /* 1613 | The MIT License (MIT) 1614 | 1615 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 1616 | 1617 | Permission is hereby granted, free of charge, to any person 1618 | obtaining a copy of this software and associated documentation files 1619 | (the "Software"), to deal in the Software without restriction, 1620 | including without limitation the rights to use, copy, modify, merge, 1621 | publish, distribute, sublicense, and/or sell copies of the Software, 1622 | and to permit persons to whom the Software is furnished to do so, 1623 | subject to the following conditions: 1624 | 1625 | The above copyright notice and this permission notice shall be 1626 | included in all copies or substantial portions of the Software. 1627 | 1628 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1629 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1630 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1631 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 1632 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 1633 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1634 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1635 | SOFTWARE. 1636 | */ 1637 | 1638 | 1639 | 1640 | function OutputLine(parent) { 1641 | this.__parent = parent; 1642 | this.__character_count = 0; 1643 | // use indent_count as a marker for this.__lines that have preserved indentation 1644 | this.__indent_count = -1; 1645 | this.__alignment_count = 0; 1646 | this.__wrap_point_index = 0; 1647 | this.__wrap_point_character_count = 0; 1648 | this.__wrap_point_indent_count = -1; 1649 | this.__wrap_point_alignment_count = 0; 1650 | 1651 | this.__items = []; 1652 | } 1653 | 1654 | OutputLine.prototype.clone_empty = function() { 1655 | var line = new OutputLine(this.__parent); 1656 | line.set_indent(this.__indent_count, this.__alignment_count); 1657 | return line; 1658 | }; 1659 | 1660 | OutputLine.prototype.item = function(index) { 1661 | if (index < 0) { 1662 | return this.__items[this.__items.length + index]; 1663 | } else { 1664 | return this.__items[index]; 1665 | } 1666 | }; 1667 | 1668 | OutputLine.prototype.has_match = function(pattern) { 1669 | for (var lastCheckedOutput = this.__items.length - 1; lastCheckedOutput >= 0; lastCheckedOutput--) { 1670 | if (this.__items[lastCheckedOutput].match(pattern)) { 1671 | return true; 1672 | } 1673 | } 1674 | return false; 1675 | }; 1676 | 1677 | OutputLine.prototype.set_indent = function(indent, alignment) { 1678 | if (this.is_empty()) { 1679 | this.__indent_count = indent || 0; 1680 | this.__alignment_count = alignment || 0; 1681 | this.__character_count = this.__parent.get_indent_size(this.__indent_count, this.__alignment_count); 1682 | } 1683 | }; 1684 | 1685 | OutputLine.prototype._set_wrap_point = function() { 1686 | if (this.__parent.wrap_line_length) { 1687 | this.__wrap_point_index = this.__items.length; 1688 | this.__wrap_point_character_count = this.__character_count; 1689 | this.__wrap_point_indent_count = this.__parent.next_line.__indent_count; 1690 | this.__wrap_point_alignment_count = this.__parent.next_line.__alignment_count; 1691 | } 1692 | }; 1693 | 1694 | OutputLine.prototype._should_wrap = function() { 1695 | return this.__wrap_point_index && 1696 | this.__character_count > this.__parent.wrap_line_length && 1697 | this.__wrap_point_character_count > this.__parent.next_line.__character_count; 1698 | }; 1699 | 1700 | OutputLine.prototype._allow_wrap = function() { 1701 | if (this._should_wrap()) { 1702 | this.__parent.add_new_line(); 1703 | var next = this.__parent.current_line; 1704 | next.set_indent(this.__wrap_point_indent_count, this.__wrap_point_alignment_count); 1705 | next.__items = this.__items.slice(this.__wrap_point_index); 1706 | this.__items = this.__items.slice(0, this.__wrap_point_index); 1707 | 1708 | next.__character_count += this.__character_count - this.__wrap_point_character_count; 1709 | this.__character_count = this.__wrap_point_character_count; 1710 | 1711 | if (next.__items[0] === " ") { 1712 | next.__items.splice(0, 1); 1713 | next.__character_count -= 1; 1714 | } 1715 | return true; 1716 | } 1717 | return false; 1718 | }; 1719 | 1720 | OutputLine.prototype.is_empty = function() { 1721 | return this.__items.length === 0; 1722 | }; 1723 | 1724 | OutputLine.prototype.last = function() { 1725 | if (!this.is_empty()) { 1726 | return this.__items[this.__items.length - 1]; 1727 | } else { 1728 | return null; 1729 | } 1730 | }; 1731 | 1732 | OutputLine.prototype.push = function(item) { 1733 | this.__items.push(item); 1734 | var last_newline_index = item.lastIndexOf('\n'); 1735 | if (last_newline_index !== -1) { 1736 | this.__character_count = item.length - last_newline_index; 1737 | } else { 1738 | this.__character_count += item.length; 1739 | } 1740 | }; 1741 | 1742 | OutputLine.prototype.pop = function() { 1743 | var item = null; 1744 | if (!this.is_empty()) { 1745 | item = this.__items.pop(); 1746 | this.__character_count -= item.length; 1747 | } 1748 | return item; 1749 | }; 1750 | 1751 | 1752 | OutputLine.prototype._remove_indent = function() { 1753 | if (this.__indent_count > 0) { 1754 | this.__indent_count -= 1; 1755 | this.__character_count -= this.__parent.indent_size; 1756 | } 1757 | }; 1758 | 1759 | OutputLine.prototype._remove_wrap_indent = function() { 1760 | if (this.__wrap_point_indent_count > 0) { 1761 | this.__wrap_point_indent_count -= 1; 1762 | } 1763 | }; 1764 | OutputLine.prototype.trim = function() { 1765 | while (this.last() === ' ') { 1766 | this.__items.pop(); 1767 | this.__character_count -= 1; 1768 | } 1769 | }; 1770 | 1771 | OutputLine.prototype.toString = function() { 1772 | var result = ''; 1773 | if (this.is_empty()) { 1774 | if (this.__parent.indent_empty_lines) { 1775 | result = this.__parent.get_indent_string(this.__indent_count); 1776 | } 1777 | } else { 1778 | result = this.__parent.get_indent_string(this.__indent_count, this.__alignment_count); 1779 | result += this.__items.join(''); 1780 | } 1781 | return result; 1782 | }; 1783 | 1784 | function IndentStringCache(options, baseIndentString) { 1785 | this.__cache = ['']; 1786 | this.__indent_size = options.indent_size; 1787 | this.__indent_string = options.indent_char; 1788 | if (!options.indent_with_tabs) { 1789 | this.__indent_string = new Array(options.indent_size + 1).join(options.indent_char); 1790 | } 1791 | 1792 | // Set to null to continue support for auto detection of base indent 1793 | baseIndentString = baseIndentString || ''; 1794 | if (options.indent_level > 0) { 1795 | baseIndentString = new Array(options.indent_level + 1).join(this.__indent_string); 1796 | } 1797 | 1798 | this.__base_string = baseIndentString; 1799 | this.__base_string_length = baseIndentString.length; 1800 | } 1801 | 1802 | IndentStringCache.prototype.get_indent_size = function(indent, column) { 1803 | var result = this.__base_string_length; 1804 | column = column || 0; 1805 | if (indent < 0) { 1806 | result = 0; 1807 | } 1808 | result += indent * this.__indent_size; 1809 | result += column; 1810 | return result; 1811 | }; 1812 | 1813 | IndentStringCache.prototype.get_indent_string = function(indent_level, column) { 1814 | var result = this.__base_string; 1815 | column = column || 0; 1816 | if (indent_level < 0) { 1817 | indent_level = 0; 1818 | result = ''; 1819 | } 1820 | column += indent_level * this.__indent_size; 1821 | this.__ensure_cache(column); 1822 | result += this.__cache[column]; 1823 | return result; 1824 | }; 1825 | 1826 | IndentStringCache.prototype.__ensure_cache = function(column) { 1827 | while (column >= this.__cache.length) { 1828 | this.__add_column(); 1829 | } 1830 | }; 1831 | 1832 | IndentStringCache.prototype.__add_column = function() { 1833 | var column = this.__cache.length; 1834 | var indent = 0; 1835 | var result = ''; 1836 | if (this.__indent_size && column >= this.__indent_size) { 1837 | indent = Math.floor(column / this.__indent_size); 1838 | column -= indent * this.__indent_size; 1839 | result = new Array(indent + 1).join(this.__indent_string); 1840 | } 1841 | if (column) { 1842 | result += new Array(column + 1).join(' '); 1843 | } 1844 | 1845 | this.__cache.push(result); 1846 | }; 1847 | 1848 | function Output(options, baseIndentString) { 1849 | this.__indent_cache = new IndentStringCache(options, baseIndentString); 1850 | this.raw = false; 1851 | this._end_with_newline = options.end_with_newline; 1852 | this.indent_size = options.indent_size; 1853 | this.wrap_line_length = options.wrap_line_length; 1854 | this.indent_empty_lines = options.indent_empty_lines; 1855 | this.__lines = []; 1856 | this.previous_line = null; 1857 | this.current_line = null; 1858 | this.next_line = new OutputLine(this); 1859 | this.space_before_token = false; 1860 | this.non_breaking_space = false; 1861 | this.previous_token_wrapped = false; 1862 | // initialize 1863 | this.__add_outputline(); 1864 | } 1865 | 1866 | Output.prototype.__add_outputline = function() { 1867 | this.previous_line = this.current_line; 1868 | this.current_line = this.next_line.clone_empty(); 1869 | this.__lines.push(this.current_line); 1870 | }; 1871 | 1872 | Output.prototype.get_line_number = function() { 1873 | return this.__lines.length; 1874 | }; 1875 | 1876 | Output.prototype.get_indent_string = function(indent, column) { 1877 | return this.__indent_cache.get_indent_string(indent, column); 1878 | }; 1879 | 1880 | Output.prototype.get_indent_size = function(indent, column) { 1881 | return this.__indent_cache.get_indent_size(indent, column); 1882 | }; 1883 | 1884 | Output.prototype.is_empty = function() { 1885 | return !this.previous_line && this.current_line.is_empty(); 1886 | }; 1887 | 1888 | Output.prototype.add_new_line = function(force_newline) { 1889 | // never newline at the start of file 1890 | // otherwise, newline only if we didn't just add one or we're forced 1891 | if (this.is_empty() || 1892 | (!force_newline && this.just_added_newline())) { 1893 | return false; 1894 | } 1895 | 1896 | // if raw output is enabled, don't print additional newlines, 1897 | // but still return True as though you had 1898 | if (!this.raw) { 1899 | this.__add_outputline(); 1900 | } 1901 | return true; 1902 | }; 1903 | 1904 | Output.prototype.get_code = function(eol) { 1905 | this.trim(true); 1906 | 1907 | // handle some edge cases where the last tokens 1908 | // has text that ends with newline(s) 1909 | var last_item = this.current_line.pop(); 1910 | if (last_item) { 1911 | if (last_item[last_item.length - 1] === '\n') { 1912 | last_item = last_item.replace(/\n+$/g, ''); 1913 | } 1914 | this.current_line.push(last_item); 1915 | } 1916 | 1917 | if (this._end_with_newline) { 1918 | this.__add_outputline(); 1919 | } 1920 | 1921 | var sweet_code = this.__lines.join('\n'); 1922 | 1923 | if (eol !== '\n') { 1924 | sweet_code = sweet_code.replace(/[\n]/g, eol); 1925 | } 1926 | return sweet_code; 1927 | }; 1928 | 1929 | Output.prototype.set_wrap_point = function() { 1930 | this.current_line._set_wrap_point(); 1931 | }; 1932 | 1933 | Output.prototype.set_indent = function(indent, alignment) { 1934 | indent = indent || 0; 1935 | alignment = alignment || 0; 1936 | 1937 | // Next line stores alignment values 1938 | this.next_line.set_indent(indent, alignment); 1939 | 1940 | // Never indent your first output indent at the start of the file 1941 | if (this.__lines.length > 1) { 1942 | this.current_line.set_indent(indent, alignment); 1943 | return true; 1944 | } 1945 | 1946 | this.current_line.set_indent(); 1947 | return false; 1948 | }; 1949 | 1950 | Output.prototype.add_raw_token = function(token) { 1951 | for (var x = 0; x < token.newlines; x++) { 1952 | this.__add_outputline(); 1953 | } 1954 | this.current_line.set_indent(-1); 1955 | this.current_line.push(token.whitespace_before); 1956 | this.current_line.push(token.text); 1957 | this.space_before_token = false; 1958 | this.non_breaking_space = false; 1959 | this.previous_token_wrapped = false; 1960 | }; 1961 | 1962 | Output.prototype.add_token = function(printable_token) { 1963 | this.__add_space_before_token(); 1964 | this.current_line.push(printable_token); 1965 | this.space_before_token = false; 1966 | this.non_breaking_space = false; 1967 | this.previous_token_wrapped = this.current_line._allow_wrap(); 1968 | }; 1969 | 1970 | Output.prototype.__add_space_before_token = function() { 1971 | if (this.space_before_token && !this.just_added_newline()) { 1972 | if (!this.non_breaking_space) { 1973 | this.set_wrap_point(); 1974 | } 1975 | this.current_line.push(' '); 1976 | } 1977 | }; 1978 | 1979 | Output.prototype.remove_indent = function(index) { 1980 | var output_length = this.__lines.length; 1981 | while (index < output_length) { 1982 | this.__lines[index]._remove_indent(); 1983 | index++; 1984 | } 1985 | this.current_line._remove_wrap_indent(); 1986 | }; 1987 | 1988 | Output.prototype.trim = function(eat_newlines) { 1989 | eat_newlines = (eat_newlines === undefined) ? false : eat_newlines; 1990 | 1991 | this.current_line.trim(); 1992 | 1993 | while (eat_newlines && this.__lines.length > 1 && 1994 | this.current_line.is_empty()) { 1995 | this.__lines.pop(); 1996 | this.current_line = this.__lines[this.__lines.length - 1]; 1997 | this.current_line.trim(); 1998 | } 1999 | 2000 | this.previous_line = this.__lines.length > 1 ? 2001 | this.__lines[this.__lines.length - 2] : null; 2002 | }; 2003 | 2004 | Output.prototype.just_added_newline = function() { 2005 | return this.current_line.is_empty(); 2006 | }; 2007 | 2008 | Output.prototype.just_added_blankline = function() { 2009 | return this.is_empty() || 2010 | (this.current_line.is_empty() && this.previous_line.is_empty()); 2011 | }; 2012 | 2013 | Output.prototype.ensure_empty_line_above = function(starts_with, ends_with) { 2014 | var index = this.__lines.length - 2; 2015 | while (index >= 0) { 2016 | var potentialEmptyLine = this.__lines[index]; 2017 | if (potentialEmptyLine.is_empty()) { 2018 | break; 2019 | } else if (potentialEmptyLine.item(0).indexOf(starts_with) !== 0 && 2020 | potentialEmptyLine.item(-1) !== ends_with) { 2021 | this.__lines.splice(index + 1, 0, new OutputLine(this)); 2022 | this.previous_line = this.__lines[this.__lines.length - 2]; 2023 | break; 2024 | } 2025 | index--; 2026 | } 2027 | }; 2028 | 2029 | module.exports.Output = Output; 2030 | 2031 | 2032 | /***/ }), 2033 | /* 3 */ 2034 | /***/ (function(module) { 2035 | 2036 | /*jshint node:true */ 2037 | /* 2038 | 2039 | The MIT License (MIT) 2040 | 2041 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 2042 | 2043 | Permission is hereby granted, free of charge, to any person 2044 | obtaining a copy of this software and associated documentation files 2045 | (the "Software"), to deal in the Software without restriction, 2046 | including without limitation the rights to use, copy, modify, merge, 2047 | publish, distribute, sublicense, and/or sell copies of the Software, 2048 | and to permit persons to whom the Software is furnished to do so, 2049 | subject to the following conditions: 2050 | 2051 | The above copyright notice and this permission notice shall be 2052 | included in all copies or substantial portions of the Software. 2053 | 2054 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2055 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2056 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2057 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2058 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 2059 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2060 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2061 | SOFTWARE. 2062 | */ 2063 | 2064 | 2065 | 2066 | function Token(type, text, newlines, whitespace_before) { 2067 | this.type = type; 2068 | this.text = text; 2069 | 2070 | // comments_before are 2071 | // comments that have a new line before them 2072 | // and may or may not have a newline after 2073 | // this is a set of comments before 2074 | this.comments_before = null; /* inline comment*/ 2075 | 2076 | 2077 | // this.comments_after = new TokenStream(); // no new line before and newline after 2078 | this.newlines = newlines || 0; 2079 | this.whitespace_before = whitespace_before || ''; 2080 | this.parent = null; 2081 | this.next = null; 2082 | this.previous = null; 2083 | this.opened = null; 2084 | this.closed = null; 2085 | this.directives = null; 2086 | } 2087 | 2088 | 2089 | module.exports.Token = Token; 2090 | 2091 | 2092 | /***/ }), 2093 | /* 4 */ 2094 | /***/ (function(__unused_webpack_module, exports) { 2095 | 2096 | /* jshint node: true, curly: false */ 2097 | // Parts of this section of code is taken from acorn. 2098 | // 2099 | // Acorn was written by Marijn Haverbeke and released under an MIT 2100 | // license. The Unicode regexps (for identifiers and whitespace) were 2101 | // taken from [Esprima](http://esprima.org) by Ariya Hidayat. 2102 | // 2103 | // Git repositories for Acorn are available at 2104 | // 2105 | // http://marijnhaverbeke.nl/git/acorn 2106 | // https://github.com/marijnh/acorn.git 2107 | 2108 | // ## Character categories 2109 | 2110 | 2111 | 2112 | 2113 | // acorn used char codes to squeeze the last bit of performance out 2114 | // Beautifier is okay without that, so we're using regex 2115 | // permit # (23), $ (36), and @ (64). @ is used in ES7 decorators. 2116 | // 65 through 91 are uppercase letters. 2117 | // permit _ (95). 2118 | // 97 through 123 are lowercase letters. 2119 | var baseASCIIidentifierStartChars = "\\x23\\x24\\x40\\x41-\\x5a\\x5f\\x61-\\x7a"; 2120 | 2121 | // inside an identifier @ is not allowed but 0-9 are. 2122 | var baseASCIIidentifierChars = "\\x24\\x30-\\x39\\x41-\\x5a\\x5f\\x61-\\x7a"; 2123 | 2124 | // Big ugly regular expressions that match characters in the 2125 | // whitespace, identifier, and identifier-start categories. These 2126 | // are only applied when a character is found to actually have a 2127 | // code point above 128. 2128 | 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"; 2129 | 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"; 2130 | //var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); 2131 | //var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); 2132 | 2133 | var identifierStart = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])"; 2134 | var identifierChars = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*"; 2135 | 2136 | exports.identifier = new RegExp(identifierStart + identifierChars, 'g'); 2137 | exports.identifierStart = new RegExp(identifierStart); 2138 | exports.identifierMatch = new RegExp("(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+"); 2139 | 2140 | var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; // jshint ignore:line 2141 | 2142 | // Whether a single character denotes a newline. 2143 | 2144 | exports.newline = /[\n\r\u2028\u2029]/; 2145 | 2146 | // Matches a whole line break (where CRLF is considered a single 2147 | // line break). Used to count lines. 2148 | 2149 | // in javascript, these two differ 2150 | // in python they are the same, different methods are called on them 2151 | exports.lineBreak = new RegExp('\r\n|' + exports.newline.source); 2152 | exports.allLineBreaks = new RegExp(exports.lineBreak.source, 'g'); 2153 | 2154 | 2155 | /***/ }), 2156 | /* 5 */ 2157 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 2158 | 2159 | /*jshint node:true */ 2160 | /* 2161 | 2162 | The MIT License (MIT) 2163 | 2164 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 2165 | 2166 | Permission is hereby granted, free of charge, to any person 2167 | obtaining a copy of this software and associated documentation files 2168 | (the "Software"), to deal in the Software without restriction, 2169 | including without limitation the rights to use, copy, modify, merge, 2170 | publish, distribute, sublicense, and/or sell copies of the Software, 2171 | and to permit persons to whom the Software is furnished to do so, 2172 | subject to the following conditions: 2173 | 2174 | The above copyright notice and this permission notice shall be 2175 | included in all copies or substantial portions of the Software. 2176 | 2177 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2178 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2179 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2180 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2181 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 2182 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2183 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2184 | SOFTWARE. 2185 | */ 2186 | 2187 | 2188 | 2189 | var BaseOptions = __webpack_require__(6).Options; 2190 | 2191 | var validPositionValues = ['before-newline', 'after-newline', 'preserve-newline']; 2192 | 2193 | function Options(options) { 2194 | BaseOptions.call(this, options, 'js'); 2195 | 2196 | // compatibility, re 2197 | var raw_brace_style = this.raw_options.brace_style || null; 2198 | if (raw_brace_style === "expand-strict") { //graceful handling of deprecated option 2199 | this.raw_options.brace_style = "expand"; 2200 | } else if (raw_brace_style === "collapse-preserve-inline") { //graceful handling of deprecated option 2201 | this.raw_options.brace_style = "collapse,preserve-inline"; 2202 | } else if (this.raw_options.braces_on_own_line !== undefined) { //graceful handling of deprecated option 2203 | this.raw_options.brace_style = this.raw_options.braces_on_own_line ? "expand" : "collapse"; 2204 | // } else if (!raw_brace_style) { //Nothing exists to set it 2205 | // raw_brace_style = "collapse"; 2206 | } 2207 | 2208 | //preserve-inline in delimited string will trigger brace_preserve_inline, everything 2209 | //else is considered a brace_style and the last one only will have an effect 2210 | 2211 | var brace_style_split = this._get_selection_list('brace_style', ['collapse', 'expand', 'end-expand', 'none', 'preserve-inline']); 2212 | 2213 | this.brace_preserve_inline = false; //Defaults in case one or other was not specified in meta-option 2214 | this.brace_style = "collapse"; 2215 | 2216 | for (var bs = 0; bs < brace_style_split.length; bs++) { 2217 | if (brace_style_split[bs] === "preserve-inline") { 2218 | this.brace_preserve_inline = true; 2219 | } else { 2220 | this.brace_style = brace_style_split[bs]; 2221 | } 2222 | } 2223 | 2224 | this.unindent_chained_methods = this._get_boolean('unindent_chained_methods'); 2225 | this.break_chained_methods = this._get_boolean('break_chained_methods'); 2226 | this.space_in_paren = this._get_boolean('space_in_paren'); 2227 | this.space_in_empty_paren = this._get_boolean('space_in_empty_paren'); 2228 | this.jslint_happy = this._get_boolean('jslint_happy'); 2229 | this.space_after_anon_function = this._get_boolean('space_after_anon_function'); 2230 | this.space_after_named_function = this._get_boolean('space_after_named_function'); 2231 | this.keep_array_indentation = this._get_boolean('keep_array_indentation'); 2232 | this.space_before_conditional = this._get_boolean('space_before_conditional', true); 2233 | this.unescape_strings = this._get_boolean('unescape_strings'); 2234 | this.e4x = this._get_boolean('e4x'); 2235 | this.comma_first = this._get_boolean('comma_first'); 2236 | this.operator_position = this._get_selection('operator_position', validPositionValues); 2237 | 2238 | // For testing of beautify preserve:start directive 2239 | this.test_output_raw = this._get_boolean('test_output_raw'); 2240 | 2241 | // force this._options.space_after_anon_function to true if this._options.jslint_happy 2242 | if (this.jslint_happy) { 2243 | this.space_after_anon_function = true; 2244 | } 2245 | 2246 | } 2247 | Options.prototype = new BaseOptions(); 2248 | 2249 | 2250 | 2251 | module.exports.Options = Options; 2252 | 2253 | 2254 | /***/ }), 2255 | /* 6 */ 2256 | /***/ (function(module) { 2257 | 2258 | /*jshint node:true */ 2259 | /* 2260 | 2261 | The MIT License (MIT) 2262 | 2263 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 2264 | 2265 | Permission is hereby granted, free of charge, to any person 2266 | obtaining a copy of this software and associated documentation files 2267 | (the "Software"), to deal in the Software without restriction, 2268 | including without limitation the rights to use, copy, modify, merge, 2269 | publish, distribute, sublicense, and/or sell copies of the Software, 2270 | and to permit persons to whom the Software is furnished to do so, 2271 | subject to the following conditions: 2272 | 2273 | The above copyright notice and this permission notice shall be 2274 | included in all copies or substantial portions of the Software. 2275 | 2276 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2277 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2278 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2279 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2280 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 2281 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2282 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2283 | SOFTWARE. 2284 | */ 2285 | 2286 | 2287 | 2288 | function Options(options, merge_child_field) { 2289 | this.raw_options = _mergeOpts(options, merge_child_field); 2290 | 2291 | // Support passing the source text back with no change 2292 | this.disabled = this._get_boolean('disabled'); 2293 | 2294 | this.eol = this._get_characters('eol', 'auto'); 2295 | this.end_with_newline = this._get_boolean('end_with_newline'); 2296 | this.indent_size = this._get_number('indent_size', 4); 2297 | this.indent_char = this._get_characters('indent_char', ' '); 2298 | this.indent_level = this._get_number('indent_level'); 2299 | 2300 | this.preserve_newlines = this._get_boolean('preserve_newlines', true); 2301 | this.max_preserve_newlines = this._get_number('max_preserve_newlines', 32786); 2302 | if (!this.preserve_newlines) { 2303 | this.max_preserve_newlines = 0; 2304 | } 2305 | 2306 | this.indent_with_tabs = this._get_boolean('indent_with_tabs', this.indent_char === '\t'); 2307 | if (this.indent_with_tabs) { 2308 | this.indent_char = '\t'; 2309 | 2310 | // indent_size behavior changed after 1.8.6 2311 | // It used to be that indent_size would be 2312 | // set to 1 for indent_with_tabs. That is no longer needed and 2313 | // actually doesn't make sense - why not use spaces? Further, 2314 | // that might produce unexpected behavior - tabs being used 2315 | // for single-column alignment. So, when indent_with_tabs is true 2316 | // and indent_size is 1, reset indent_size to 4. 2317 | if (this.indent_size === 1) { 2318 | this.indent_size = 4; 2319 | } 2320 | } 2321 | 2322 | // Backwards compat with 1.3.x 2323 | this.wrap_line_length = this._get_number('wrap_line_length', this._get_number('max_char')); 2324 | 2325 | this.indent_empty_lines = this._get_boolean('indent_empty_lines'); 2326 | 2327 | // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] 2328 | // For now, 'auto' = all off for javascript, all on for html (and inline javascript). 2329 | // other values ignored 2330 | this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); 2331 | } 2332 | 2333 | Options.prototype._get_array = function(name, default_value) { 2334 | var option_value = this.raw_options[name]; 2335 | var result = default_value || []; 2336 | if (typeof option_value === 'object') { 2337 | if (option_value !== null && typeof option_value.concat === 'function') { 2338 | result = option_value.concat(); 2339 | } 2340 | } else if (typeof option_value === 'string') { 2341 | result = option_value.split(/[^a-zA-Z0-9_\/\-]+/); 2342 | } 2343 | return result; 2344 | }; 2345 | 2346 | Options.prototype._get_boolean = function(name, default_value) { 2347 | var option_value = this.raw_options[name]; 2348 | var result = option_value === undefined ? !!default_value : !!option_value; 2349 | return result; 2350 | }; 2351 | 2352 | Options.prototype._get_characters = function(name, default_value) { 2353 | var option_value = this.raw_options[name]; 2354 | var result = default_value || ''; 2355 | if (typeof option_value === 'string') { 2356 | result = option_value.replace(/\\r/, '\r').replace(/\\n/, '\n').replace(/\\t/, '\t'); 2357 | } 2358 | return result; 2359 | }; 2360 | 2361 | Options.prototype._get_number = function(name, default_value) { 2362 | var option_value = this.raw_options[name]; 2363 | default_value = parseInt(default_value, 10); 2364 | if (isNaN(default_value)) { 2365 | default_value = 0; 2366 | } 2367 | var result = parseInt(option_value, 10); 2368 | if (isNaN(result)) { 2369 | result = default_value; 2370 | } 2371 | return result; 2372 | }; 2373 | 2374 | Options.prototype._get_selection = function(name, selection_list, default_value) { 2375 | var result = this._get_selection_list(name, selection_list, default_value); 2376 | if (result.length !== 1) { 2377 | throw new Error( 2378 | "Invalid Option Value: The option '" + name + "' can only be one of the following values:\n" + 2379 | selection_list + "\nYou passed in: '" + this.raw_options[name] + "'"); 2380 | } 2381 | 2382 | return result[0]; 2383 | }; 2384 | 2385 | 2386 | Options.prototype._get_selection_list = function(name, selection_list, default_value) { 2387 | if (!selection_list || selection_list.length === 0) { 2388 | throw new Error("Selection list cannot be empty."); 2389 | } 2390 | 2391 | default_value = default_value || [selection_list[0]]; 2392 | if (!this._is_valid_selection(default_value, selection_list)) { 2393 | throw new Error("Invalid Default Value!"); 2394 | } 2395 | 2396 | var result = this._get_array(name, default_value); 2397 | if (!this._is_valid_selection(result, selection_list)) { 2398 | throw new Error( 2399 | "Invalid Option Value: The option '" + name + "' can contain only the following values:\n" + 2400 | selection_list + "\nYou passed in: '" + this.raw_options[name] + "'"); 2401 | } 2402 | 2403 | return result; 2404 | }; 2405 | 2406 | Options.prototype._is_valid_selection = function(result, selection_list) { 2407 | return result.length && selection_list.length && 2408 | !result.some(function(item) { return selection_list.indexOf(item) === -1; }); 2409 | }; 2410 | 2411 | 2412 | // merges child options up with the parent options object 2413 | // Example: obj = {a: 1, b: {a: 2}} 2414 | // mergeOpts(obj, 'b') 2415 | // 2416 | // Returns: {a: 2} 2417 | function _mergeOpts(allOptions, childFieldName) { 2418 | var finalOpts = {}; 2419 | allOptions = _normalizeOpts(allOptions); 2420 | var name; 2421 | 2422 | for (name in allOptions) { 2423 | if (name !== childFieldName) { 2424 | finalOpts[name] = allOptions[name]; 2425 | } 2426 | } 2427 | 2428 | //merge in the per type settings for the childFieldName 2429 | if (childFieldName && allOptions[childFieldName]) { 2430 | for (name in allOptions[childFieldName]) { 2431 | finalOpts[name] = allOptions[childFieldName][name]; 2432 | } 2433 | } 2434 | return finalOpts; 2435 | } 2436 | 2437 | function _normalizeOpts(options) { 2438 | var convertedOpts = {}; 2439 | var key; 2440 | 2441 | for (key in options) { 2442 | var newKey = key.replace(/-/g, "_"); 2443 | convertedOpts[newKey] = options[key]; 2444 | } 2445 | return convertedOpts; 2446 | } 2447 | 2448 | module.exports.Options = Options; 2449 | module.exports.normalizeOpts = _normalizeOpts; 2450 | module.exports.mergeOpts = _mergeOpts; 2451 | 2452 | 2453 | /***/ }), 2454 | /* 7 */ 2455 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 2456 | 2457 | /*jshint node:true */ 2458 | /* 2459 | 2460 | The MIT License (MIT) 2461 | 2462 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 2463 | 2464 | Permission is hereby granted, free of charge, to any person 2465 | obtaining a copy of this software and associated documentation files 2466 | (the "Software"), to deal in the Software without restriction, 2467 | including without limitation the rights to use, copy, modify, merge, 2468 | publish, distribute, sublicense, and/or sell copies of the Software, 2469 | and to permit persons to whom the Software is furnished to do so, 2470 | subject to the following conditions: 2471 | 2472 | The above copyright notice and this permission notice shall be 2473 | included in all copies or substantial portions of the Software. 2474 | 2475 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2476 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2477 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2478 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2479 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 2480 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2481 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2482 | SOFTWARE. 2483 | */ 2484 | 2485 | 2486 | 2487 | var InputScanner = __webpack_require__(8).InputScanner; 2488 | var BaseTokenizer = __webpack_require__(9).Tokenizer; 2489 | var BASETOKEN = __webpack_require__(9).TOKEN; 2490 | var Directives = __webpack_require__(13).Directives; 2491 | var acorn = __webpack_require__(4); 2492 | var Pattern = __webpack_require__(12).Pattern; 2493 | var TemplatablePattern = __webpack_require__(14).TemplatablePattern; 2494 | 2495 | 2496 | function in_array(what, arr) { 2497 | return arr.indexOf(what) !== -1; 2498 | } 2499 | 2500 | 2501 | var TOKEN = { 2502 | START_EXPR: 'TK_START_EXPR', 2503 | END_EXPR: 'TK_END_EXPR', 2504 | START_BLOCK: 'TK_START_BLOCK', 2505 | END_BLOCK: 'TK_END_BLOCK', 2506 | WORD: 'TK_WORD', 2507 | RESERVED: 'TK_RESERVED', 2508 | SEMICOLON: 'TK_SEMICOLON', 2509 | STRING: 'TK_STRING', 2510 | EQUALS: 'TK_EQUALS', 2511 | OPERATOR: 'TK_OPERATOR', 2512 | COMMA: 'TK_COMMA', 2513 | BLOCK_COMMENT: 'TK_BLOCK_COMMENT', 2514 | COMMENT: 'TK_COMMENT', 2515 | DOT: 'TK_DOT', 2516 | UNKNOWN: 'TK_UNKNOWN', 2517 | START: BASETOKEN.START, 2518 | RAW: BASETOKEN.RAW, 2519 | EOF: BASETOKEN.EOF 2520 | }; 2521 | 2522 | 2523 | var directives_core = new Directives(/\/\*/, /\*\//); 2524 | 2525 | var number_pattern = /0[xX][0123456789abcdefABCDEF_]*n?|0[oO][01234567_]*n?|0[bB][01_]*n?|\d[\d_]*n|(?:\.\d[\d_]*|\d[\d_]*\.?[\d_]*)(?:[eE][+-]?[\d_]+)?/; 2526 | 2527 | var digit = /[0-9]/; 2528 | 2529 | // Dot "." must be distinguished from "..." and decimal 2530 | var dot_pattern = /[^\d\.]/; 2531 | 2532 | var positionable_operators = ( 2533 | ">>> === !== " + 2534 | "<< && >= ** != == <= >> || ?? |> " + 2535 | "< / - + > : & % ? ^ | *").split(' '); 2536 | 2537 | // IMPORTANT: this must be sorted longest to shortest or tokenizing many not work. 2538 | // Also, you must update possitionable operators separately from punct 2539 | var punct = 2540 | ">>>= " + 2541 | "... >>= <<= === >>> !== **= " + 2542 | "=> ^= :: /= << <= == && -= >= >> != -- += ** || ?? ++ %= &= *= |= |> " + 2543 | "= ! ? > < : / ^ - + * & % ~ |"; 2544 | 2545 | punct = punct.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&"); 2546 | // ?. but not if followed by a number 2547 | punct = '\\?\\.(?!\\d) ' + punct; 2548 | punct = punct.replace(/ /g, '|'); 2549 | 2550 | var punct_pattern = new RegExp(punct); 2551 | 2552 | // words which should always start on new line. 2553 | var line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(','); 2554 | var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as']); 2555 | var reserved_word_pattern = new RegExp('^(?:' + reserved_words.join('|') + ')$'); 2556 | 2557 | // var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g; 2558 | 2559 | var in_html_comment; 2560 | 2561 | var Tokenizer = function(input_string, options) { 2562 | BaseTokenizer.call(this, input_string, options); 2563 | 2564 | this._patterns.whitespace = this._patterns.whitespace.matching( 2565 | /\u00A0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff/.source, 2566 | /\u2028\u2029/.source); 2567 | 2568 | var pattern_reader = new Pattern(this._input); 2569 | var templatable = new TemplatablePattern(this._input) 2570 | .read_options(this._options); 2571 | 2572 | this.__patterns = { 2573 | template: templatable, 2574 | identifier: templatable.starting_with(acorn.identifier).matching(acorn.identifierMatch), 2575 | number: pattern_reader.matching(number_pattern), 2576 | punct: pattern_reader.matching(punct_pattern), 2577 | // comment ends just before nearest linefeed or end of file 2578 | comment: pattern_reader.starting_with(/\/\//).until(/[\n\r\u2028\u2029]/), 2579 | // /* ... */ comment ends with nearest */ or end of file 2580 | block_comment: pattern_reader.starting_with(/\/\*/).until_after(/\*\//), 2581 | html_comment_start: pattern_reader.matching(//), 2583 | include: pattern_reader.starting_with(/#include/).until_after(acorn.lineBreak), 2584 | shebang: pattern_reader.starting_with(/#!/).until_after(acorn.lineBreak), 2585 | xml: pattern_reader.matching(/[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\]|)(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{[\s\S]+?}))*\s*(\/?)\s*>/), 2586 | single_quote: templatable.until(/['\\\n\r\u2028\u2029]/), 2587 | double_quote: templatable.until(/["\\\n\r\u2028\u2029]/), 2588 | template_text: templatable.until(/[`\\$]/), 2589 | template_expression: templatable.until(/[`}\\]/) 2590 | }; 2591 | 2592 | }; 2593 | Tokenizer.prototype = new BaseTokenizer(); 2594 | 2595 | Tokenizer.prototype._is_comment = function(current_token) { 2596 | return current_token.type === TOKEN.COMMENT || current_token.type === TOKEN.BLOCK_COMMENT || current_token.type === TOKEN.UNKNOWN; 2597 | }; 2598 | 2599 | Tokenizer.prototype._is_opening = function(current_token) { 2600 | return current_token.type === TOKEN.START_BLOCK || current_token.type === TOKEN.START_EXPR; 2601 | }; 2602 | 2603 | Tokenizer.prototype._is_closing = function(current_token, open_token) { 2604 | return (current_token.type === TOKEN.END_BLOCK || current_token.type === TOKEN.END_EXPR) && 2605 | (open_token && ( 2606 | (current_token.text === ']' && open_token.text === '[') || 2607 | (current_token.text === ')' && open_token.text === '(') || 2608 | (current_token.text === '}' && open_token.text === '{'))); 2609 | }; 2610 | 2611 | Tokenizer.prototype._reset = function() { 2612 | in_html_comment = false; 2613 | }; 2614 | 2615 | Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // jshint unused:false 2616 | var token = null; 2617 | this._readWhitespace(); 2618 | var c = this._input.peek(); 2619 | 2620 | if (c === null) { 2621 | return this._create_token(TOKEN.EOF, ''); 2622 | } 2623 | 2624 | token = token || this._read_non_javascript(c); 2625 | token = token || this._read_string(c); 2626 | token = token || this._read_word(previous_token); 2627 | token = token || this._read_singles(c); 2628 | token = token || this._read_comment(c); 2629 | token = token || this._read_regexp(c, previous_token); 2630 | token = token || this._read_xml(c, previous_token); 2631 | token = token || this._read_punctuation(); 2632 | token = token || this._create_token(TOKEN.UNKNOWN, this._input.next()); 2633 | 2634 | return token; 2635 | }; 2636 | 2637 | Tokenizer.prototype._read_word = function(previous_token) { 2638 | var resulting_string; 2639 | resulting_string = this.__patterns.identifier.read(); 2640 | if (resulting_string !== '') { 2641 | resulting_string = resulting_string.replace(acorn.allLineBreaks, '\n'); 2642 | if (!(previous_token.type === TOKEN.DOT || 2643 | (previous_token.type === TOKEN.RESERVED && (previous_token.text === 'set' || previous_token.text === 'get'))) && 2644 | reserved_word_pattern.test(resulting_string)) { 2645 | if (resulting_string === 'in' || resulting_string === 'of') { // hack for 'in' and 'of' operators 2646 | return this._create_token(TOKEN.OPERATOR, resulting_string); 2647 | } 2648 | return this._create_token(TOKEN.RESERVED, resulting_string); 2649 | } 2650 | return this._create_token(TOKEN.WORD, resulting_string); 2651 | } 2652 | 2653 | resulting_string = this.__patterns.number.read(); 2654 | if (resulting_string !== '') { 2655 | return this._create_token(TOKEN.WORD, resulting_string); 2656 | } 2657 | }; 2658 | 2659 | Tokenizer.prototype._read_singles = function(c) { 2660 | var token = null; 2661 | if (c === '(' || c === '[') { 2662 | token = this._create_token(TOKEN.START_EXPR, c); 2663 | } else if (c === ')' || c === ']') { 2664 | token = this._create_token(TOKEN.END_EXPR, c); 2665 | } else if (c === '{') { 2666 | token = this._create_token(TOKEN.START_BLOCK, c); 2667 | } else if (c === '}') { 2668 | token = this._create_token(TOKEN.END_BLOCK, c); 2669 | } else if (c === ';') { 2670 | token = this._create_token(TOKEN.SEMICOLON, c); 2671 | } else if (c === '.' && dot_pattern.test(this._input.peek(1))) { 2672 | token = this._create_token(TOKEN.DOT, c); 2673 | } else if (c === ',') { 2674 | token = this._create_token(TOKEN.COMMA, c); 2675 | } 2676 | 2677 | if (token) { 2678 | this._input.next(); 2679 | } 2680 | return token; 2681 | }; 2682 | 2683 | Tokenizer.prototype._read_punctuation = function() { 2684 | var resulting_string = this.__patterns.punct.read(); 2685 | 2686 | if (resulting_string !== '') { 2687 | if (resulting_string === '=') { 2688 | return this._create_token(TOKEN.EQUALS, resulting_string); 2689 | } else if (resulting_string === '?.') { 2690 | return this._create_token(TOKEN.DOT, resulting_string); 2691 | } else { 2692 | return this._create_token(TOKEN.OPERATOR, resulting_string); 2693 | } 2694 | } 2695 | }; 2696 | 2697 | Tokenizer.prototype._read_non_javascript = function(c) { 2698 | var resulting_string = ''; 2699 | 2700 | if (c === '#') { 2701 | if (this._is_first_token()) { 2702 | resulting_string = this.__patterns.shebang.read(); 2703 | 2704 | if (resulting_string) { 2705 | return this._create_token(TOKEN.UNKNOWN, resulting_string.trim() + '\n'); 2706 | } 2707 | } 2708 | 2709 | // handles extendscript #includes 2710 | resulting_string = this.__patterns.include.read(); 2711 | 2712 | if (resulting_string) { 2713 | return this._create_token(TOKEN.UNKNOWN, resulting_string.trim() + '\n'); 2714 | } 2715 | 2716 | c = this._input.next(); 2717 | 2718 | // Spidermonkey-specific sharp variables for circular references. Considered obsolete. 2719 | var sharp = '#'; 2720 | if (this._input.hasNext() && this._input.testChar(digit)) { 2721 | do { 2722 | c = this._input.next(); 2723 | sharp += c; 2724 | } while (this._input.hasNext() && c !== '#' && c !== '='); 2725 | if (c === '#') { 2726 | // 2727 | } else if (this._input.peek() === '[' && this._input.peek(1) === ']') { 2728 | sharp += '[]'; 2729 | this._input.next(); 2730 | this._input.next(); 2731 | } else if (this._input.peek() === '{' && this._input.peek(1) === '}') { 2732 | sharp += '{}'; 2733 | this._input.next(); 2734 | this._input.next(); 2735 | } 2736 | return this._create_token(TOKEN.WORD, sharp); 2737 | } 2738 | 2739 | this._input.back(); 2740 | 2741 | } else if (c === '<' && this._is_first_token()) { 2742 | resulting_string = this.__patterns.html_comment_start.read(); 2743 | if (resulting_string) { 2744 | while (this._input.hasNext() && !this._input.testChar(acorn.newline)) { 2745 | resulting_string += this._input.next(); 2746 | } 2747 | in_html_comment = true; 2748 | return this._create_token(TOKEN.COMMENT, resulting_string); 2749 | } 2750 | } else if (in_html_comment && c === '-') { 2751 | resulting_string = this.__patterns.html_comment_end.read(); 2752 | if (resulting_string) { 2753 | in_html_comment = false; 2754 | return this._create_token(TOKEN.COMMENT, resulting_string); 2755 | } 2756 | } 2757 | 2758 | return null; 2759 | }; 2760 | 2761 | Tokenizer.prototype._read_comment = function(c) { 2762 | var token = null; 2763 | if (c === '/') { 2764 | var comment = ''; 2765 | if (this._input.peek(1) === '*') { 2766 | // peek for comment /* ... */ 2767 | comment = this.__patterns.block_comment.read(); 2768 | var directives = directives_core.get_directives(comment); 2769 | if (directives && directives.ignore === 'start') { 2770 | comment += directives_core.readIgnored(this._input); 2771 | } 2772 | comment = comment.replace(acorn.allLineBreaks, '\n'); 2773 | token = this._create_token(TOKEN.BLOCK_COMMENT, comment); 2774 | token.directives = directives; 2775 | } else if (this._input.peek(1) === '/') { 2776 | // peek for comment // ... 2777 | comment = this.__patterns.comment.read(); 2778 | token = this._create_token(TOKEN.COMMENT, comment); 2779 | } 2780 | } 2781 | return token; 2782 | }; 2783 | 2784 | Tokenizer.prototype._read_string = function(c) { 2785 | if (c === '`' || c === "'" || c === '"') { 2786 | var resulting_string = this._input.next(); 2787 | this.has_char_escapes = false; 2788 | 2789 | if (c === '`') { 2790 | resulting_string += this._read_string_recursive('`', true, '${'); 2791 | } else { 2792 | resulting_string += this._read_string_recursive(c); 2793 | } 2794 | 2795 | if (this.has_char_escapes && this._options.unescape_strings) { 2796 | resulting_string = unescape_string(resulting_string); 2797 | } 2798 | 2799 | if (this._input.peek() === c) { 2800 | resulting_string += this._input.next(); 2801 | } 2802 | 2803 | resulting_string = resulting_string.replace(acorn.allLineBreaks, '\n'); 2804 | 2805 | return this._create_token(TOKEN.STRING, resulting_string); 2806 | } 2807 | 2808 | return null; 2809 | }; 2810 | 2811 | Tokenizer.prototype._allow_regexp_or_xml = function(previous_token) { 2812 | // regex and xml can only appear in specific locations during parsing 2813 | return (previous_token.type === TOKEN.RESERVED && in_array(previous_token.text, ['return', 'case', 'throw', 'else', 'do', 'typeof', 'yield'])) || 2814 | (previous_token.type === TOKEN.END_EXPR && previous_token.text === ')' && 2815 | previous_token.opened.previous.type === TOKEN.RESERVED && in_array(previous_token.opened.previous.text, ['if', 'while', 'for'])) || 2816 | (in_array(previous_token.type, [TOKEN.COMMENT, TOKEN.START_EXPR, TOKEN.START_BLOCK, TOKEN.START, 2817 | TOKEN.END_BLOCK, TOKEN.OPERATOR, TOKEN.EQUALS, TOKEN.EOF, TOKEN.SEMICOLON, TOKEN.COMMA 2818 | ])); 2819 | }; 2820 | 2821 | Tokenizer.prototype._read_regexp = function(c, previous_token) { 2822 | 2823 | if (c === '/' && this._allow_regexp_or_xml(previous_token)) { 2824 | // handle regexp 2825 | // 2826 | var resulting_string = this._input.next(); 2827 | var esc = false; 2828 | 2829 | var in_char_class = false; 2830 | while (this._input.hasNext() && 2831 | ((esc || in_char_class || this._input.peek() !== c) && 2832 | !this._input.testChar(acorn.newline))) { 2833 | resulting_string += this._input.peek(); 2834 | if (!esc) { 2835 | esc = this._input.peek() === '\\'; 2836 | if (this._input.peek() === '[') { 2837 | in_char_class = true; 2838 | } else if (this._input.peek() === ']') { 2839 | in_char_class = false; 2840 | } 2841 | } else { 2842 | esc = false; 2843 | } 2844 | this._input.next(); 2845 | } 2846 | 2847 | if (this._input.peek() === c) { 2848 | resulting_string += this._input.next(); 2849 | 2850 | // regexps may have modifiers /regexp/MOD , so fetch those, too 2851 | // Only [gim] are valid, but if the user puts in garbage, do what we can to take it. 2852 | resulting_string += this._input.read(acorn.identifier); 2853 | } 2854 | return this._create_token(TOKEN.STRING, resulting_string); 2855 | } 2856 | return null; 2857 | }; 2858 | 2859 | Tokenizer.prototype._read_xml = function(c, previous_token) { 2860 | 2861 | if (this._options.e4x && c === "<" && this._allow_regexp_or_xml(previous_token)) { 2862 | var xmlStr = ''; 2863 | var match = this.__patterns.xml.read_match(); 2864 | // handle e4x xml literals 2865 | // 2866 | if (match) { 2867 | // Trim root tag to attempt to 2868 | var rootTag = match[2].replace(/^{\s+/, '{').replace(/\s+}$/, '}'); 2869 | var isCurlyRoot = rootTag.indexOf('{') === 0; 2870 | var depth = 0; 2871 | while (match) { 2872 | var isEndTag = !!match[1]; 2873 | var tagName = match[2]; 2874 | var isSingletonTag = (!!match[match.length - 1]) || (tagName.slice(0, 8) === "![CDATA["); 2875 | if (!isSingletonTag && 2876 | (tagName === rootTag || (isCurlyRoot && tagName.replace(/^{\s+/, '{').replace(/\s+}$/, '}')))) { 2877 | if (isEndTag) { 2878 | --depth; 2879 | } else { 2880 | ++depth; 2881 | } 2882 | } 2883 | xmlStr += match[0]; 2884 | if (depth <= 0) { 2885 | break; 2886 | } 2887 | match = this.__patterns.xml.read_match(); 2888 | } 2889 | // if we didn't close correctly, keep unformatted. 2890 | if (!match) { 2891 | xmlStr += this._input.match(/[\s\S]*/g)[0]; 2892 | } 2893 | xmlStr = xmlStr.replace(acorn.allLineBreaks, '\n'); 2894 | return this._create_token(TOKEN.STRING, xmlStr); 2895 | } 2896 | } 2897 | 2898 | return null; 2899 | }; 2900 | 2901 | function unescape_string(s) { 2902 | // You think that a regex would work for this 2903 | // return s.replace(/\\x([0-9a-f]{2})/gi, function(match, val) { 2904 | // return String.fromCharCode(parseInt(val, 16)); 2905 | // }) 2906 | // However, dealing with '\xff', '\\xff', '\\\xff' makes this more fun. 2907 | var out = '', 2908 | escaped = 0; 2909 | 2910 | var input_scan = new InputScanner(s); 2911 | var matched = null; 2912 | 2913 | while (input_scan.hasNext()) { 2914 | // Keep any whitespace, non-slash characters 2915 | // also keep slash pairs. 2916 | matched = input_scan.match(/([\s]|[^\\]|\\\\)+/g); 2917 | 2918 | if (matched) { 2919 | out += matched[0]; 2920 | } 2921 | 2922 | if (input_scan.peek() === '\\') { 2923 | input_scan.next(); 2924 | if (input_scan.peek() === 'x') { 2925 | matched = input_scan.match(/x([0-9A-Fa-f]{2})/g); 2926 | } else if (input_scan.peek() === 'u') { 2927 | matched = input_scan.match(/u([0-9A-Fa-f]{4})/g); 2928 | } else { 2929 | out += '\\'; 2930 | if (input_scan.hasNext()) { 2931 | out += input_scan.next(); 2932 | } 2933 | continue; 2934 | } 2935 | 2936 | // If there's some error decoding, return the original string 2937 | if (!matched) { 2938 | return s; 2939 | } 2940 | 2941 | escaped = parseInt(matched[1], 16); 2942 | 2943 | if (escaped > 0x7e && escaped <= 0xff && matched[0].indexOf('x') === 0) { 2944 | // we bail out on \x7f..\xff, 2945 | // leaving whole string escaped, 2946 | // as it's probably completely binary 2947 | return s; 2948 | } else if (escaped >= 0x00 && escaped < 0x20) { 2949 | // leave 0x00...0x1f escaped 2950 | out += '\\' + matched[0]; 2951 | continue; 2952 | } else if (escaped === 0x22 || escaped === 0x27 || escaped === 0x5c) { 2953 | // single-quote, apostrophe, backslash - escape these 2954 | out += '\\' + String.fromCharCode(escaped); 2955 | } else { 2956 | out += String.fromCharCode(escaped); 2957 | } 2958 | } 2959 | } 2960 | 2961 | return out; 2962 | } 2963 | 2964 | // handle string 2965 | // 2966 | Tokenizer.prototype._read_string_recursive = function(delimiter, allow_unescaped_newlines, start_sub) { 2967 | var current_char; 2968 | var pattern; 2969 | if (delimiter === '\'') { 2970 | pattern = this.__patterns.single_quote; 2971 | } else if (delimiter === '"') { 2972 | pattern = this.__patterns.double_quote; 2973 | } else if (delimiter === '`') { 2974 | pattern = this.__patterns.template_text; 2975 | } else if (delimiter === '}') { 2976 | pattern = this.__patterns.template_expression; 2977 | } 2978 | 2979 | var resulting_string = pattern.read(); 2980 | var next = ''; 2981 | while (this._input.hasNext()) { 2982 | next = this._input.next(); 2983 | if (next === delimiter || 2984 | (!allow_unescaped_newlines && acorn.newline.test(next))) { 2985 | this._input.back(); 2986 | break; 2987 | } else if (next === '\\' && this._input.hasNext()) { 2988 | current_char = this._input.peek(); 2989 | 2990 | if (current_char === 'x' || current_char === 'u') { 2991 | this.has_char_escapes = true; 2992 | } else if (current_char === '\r' && this._input.peek(1) === '\n') { 2993 | this._input.next(); 2994 | } 2995 | next += this._input.next(); 2996 | } else if (start_sub) { 2997 | if (start_sub === '${' && next === '$' && this._input.peek() === '{') { 2998 | next += this._input.next(); 2999 | } 3000 | 3001 | if (start_sub === next) { 3002 | if (delimiter === '`') { 3003 | next += this._read_string_recursive('}', allow_unescaped_newlines, '`'); 3004 | } else { 3005 | next += this._read_string_recursive('`', allow_unescaped_newlines, '${'); 3006 | } 3007 | if (this._input.hasNext()) { 3008 | next += this._input.next(); 3009 | } 3010 | } 3011 | } 3012 | next += pattern.read(); 3013 | resulting_string += next; 3014 | } 3015 | 3016 | return resulting_string; 3017 | }; 3018 | 3019 | module.exports.Tokenizer = Tokenizer; 3020 | module.exports.TOKEN = TOKEN; 3021 | module.exports.positionable_operators = positionable_operators.slice(); 3022 | module.exports.line_starters = line_starters.slice(); 3023 | 3024 | 3025 | /***/ }), 3026 | /* 8 */ 3027 | /***/ (function(module) { 3028 | 3029 | /*jshint node:true */ 3030 | /* 3031 | 3032 | The MIT License (MIT) 3033 | 3034 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 3035 | 3036 | Permission is hereby granted, free of charge, to any person 3037 | obtaining a copy of this software and associated documentation files 3038 | (the "Software"), to deal in the Software without restriction, 3039 | including without limitation the rights to use, copy, modify, merge, 3040 | publish, distribute, sublicense, and/or sell copies of the Software, 3041 | and to permit persons to whom the Software is furnished to do so, 3042 | subject to the following conditions: 3043 | 3044 | The above copyright notice and this permission notice shall be 3045 | included in all copies or substantial portions of the Software. 3046 | 3047 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 3048 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3049 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 3050 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 3051 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3052 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3053 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3054 | SOFTWARE. 3055 | */ 3056 | 3057 | 3058 | 3059 | var regexp_has_sticky = RegExp.prototype.hasOwnProperty('sticky'); 3060 | 3061 | function InputScanner(input_string) { 3062 | this.__input = input_string || ''; 3063 | this.__input_length = this.__input.length; 3064 | this.__position = 0; 3065 | } 3066 | 3067 | InputScanner.prototype.restart = function() { 3068 | this.__position = 0; 3069 | }; 3070 | 3071 | InputScanner.prototype.back = function() { 3072 | if (this.__position > 0) { 3073 | this.__position -= 1; 3074 | } 3075 | }; 3076 | 3077 | InputScanner.prototype.hasNext = function() { 3078 | return this.__position < this.__input_length; 3079 | }; 3080 | 3081 | InputScanner.prototype.next = function() { 3082 | var val = null; 3083 | if (this.hasNext()) { 3084 | val = this.__input.charAt(this.__position); 3085 | this.__position += 1; 3086 | } 3087 | return val; 3088 | }; 3089 | 3090 | InputScanner.prototype.peek = function(index) { 3091 | var val = null; 3092 | index = index || 0; 3093 | index += this.__position; 3094 | if (index >= 0 && index < this.__input_length) { 3095 | val = this.__input.charAt(index); 3096 | } 3097 | return val; 3098 | }; 3099 | 3100 | // This is a JavaScript only helper function (not in python) 3101 | // Javascript doesn't have a match method 3102 | // and not all implementation support "sticky" flag. 3103 | // If they do not support sticky then both this.match() and this.test() method 3104 | // must get the match and check the index of the match. 3105 | // If sticky is supported and set, this method will use it. 3106 | // Otherwise it will check that global is set, and fall back to the slower method. 3107 | InputScanner.prototype.__match = function(pattern, index) { 3108 | pattern.lastIndex = index; 3109 | var pattern_match = pattern.exec(this.__input); 3110 | 3111 | if (pattern_match && !(regexp_has_sticky && pattern.sticky)) { 3112 | if (pattern_match.index !== index) { 3113 | pattern_match = null; 3114 | } 3115 | } 3116 | 3117 | return pattern_match; 3118 | }; 3119 | 3120 | InputScanner.prototype.test = function(pattern, index) { 3121 | index = index || 0; 3122 | index += this.__position; 3123 | 3124 | if (index >= 0 && index < this.__input_length) { 3125 | return !!this.__match(pattern, index); 3126 | } else { 3127 | return false; 3128 | } 3129 | }; 3130 | 3131 | InputScanner.prototype.testChar = function(pattern, index) { 3132 | // test one character regex match 3133 | var val = this.peek(index); 3134 | pattern.lastIndex = 0; 3135 | return val !== null && pattern.test(val); 3136 | }; 3137 | 3138 | InputScanner.prototype.match = function(pattern) { 3139 | var pattern_match = this.__match(pattern, this.__position); 3140 | if (pattern_match) { 3141 | this.__position += pattern_match[0].length; 3142 | } else { 3143 | pattern_match = null; 3144 | } 3145 | return pattern_match; 3146 | }; 3147 | 3148 | InputScanner.prototype.read = function(starting_pattern, until_pattern, until_after) { 3149 | var val = ''; 3150 | var match; 3151 | if (starting_pattern) { 3152 | match = this.match(starting_pattern); 3153 | if (match) { 3154 | val += match[0]; 3155 | } 3156 | } 3157 | if (until_pattern && (match || !starting_pattern)) { 3158 | val += this.readUntil(until_pattern, until_after); 3159 | } 3160 | return val; 3161 | }; 3162 | 3163 | InputScanner.prototype.readUntil = function(pattern, until_after) { 3164 | var val = ''; 3165 | var match_index = this.__position; 3166 | pattern.lastIndex = this.__position; 3167 | var pattern_match = pattern.exec(this.__input); 3168 | if (pattern_match) { 3169 | match_index = pattern_match.index; 3170 | if (until_after) { 3171 | match_index += pattern_match[0].length; 3172 | } 3173 | } else { 3174 | match_index = this.__input_length; 3175 | } 3176 | 3177 | val = this.__input.substring(this.__position, match_index); 3178 | this.__position = match_index; 3179 | return val; 3180 | }; 3181 | 3182 | InputScanner.prototype.readUntilAfter = function(pattern) { 3183 | return this.readUntil(pattern, true); 3184 | }; 3185 | 3186 | InputScanner.prototype.get_regexp = function(pattern, match_from) { 3187 | var result = null; 3188 | var flags = 'g'; 3189 | if (match_from && regexp_has_sticky) { 3190 | flags = 'y'; 3191 | } 3192 | // strings are converted to regexp 3193 | if (typeof pattern === "string" && pattern !== '') { 3194 | // result = new RegExp(pattern.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), flags); 3195 | result = new RegExp(pattern, flags); 3196 | } else if (pattern) { 3197 | result = new RegExp(pattern.source, flags); 3198 | } 3199 | return result; 3200 | }; 3201 | 3202 | InputScanner.prototype.get_literal_regexp = function(literal_string) { 3203 | return RegExp(literal_string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')); 3204 | }; 3205 | 3206 | /* css beautifier legacy helpers */ 3207 | InputScanner.prototype.peekUntilAfter = function(pattern) { 3208 | var start = this.__position; 3209 | var val = this.readUntilAfter(pattern); 3210 | this.__position = start; 3211 | return val; 3212 | }; 3213 | 3214 | InputScanner.prototype.lookBack = function(testVal) { 3215 | var start = this.__position - 1; 3216 | return start >= testVal.length && this.__input.substring(start - testVal.length, start) 3217 | .toLowerCase() === testVal; 3218 | }; 3219 | 3220 | module.exports.InputScanner = InputScanner; 3221 | 3222 | 3223 | /***/ }), 3224 | /* 9 */ 3225 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 3226 | 3227 | /*jshint node:true */ 3228 | /* 3229 | 3230 | The MIT License (MIT) 3231 | 3232 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 3233 | 3234 | Permission is hereby granted, free of charge, to any person 3235 | obtaining a copy of this software and associated documentation files 3236 | (the "Software"), to deal in the Software without restriction, 3237 | including without limitation the rights to use, copy, modify, merge, 3238 | publish, distribute, sublicense, and/or sell copies of the Software, 3239 | and to permit persons to whom the Software is furnished to do so, 3240 | subject to the following conditions: 3241 | 3242 | The above copyright notice and this permission notice shall be 3243 | included in all copies or substantial portions of the Software. 3244 | 3245 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 3246 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3247 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 3248 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 3249 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3250 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3251 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3252 | SOFTWARE. 3253 | */ 3254 | 3255 | 3256 | 3257 | var InputScanner = __webpack_require__(8).InputScanner; 3258 | var Token = __webpack_require__(3).Token; 3259 | var TokenStream = __webpack_require__(10).TokenStream; 3260 | var WhitespacePattern = __webpack_require__(11).WhitespacePattern; 3261 | 3262 | var TOKEN = { 3263 | START: 'TK_START', 3264 | RAW: 'TK_RAW', 3265 | EOF: 'TK_EOF' 3266 | }; 3267 | 3268 | var Tokenizer = function(input_string, options) { 3269 | this._input = new InputScanner(input_string); 3270 | this._options = options || {}; 3271 | this.__tokens = null; 3272 | 3273 | this._patterns = {}; 3274 | this._patterns.whitespace = new WhitespacePattern(this._input); 3275 | }; 3276 | 3277 | Tokenizer.prototype.tokenize = function() { 3278 | this._input.restart(); 3279 | this.__tokens = new TokenStream(); 3280 | 3281 | this._reset(); 3282 | 3283 | var current; 3284 | var previous = new Token(TOKEN.START, ''); 3285 | var open_token = null; 3286 | var open_stack = []; 3287 | var comments = new TokenStream(); 3288 | 3289 | while (previous.type !== TOKEN.EOF) { 3290 | current = this._get_next_token(previous, open_token); 3291 | while (this._is_comment(current)) { 3292 | comments.add(current); 3293 | current = this._get_next_token(previous, open_token); 3294 | } 3295 | 3296 | if (!comments.isEmpty()) { 3297 | current.comments_before = comments; 3298 | comments = new TokenStream(); 3299 | } 3300 | 3301 | current.parent = open_token; 3302 | 3303 | if (this._is_opening(current)) { 3304 | open_stack.push(open_token); 3305 | open_token = current; 3306 | } else if (open_token && this._is_closing(current, open_token)) { 3307 | current.opened = open_token; 3308 | open_token.closed = current; 3309 | open_token = open_stack.pop(); 3310 | current.parent = open_token; 3311 | } 3312 | 3313 | current.previous = previous; 3314 | previous.next = current; 3315 | 3316 | this.__tokens.add(current); 3317 | previous = current; 3318 | } 3319 | 3320 | return this.__tokens; 3321 | }; 3322 | 3323 | 3324 | Tokenizer.prototype._is_first_token = function() { 3325 | return this.__tokens.isEmpty(); 3326 | }; 3327 | 3328 | Tokenizer.prototype._reset = function() {}; 3329 | 3330 | Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // jshint unused:false 3331 | this._readWhitespace(); 3332 | var resulting_string = this._input.read(/.+/g); 3333 | if (resulting_string) { 3334 | return this._create_token(TOKEN.RAW, resulting_string); 3335 | } else { 3336 | return this._create_token(TOKEN.EOF, ''); 3337 | } 3338 | }; 3339 | 3340 | Tokenizer.prototype._is_comment = function(current_token) { // jshint unused:false 3341 | return false; 3342 | }; 3343 | 3344 | Tokenizer.prototype._is_opening = function(current_token) { // jshint unused:false 3345 | return false; 3346 | }; 3347 | 3348 | Tokenizer.prototype._is_closing = function(current_token, open_token) { // jshint unused:false 3349 | return false; 3350 | }; 3351 | 3352 | Tokenizer.prototype._create_token = function(type, text) { 3353 | var token = new Token(type, text, 3354 | this._patterns.whitespace.newline_count, 3355 | this._patterns.whitespace.whitespace_before_token); 3356 | return token; 3357 | }; 3358 | 3359 | Tokenizer.prototype._readWhitespace = function() { 3360 | return this._patterns.whitespace.read(); 3361 | }; 3362 | 3363 | 3364 | 3365 | module.exports.Tokenizer = Tokenizer; 3366 | module.exports.TOKEN = TOKEN; 3367 | 3368 | 3369 | /***/ }), 3370 | /* 10 */ 3371 | /***/ (function(module) { 3372 | 3373 | /*jshint node:true */ 3374 | /* 3375 | 3376 | The MIT License (MIT) 3377 | 3378 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 3379 | 3380 | Permission is hereby granted, free of charge, to any person 3381 | obtaining a copy of this software and associated documentation files 3382 | (the "Software"), to deal in the Software without restriction, 3383 | including without limitation the rights to use, copy, modify, merge, 3384 | publish, distribute, sublicense, and/or sell copies of the Software, 3385 | and to permit persons to whom the Software is furnished to do so, 3386 | subject to the following conditions: 3387 | 3388 | The above copyright notice and this permission notice shall be 3389 | included in all copies or substantial portions of the Software. 3390 | 3391 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 3392 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3393 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 3394 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 3395 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3396 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3397 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3398 | SOFTWARE. 3399 | */ 3400 | 3401 | 3402 | 3403 | function TokenStream(parent_token) { 3404 | // private 3405 | this.__tokens = []; 3406 | this.__tokens_length = this.__tokens.length; 3407 | this.__position = 0; 3408 | this.__parent_token = parent_token; 3409 | } 3410 | 3411 | TokenStream.prototype.restart = function() { 3412 | this.__position = 0; 3413 | }; 3414 | 3415 | TokenStream.prototype.isEmpty = function() { 3416 | return this.__tokens_length === 0; 3417 | }; 3418 | 3419 | TokenStream.prototype.hasNext = function() { 3420 | return this.__position < this.__tokens_length; 3421 | }; 3422 | 3423 | TokenStream.prototype.next = function() { 3424 | var val = null; 3425 | if (this.hasNext()) { 3426 | val = this.__tokens[this.__position]; 3427 | this.__position += 1; 3428 | } 3429 | return val; 3430 | }; 3431 | 3432 | TokenStream.prototype.peek = function(index) { 3433 | var val = null; 3434 | index = index || 0; 3435 | index += this.__position; 3436 | if (index >= 0 && index < this.__tokens_length) { 3437 | val = this.__tokens[index]; 3438 | } 3439 | return val; 3440 | }; 3441 | 3442 | TokenStream.prototype.add = function(token) { 3443 | if (this.__parent_token) { 3444 | token.parent = this.__parent_token; 3445 | } 3446 | this.__tokens.push(token); 3447 | this.__tokens_length += 1; 3448 | }; 3449 | 3450 | module.exports.TokenStream = TokenStream; 3451 | 3452 | 3453 | /***/ }), 3454 | /* 11 */ 3455 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 3456 | 3457 | /*jshint node:true */ 3458 | /* 3459 | 3460 | The MIT License (MIT) 3461 | 3462 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 3463 | 3464 | Permission is hereby granted, free of charge, to any person 3465 | obtaining a copy of this software and associated documentation files 3466 | (the "Software"), to deal in the Software without restriction, 3467 | including without limitation the rights to use, copy, modify, merge, 3468 | publish, distribute, sublicense, and/or sell copies of the Software, 3469 | and to permit persons to whom the Software is furnished to do so, 3470 | subject to the following conditions: 3471 | 3472 | The above copyright notice and this permission notice shall be 3473 | included in all copies or substantial portions of the Software. 3474 | 3475 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 3476 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3477 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 3478 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 3479 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3480 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3481 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3482 | SOFTWARE. 3483 | */ 3484 | 3485 | 3486 | 3487 | var Pattern = __webpack_require__(12).Pattern; 3488 | 3489 | function WhitespacePattern(input_scanner, parent) { 3490 | Pattern.call(this, input_scanner, parent); 3491 | if (parent) { 3492 | this._line_regexp = this._input.get_regexp(parent._line_regexp); 3493 | } else { 3494 | this.__set_whitespace_patterns('', ''); 3495 | } 3496 | 3497 | this.newline_count = 0; 3498 | this.whitespace_before_token = ''; 3499 | } 3500 | WhitespacePattern.prototype = new Pattern(); 3501 | 3502 | WhitespacePattern.prototype.__set_whitespace_patterns = function(whitespace_chars, newline_chars) { 3503 | whitespace_chars += '\\t '; 3504 | newline_chars += '\\n\\r'; 3505 | 3506 | this._match_pattern = this._input.get_regexp( 3507 | '[' + whitespace_chars + newline_chars + ']+', true); 3508 | this._newline_regexp = this._input.get_regexp( 3509 | '\\r\\n|[' + newline_chars + ']'); 3510 | }; 3511 | 3512 | WhitespacePattern.prototype.read = function() { 3513 | this.newline_count = 0; 3514 | this.whitespace_before_token = ''; 3515 | 3516 | var resulting_string = this._input.read(this._match_pattern); 3517 | if (resulting_string === ' ') { 3518 | this.whitespace_before_token = ' '; 3519 | } else if (resulting_string) { 3520 | var matches = this.__split(this._newline_regexp, resulting_string); 3521 | this.newline_count = matches.length - 1; 3522 | this.whitespace_before_token = matches[this.newline_count]; 3523 | } 3524 | 3525 | return resulting_string; 3526 | }; 3527 | 3528 | WhitespacePattern.prototype.matching = function(whitespace_chars, newline_chars) { 3529 | var result = this._create(); 3530 | result.__set_whitespace_patterns(whitespace_chars, newline_chars); 3531 | result._update(); 3532 | return result; 3533 | }; 3534 | 3535 | WhitespacePattern.prototype._create = function() { 3536 | return new WhitespacePattern(this._input, this); 3537 | }; 3538 | 3539 | WhitespacePattern.prototype.__split = function(regexp, input_string) { 3540 | regexp.lastIndex = 0; 3541 | var start_index = 0; 3542 | var result = []; 3543 | var next_match = regexp.exec(input_string); 3544 | while (next_match) { 3545 | result.push(input_string.substring(start_index, next_match.index)); 3546 | start_index = next_match.index + next_match[0].length; 3547 | next_match = regexp.exec(input_string); 3548 | } 3549 | 3550 | if (start_index < input_string.length) { 3551 | result.push(input_string.substring(start_index, input_string.length)); 3552 | } else { 3553 | result.push(''); 3554 | } 3555 | 3556 | return result; 3557 | }; 3558 | 3559 | 3560 | 3561 | module.exports.WhitespacePattern = WhitespacePattern; 3562 | 3563 | 3564 | /***/ }), 3565 | /* 12 */ 3566 | /***/ (function(module) { 3567 | 3568 | /*jshint node:true */ 3569 | /* 3570 | 3571 | The MIT License (MIT) 3572 | 3573 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 3574 | 3575 | Permission is hereby granted, free of charge, to any person 3576 | obtaining a copy of this software and associated documentation files 3577 | (the "Software"), to deal in the Software without restriction, 3578 | including without limitation the rights to use, copy, modify, merge, 3579 | publish, distribute, sublicense, and/or sell copies of the Software, 3580 | and to permit persons to whom the Software is furnished to do so, 3581 | subject to the following conditions: 3582 | 3583 | The above copyright notice and this permission notice shall be 3584 | included in all copies or substantial portions of the Software. 3585 | 3586 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 3587 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3588 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 3589 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 3590 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3591 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3592 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3593 | SOFTWARE. 3594 | */ 3595 | 3596 | 3597 | 3598 | function Pattern(input_scanner, parent) { 3599 | this._input = input_scanner; 3600 | this._starting_pattern = null; 3601 | this._match_pattern = null; 3602 | this._until_pattern = null; 3603 | this._until_after = false; 3604 | 3605 | if (parent) { 3606 | this._starting_pattern = this._input.get_regexp(parent._starting_pattern, true); 3607 | this._match_pattern = this._input.get_regexp(parent._match_pattern, true); 3608 | this._until_pattern = this._input.get_regexp(parent._until_pattern); 3609 | this._until_after = parent._until_after; 3610 | } 3611 | } 3612 | 3613 | Pattern.prototype.read = function() { 3614 | var result = this._input.read(this._starting_pattern); 3615 | if (!this._starting_pattern || result) { 3616 | result += this._input.read(this._match_pattern, this._until_pattern, this._until_after); 3617 | } 3618 | return result; 3619 | }; 3620 | 3621 | Pattern.prototype.read_match = function() { 3622 | return this._input.match(this._match_pattern); 3623 | }; 3624 | 3625 | Pattern.prototype.until_after = function(pattern) { 3626 | var result = this._create(); 3627 | result._until_after = true; 3628 | result._until_pattern = this._input.get_regexp(pattern); 3629 | result._update(); 3630 | return result; 3631 | }; 3632 | 3633 | Pattern.prototype.until = function(pattern) { 3634 | var result = this._create(); 3635 | result._until_after = false; 3636 | result._until_pattern = this._input.get_regexp(pattern); 3637 | result._update(); 3638 | return result; 3639 | }; 3640 | 3641 | Pattern.prototype.starting_with = function(pattern) { 3642 | var result = this._create(); 3643 | result._starting_pattern = this._input.get_regexp(pattern, true); 3644 | result._update(); 3645 | return result; 3646 | }; 3647 | 3648 | Pattern.prototype.matching = function(pattern) { 3649 | var result = this._create(); 3650 | result._match_pattern = this._input.get_regexp(pattern, true); 3651 | result._update(); 3652 | return result; 3653 | }; 3654 | 3655 | Pattern.prototype._create = function() { 3656 | return new Pattern(this._input, this); 3657 | }; 3658 | 3659 | Pattern.prototype._update = function() {}; 3660 | 3661 | module.exports.Pattern = Pattern; 3662 | 3663 | 3664 | /***/ }), 3665 | /* 13 */ 3666 | /***/ (function(module) { 3667 | 3668 | /*jshint node:true */ 3669 | /* 3670 | 3671 | The MIT License (MIT) 3672 | 3673 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 3674 | 3675 | Permission is hereby granted, free of charge, to any person 3676 | obtaining a copy of this software and associated documentation files 3677 | (the "Software"), to deal in the Software without restriction, 3678 | including without limitation the rights to use, copy, modify, merge, 3679 | publish, distribute, sublicense, and/or sell copies of the Software, 3680 | and to permit persons to whom the Software is furnished to do so, 3681 | subject to the following conditions: 3682 | 3683 | The above copyright notice and this permission notice shall be 3684 | included in all copies or substantial portions of the Software. 3685 | 3686 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 3687 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3688 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 3689 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 3690 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3691 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3692 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3693 | SOFTWARE. 3694 | */ 3695 | 3696 | 3697 | 3698 | function Directives(start_block_pattern, end_block_pattern) { 3699 | start_block_pattern = typeof start_block_pattern === 'string' ? start_block_pattern : start_block_pattern.source; 3700 | end_block_pattern = typeof end_block_pattern === 'string' ? end_block_pattern : end_block_pattern.source; 3701 | this.__directives_block_pattern = new RegExp(start_block_pattern + / beautify( \w+[:]\w+)+ /.source + end_block_pattern, 'g'); 3702 | this.__directive_pattern = / (\w+)[:](\w+)/g; 3703 | 3704 | this.__directives_end_ignore_pattern = new RegExp(start_block_pattern + /\sbeautify\signore:end\s/.source + end_block_pattern, 'g'); 3705 | } 3706 | 3707 | Directives.prototype.get_directives = function(text) { 3708 | if (!text.match(this.__directives_block_pattern)) { 3709 | return null; 3710 | } 3711 | 3712 | var directives = {}; 3713 | this.__directive_pattern.lastIndex = 0; 3714 | var directive_match = this.__directive_pattern.exec(text); 3715 | 3716 | while (directive_match) { 3717 | directives[directive_match[1]] = directive_match[2]; 3718 | directive_match = this.__directive_pattern.exec(text); 3719 | } 3720 | 3721 | return directives; 3722 | }; 3723 | 3724 | Directives.prototype.readIgnored = function(input) { 3725 | return input.readUntilAfter(this.__directives_end_ignore_pattern); 3726 | }; 3727 | 3728 | 3729 | module.exports.Directives = Directives; 3730 | 3731 | 3732 | /***/ }), 3733 | /* 14 */ 3734 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 3735 | 3736 | /*jshint node:true */ 3737 | /* 3738 | 3739 | The MIT License (MIT) 3740 | 3741 | Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 3742 | 3743 | Permission is hereby granted, free of charge, to any person 3744 | obtaining a copy of this software and associated documentation files 3745 | (the "Software"), to deal in the Software without restriction, 3746 | including without limitation the rights to use, copy, modify, merge, 3747 | publish, distribute, sublicense, and/or sell copies of the Software, 3748 | and to permit persons to whom the Software is furnished to do so, 3749 | subject to the following conditions: 3750 | 3751 | The above copyright notice and this permission notice shall be 3752 | included in all copies or substantial portions of the Software. 3753 | 3754 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 3755 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3756 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 3757 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 3758 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3759 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3760 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3761 | SOFTWARE. 3762 | */ 3763 | 3764 | 3765 | 3766 | var Pattern = __webpack_require__(12).Pattern; 3767 | 3768 | 3769 | var template_names = { 3770 | django: false, 3771 | erb: false, 3772 | handlebars: false, 3773 | php: false, 3774 | smarty: false 3775 | }; 3776 | 3777 | // This lets templates appear anywhere we would do a readUntil 3778 | // The cost is higher but it is pay to play. 3779 | function TemplatablePattern(input_scanner, parent) { 3780 | Pattern.call(this, input_scanner, parent); 3781 | this.__template_pattern = null; 3782 | this._disabled = Object.assign({}, template_names); 3783 | this._excluded = Object.assign({}, template_names); 3784 | 3785 | if (parent) { 3786 | this.__template_pattern = this._input.get_regexp(parent.__template_pattern); 3787 | this._excluded = Object.assign(this._excluded, parent._excluded); 3788 | this._disabled = Object.assign(this._disabled, parent._disabled); 3789 | } 3790 | var pattern = new Pattern(input_scanner); 3791 | this.__patterns = { 3792 | handlebars_comment: pattern.starting_with(/{{!--/).until_after(/--}}/), 3793 | handlebars_unescaped: pattern.starting_with(/{{{/).until_after(/}}}/), 3794 | handlebars: pattern.starting_with(/{{/).until_after(/}}/), 3795 | php: pattern.starting_with(/<\?(?:[= ]|php)/).until_after(/\?>/), 3796 | erb: pattern.starting_with(/<%[^%]/).until_after(/[^%]%>/), 3797 | // django coflicts with handlebars a bit. 3798 | django: pattern.starting_with(/{%/).until_after(/%}/), 3799 | django_value: pattern.starting_with(/{{/).until_after(/}}/), 3800 | django_comment: pattern.starting_with(/{#/).until_after(/#}/), 3801 | smarty: pattern.starting_with(/{(?=[^}{\s\n])/).until_after(/[^\s\n]}/), 3802 | smarty_comment: pattern.starting_with(/{\*/).until_after(/\*}/), 3803 | smarty_literal: pattern.starting_with(/{literal}/).until_after(/{\/literal}/) 3804 | }; 3805 | } 3806 | TemplatablePattern.prototype = new Pattern(); 3807 | 3808 | TemplatablePattern.prototype._create = function() { 3809 | return new TemplatablePattern(this._input, this); 3810 | }; 3811 | 3812 | TemplatablePattern.prototype._update = function() { 3813 | this.__set_templated_pattern(); 3814 | }; 3815 | 3816 | TemplatablePattern.prototype.disable = function(language) { 3817 | var result = this._create(); 3818 | result._disabled[language] = true; 3819 | result._update(); 3820 | return result; 3821 | }; 3822 | 3823 | TemplatablePattern.prototype.read_options = function(options) { 3824 | var result = this._create(); 3825 | for (var language in template_names) { 3826 | result._disabled[language] = options.templating.indexOf(language) === -1; 3827 | } 3828 | result._update(); 3829 | return result; 3830 | }; 3831 | 3832 | TemplatablePattern.prototype.exclude = function(language) { 3833 | var result = this._create(); 3834 | result._excluded[language] = true; 3835 | result._update(); 3836 | return result; 3837 | }; 3838 | 3839 | TemplatablePattern.prototype.read = function() { 3840 | var result = ''; 3841 | if (this._match_pattern) { 3842 | result = this._input.read(this._starting_pattern); 3843 | } else { 3844 | result = this._input.read(this._starting_pattern, this.__template_pattern); 3845 | } 3846 | var next = this._read_template(); 3847 | while (next) { 3848 | if (this._match_pattern) { 3849 | next += this._input.read(this._match_pattern); 3850 | } else { 3851 | next += this._input.readUntil(this.__template_pattern); 3852 | } 3853 | result += next; 3854 | next = this._read_template(); 3855 | } 3856 | 3857 | if (this._until_after) { 3858 | result += this._input.readUntilAfter(this._until_pattern); 3859 | } 3860 | return result; 3861 | }; 3862 | 3863 | TemplatablePattern.prototype.__set_templated_pattern = function() { 3864 | var items = []; 3865 | 3866 | if (!this._disabled.php) { 3867 | items.push(this.__patterns.php._starting_pattern.source); 3868 | } 3869 | if (!this._disabled.handlebars) { 3870 | items.push(this.__patterns.handlebars._starting_pattern.source); 3871 | } 3872 | if (!this._disabled.erb) { 3873 | items.push(this.__patterns.erb._starting_pattern.source); 3874 | } 3875 | if (!this._disabled.django) { 3876 | items.push(this.__patterns.django._starting_pattern.source); 3877 | // The starting pattern for django is more complex because it has different 3878 | // patterns for value, comment, and other sections 3879 | items.push(this.__patterns.django_value._starting_pattern.source); 3880 | items.push(this.__patterns.django_comment._starting_pattern.source); 3881 | } 3882 | if (!this._disabled.smarty) { 3883 | items.push(this.__patterns.smarty._starting_pattern.source); 3884 | } 3885 | 3886 | if (this._until_pattern) { 3887 | items.push(this._until_pattern.source); 3888 | } 3889 | this.__template_pattern = this._input.get_regexp('(?:' + items.join('|') + ')'); 3890 | }; 3891 | 3892 | TemplatablePattern.prototype._read_template = function() { 3893 | var resulting_string = ''; 3894 | var c = this._input.peek(); 3895 | if (c === '<') { 3896 | var peek1 = this._input.peek(1); 3897 | //if we're in a comment, do something special 3898 | // We treat all comments as literals, even more than preformatted tags 3899 | // we just look for the appropriate close tag 3900 | if (!this._disabled.php && !this._excluded.php && peek1 === '?') { 3901 | resulting_string = resulting_string || 3902 | this.__patterns.php.read(); 3903 | } 3904 | if (!this._disabled.erb && !this._excluded.erb && peek1 === '%') { 3905 | resulting_string = resulting_string || 3906 | this.__patterns.erb.read(); 3907 | } 3908 | } else if (c === '{') { 3909 | if (!this._disabled.handlebars && !this._excluded.handlebars) { 3910 | resulting_string = resulting_string || 3911 | this.__patterns.handlebars_comment.read(); 3912 | resulting_string = resulting_string || 3913 | this.__patterns.handlebars_unescaped.read(); 3914 | resulting_string = resulting_string || 3915 | this.__patterns.handlebars.read(); 3916 | } 3917 | if (!this._disabled.django) { 3918 | // django coflicts with handlebars a bit. 3919 | if (!this._excluded.django && !this._excluded.handlebars) { 3920 | resulting_string = resulting_string || 3921 | this.__patterns.django_value.read(); 3922 | } 3923 | if (!this._excluded.django) { 3924 | resulting_string = resulting_string || 3925 | this.__patterns.django_comment.read(); 3926 | resulting_string = resulting_string || 3927 | this.__patterns.django.read(); 3928 | } 3929 | } 3930 | if (!this._disabled.smarty) { 3931 | // smarty cannot be enabled with django or handlebars enabled 3932 | if (this._disabled.django && this._disabled.handlebars) { 3933 | resulting_string = resulting_string || 3934 | this.__patterns.smarty_comment.read(); 3935 | resulting_string = resulting_string || 3936 | this.__patterns.smarty_literal.read(); 3937 | resulting_string = resulting_string || 3938 | this.__patterns.smarty.read(); 3939 | } 3940 | } 3941 | } 3942 | return resulting_string; 3943 | }; 3944 | 3945 | 3946 | module.exports.TemplatablePattern = TemplatablePattern; 3947 | 3948 | 3949 | /***/ }) 3950 | /******/ ]); 3951 | /************************************************************************/ 3952 | /******/ // The module cache 3953 | /******/ var __webpack_module_cache__ = {}; 3954 | /******/ 3955 | /******/ // The require function 3956 | /******/ function __webpack_require__(moduleId) { 3957 | /******/ // Check if module is in cache 3958 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 3959 | /******/ if (cachedModule !== undefined) { 3960 | /******/ return cachedModule.exports; 3961 | /******/ } 3962 | /******/ // Create a new module (and put it into the cache) 3963 | /******/ var module = __webpack_module_cache__[moduleId] = { 3964 | /******/ // no module.id needed 3965 | /******/ // no module.loaded needed 3966 | /******/ exports: {} 3967 | /******/ }; 3968 | /******/ 3969 | /******/ // Execute the module function 3970 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 3971 | /******/ 3972 | /******/ // Return the exports of the module 3973 | /******/ return module.exports; 3974 | /******/ } 3975 | /******/ 3976 | /************************************************************************/ 3977 | /******/ 3978 | /******/ // startup 3979 | /******/ // Load entry module and return exports 3980 | /******/ // This entry module is referenced by other modules so it can't be inlined 3981 | /******/ var __webpack_exports__ = __webpack_require__(0); 3982 | /******/ legacy_beautify_js = __webpack_exports__; 3983 | /******/ 3984 | /******/ })() 3985 | ; 3986 | var js_beautify = legacy_beautify_js; 3987 | /* Footer */ 3988 | if (typeof define === "function" && define.amd) { 3989 | // Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- ) 3990 | define([], function() { 3991 | return { js_beautify: js_beautify }; 3992 | }); 3993 | } else if (typeof exports !== "undefined") { 3994 | // Add support for CommonJS. Just put this file somewhere on your require.paths 3995 | // and you will be able to `var js_beautify = require("beautify").js_beautify`. 3996 | exports.js_beautify = js_beautify; 3997 | } else if (typeof window !== "undefined") { 3998 | // If we're running a web page and don't have either of the above, add our one global 3999 | window.js_beautify = js_beautify; 4000 | } else if (typeof global !== "undefined") { 4001 | // If we don't even have window, try global. 4002 | global.js_beautify = js_beautify; 4003 | } 4004 | 4005 | }()); 4006 | 4007 | --------------------------------------------------------------------------------