diff --git a/.brackets.json b/.brackets.json index 8f30fd22e2e..02e9bc8fa6b 100644 --- a/.brackets.json +++ b/.brackets.json @@ -2,10 +2,28 @@ "jslint.options": { "vars": true, "plusplus": true, + "browser": false, "devel": true, "nomen": true, + "indent": 4, "maxerr": 50, - "es5": true + "es5": true, + "predef": [ + "brackets", + + "require", + "define", + "$", + + "window", + "setTimeout", + "clearTimeout", + + "ArrayBuffer", + "XMLHttpRequest", + "Uint32Array", + "WebSocket" + ] }, "defaultExtension": "js", "language": { diff --git a/.eslintrc.json b/.eslintrc.json index 90190b04568..16b5f74189a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,9 +1,6 @@ { - "env": { - "node": true - }, "rules": { - "no-bitwise": 0, + "no-bitwise": 2, "curly": 2, "eqeqeq": 2, "guard-for-in": 0, @@ -25,7 +22,7 @@ "no-control-regex": 2, "no-regex-spaces": 2, "no-undef": 2, - "strict": 0, + "strict": 2, "no-unused-vars": [0, {"vars": "all", "args": "none"}], "semi": 2, @@ -49,20 +46,24 @@ "valid-typeof": 2, "no-trailing-spaces": 0, - "eol-last": 0 + "eol-last": 0, + "max-len": [1, 120] }, "globals": { "brackets": false, + "require": false, + "define": false, + "$": false, + "window": false, - "alert": false, - "document": false, - "localStorage": false, - "navigator": false, + "console": false, "setTimeout": false, + "clearTimeout": false, - "require": false, - "define": false, - "$": false + "ArrayBuffer": false, + "XMLHttpRequest": false, + "Uint32Array": false, + "WebSocket": false } } diff --git a/.gitignore b/.gitignore index d0bce994f57..a7ff9346eee 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ Thumbs.db # unit test working directory /test/results +/test/temp # Netbeans /nbproject diff --git a/.gitmodules b/.gitmodules index 0fdbcddffb1..99f7ae246b7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,12 +7,6 @@ [submodule "src/thirdparty/mustache"] path = src/thirdparty/mustache url = https://github.com/janl/mustache.js.git -[submodule "src/extensions/default/JavaScriptCodeHints/thirdparty/tern"] - path = src/extensions/default/JavaScriptCodeHints/thirdparty/tern - url = https://github.com/ternjs/tern.git -[submodule "src/extensions/default/JavaScriptCodeHints/thirdparty/acorn"] - path = src/extensions/default/JavaScriptCodeHints/thirdparty/acorn - url = https://github.com/marijnh/acorn.git [submodule "src/thirdparty/requirejs"] path = src/thirdparty/requirejs url = https://github.com/jrburke/requirejs.git diff --git a/.travis.yml b/.travis.yml index 5f431ee20ee..464408502fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: node_js sudo: false # use container-based Travis infrastructure node_js: - - "0.10" + - "6" before_script: - npm install -g grunt-cli - npm install -g jasmine-node diff --git a/Gruntfile.js b/Gruntfile.js index 38f79c6b3f2..62278c7110e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -20,10 +20,12 @@ * DEALINGS IN THE SOFTWARE. * */ -/*global module, require*/ -module.exports = function (grunt) { - 'use strict'; +/*eslint-env node */ +/*jslint node: true */ +'use strict'; + +module.exports = function (grunt) { // load dependencies require('load-grunt-tasks')(grunt, { pattern: [ @@ -321,7 +323,7 @@ module.exports = function (grunt) { }); // task: install - grunt.registerTask('install', ['write-config', 'less']); + grunt.registerTask('install', ['write-config', 'less', 'npm-install-extensions']); // task: test grunt.registerTask('test', ['eslint', 'jasmine', 'nls-check']); @@ -345,6 +347,7 @@ module.exports = function (grunt) { /*'cssmin',*/ /*'uglify',*/ 'copy', + 'npm-install', 'cleanempty', 'usemin', 'build-config' diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 00000000000..74a662687cf --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,27 @@ +### Prerequisites + +* [ ] Can you reproduce the problem with `Debug \ Reload Without Extensions`? +* [ ] Did you perform a cursory search to see if your bug or enhancement is already reported? +* [ ] Did you read the [Troubleshooting guide](https://github.com/adobe/brackets/wiki/Troubleshooting)? + +For more information on how to write a good bug report read [here](https://github.com/adobe/brackets/wiki/How-to-Report-an-Issue) +For more information on how to contribute read [here](https://github.com/adobe/brackets/blob/master/CONTRIBUTING.md) + +### Description + +[Description of the bug or feature] + +### Steps to Reproduce + +1. [First Step] +2. [Second Step] +3. [and so on...] + +**Expected behavior:** [What you expected to happen] + +**Actual behavior:** [What actually happened] + +### Versions + +Please include the OS and what version of the OS you're running. +Please include the version of Brackets. You can find it under `Help \ About Brackets` diff --git a/README.md b/README.md index 3bc231e10d4..dda66500c0b 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ Having problems starting Brackets the first time, or not sure how to use Bracket review [Troubleshooting](https://github.com/adobe/brackets/wiki/Troubleshooting), which helps you to fix common problems and find extra help if needed. +For a list of common Linux issues and workarounds you can [visit this guide](https://nathanjplummer.github.io/Brackets/). + Helping Brackets ---------------- diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json new file mode 100644 index 00000000000..23f1f90405c --- /dev/null +++ b/npm-shrinkwrap.json @@ -0,0 +1,286 @@ +{ + "name": "Brackets", + "version": "1.8.0-0", + "dependencies": { + "anymatch": { + "version": "1.3.0", + "from": "anymatch@1.3.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz" + }, + "arr-diff": { + "version": "2.0.0", + "from": "arr-diff@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz" + }, + "arr-flatten": { + "version": "1.0.1", + "from": "arr-flatten@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz" + }, + "array-unique": { + "version": "0.2.1", + "from": "array-unique@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz" + }, + "arrify": { + "version": "1.0.1", + "from": "arrify@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + }, + "async-each": { + "version": "1.0.1", + "from": "async-each@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz" + }, + "balanced-match": { + "version": "0.4.2", + "from": "balanced-match@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz" + }, + "binary-extensions": { + "version": "1.5.0", + "from": "binary-extensions@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.5.0.tgz" + }, + "brace-expansion": { + "version": "1.1.6", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz" + }, + "braces": { + "version": "1.8.5", + "from": "braces@>=1.8.2 <2.0.0", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz" + }, + "buffer-shims": { + "version": "1.0.0", + "from": "buffer-shims@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" + }, + "chokidar": { + "version": "1.6.0", + "from": "chokidar@1.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + }, + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "expand-brackets": { + "version": "0.1.5", + "from": "expand-brackets@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz" + }, + "expand-range": { + "version": "1.8.2", + "from": "expand-range@>=1.8.1 <2.0.0", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz" + }, + "extglob": { + "version": "0.3.2", + "from": "extglob@>=0.3.1 <0.4.0", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz" + }, + "filename-regex": { + "version": "2.0.0", + "from": "filename-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz" + }, + "fill-range": { + "version": "2.2.3", + "from": "fill-range@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz" + }, + "for-in": { + "version": "0.1.5", + "from": "for-in@>=0.1.5 <0.2.0", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.5.tgz" + }, + "for-own": { + "version": "0.1.4", + "from": "for-own@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.4.tgz" + }, + "glob-base": { + "version": "0.3.0", + "from": "glob-base@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz" + }, + "glob-parent": { + "version": "2.0.0", + "from": "glob-parent@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz" + }, + "graceful-fs": { + "version": "4.1.6", + "from": "graceful-fs@>=4.1.2 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.6.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "is-binary-path": { + "version": "1.0.1", + "from": "is-binary-path@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz" + }, + "is-buffer": { + "version": "1.1.4", + "from": "is-buffer@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.4.tgz" + }, + "is-dotfile": { + "version": "1.0.2", + "from": "is-dotfile@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz" + }, + "is-equal-shallow": { + "version": "0.1.3", + "from": "is-equal-shallow@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz" + }, + "is-extendable": { + "version": "0.1.1", + "from": "is-extendable@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" + }, + "is-extglob": { + "version": "1.0.0", + "from": "is-extglob@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz" + }, + "is-glob": { + "version": "2.0.1", + "from": "is-glob@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz" + }, + "is-number": { + "version": "2.1.0", + "from": "is-number@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz" + }, + "is-posix-bracket": { + "version": "0.1.1", + "from": "is-posix-bracket@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz" + }, + "is-primitive": { + "version": "2.0.0", + "from": "is-primitive@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz" + }, + "isarray": { + "version": "1.0.0", + "from": "isarray@1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "isobject": { + "version": "2.1.0", + "from": "isobject@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" + }, + "kind-of": { + "version": "3.0.4", + "from": "kind-of@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.0.4.tgz" + }, + "lodash": { + "version": "4.15.0", + "from": "lodash@4.15.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.15.0.tgz" + }, + "micromatch": { + "version": "2.3.11", + "from": "micromatch@>=2.1.5 <3.0.0", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz" + }, + "minimatch": { + "version": "3.0.3", + "from": "minimatch@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz" + }, + "normalize-path": { + "version": "2.0.1", + "from": "normalize-path@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz" + }, + "object.omit": { + "version": "2.0.0", + "from": "object.omit@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.0.tgz" + }, + "parse-glob": { + "version": "3.0.4", + "from": "parse-glob@>=3.0.4 <4.0.0", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz" + }, + "path-is-absolute": { + "version": "1.0.0", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" + }, + "preserve": { + "version": "0.2.0", + "from": "preserve@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" + }, + "randomatic": { + "version": "1.1.5", + "from": "randomatic@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.5.tgz" + }, + "readable-stream": { + "version": "2.1.5", + "from": "readable-stream@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz" + }, + "readdirp": { + "version": "2.1.0", + "from": "readdirp@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz" + }, + "regex-cache": { + "version": "0.4.3", + "from": "regex-cache@>=0.4.2 <0.5.0", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz" + }, + "repeat-element": { + "version": "1.1.2", + "from": "repeat-element@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz" + }, + "repeat-string": { + "version": "1.5.4", + "from": "repeat-string@>=1.5.2 <2.0.0", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.5.4.tgz" + }, + "set-immediate-shim": { + "version": "1.0.1", + "from": "set-immediate-shim@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + } +} diff --git a/package.json b/package.json index 58666f28049..950b6ba98fe 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Brackets", - "version": "1.7.0-0", - "apiVersion": "1.7.0", + "version": "1.8.0-0", + "apiVersion": "1.8.0", "homepage": "http://brackets.io", "issues": { "url": "http://github.com/adobe/brackets/issues" @@ -12,7 +12,13 @@ "branch": "", "SHA": "" }, + "dependencies": { + "anymatch": "1.3.0", + "chokidar": "1.6.0", + "lodash": "4.15.0" + }, "devDependencies": { + "glob": "7.0.6", "grunt": "0.4.5", "jasmine-node": "1.11.0", "grunt-jasmine-node": "0.1.0", diff --git a/samples/bg/Getting Started/main.css b/samples/bg/Getting Started/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/bg/Getting Started/main.css +++ b/samples/bg/Getting Started/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/bg/Getting Started/screenshots/quick-edit.png b/samples/bg/Getting Started/screenshots/quick-edit.png index 8174e86264d..f986c39ce46 100644 Binary files a/samples/bg/Getting Started/screenshots/quick-edit.png and b/samples/bg/Getting Started/screenshots/quick-edit.png differ diff --git a/samples/cs/Getting Started/main.css b/samples/cs/Getting Started/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/cs/Getting Started/main.css +++ b/samples/cs/Getting Started/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/cs/Getting Started/screenshots/quick-edit.png b/samples/cs/Getting Started/screenshots/quick-edit.png index f377cb0b177..8ee7a257334 100644 Binary files a/samples/cs/Getting Started/screenshots/quick-edit.png and b/samples/cs/Getting Started/screenshots/quick-edit.png differ diff --git a/samples/da/Kom godt i gang/main.css b/samples/da/Kom godt i gang/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/da/Kom godt i gang/main.css +++ b/samples/da/Kom godt i gang/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/da/Kom godt i gang/screenshots/quick-edit.png b/samples/da/Kom godt i gang/screenshots/quick-edit.png index 911d70c8266..97710aabceb 100644 Binary files a/samples/da/Kom godt i gang/screenshots/quick-edit.png and b/samples/da/Kom godt i gang/screenshots/quick-edit.png differ diff --git a/samples/de/Erste Schritte/main.css b/samples/de/Erste Schritte/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/de/Erste Schritte/main.css +++ b/samples/de/Erste Schritte/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/el/Getting Started/main.css b/samples/el/Getting Started/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/el/Getting Started/main.css +++ b/samples/el/Getting Started/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/el/Getting Started/screenshots/quick-edit.png b/samples/el/Getting Started/screenshots/quick-edit.png index f7bfd7523f9..61be4fe4184 100644 Binary files a/samples/el/Getting Started/screenshots/quick-edit.png and b/samples/el/Getting Started/screenshots/quick-edit.png differ diff --git a/samples/es/Primeros Pasos/main.css b/samples/es/Primeros Pasos/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/es/Primeros Pasos/main.css +++ b/samples/es/Primeros Pasos/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/fa-ir/Getting Started/main.css b/samples/fa-ir/Getting Started/main.css index e3a4dd6e214..4c5fd77d2c4 100644 --- a/samples/fa-ir/Getting Started/main.css +++ b/samples/fa-ir/Getting Started/main.css @@ -44,7 +44,6 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); @@ -54,20 +53,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } diff --git a/samples/fa-ir/Getting Started/screenshots/farsiquick-edit.png b/samples/fa-ir/Getting Started/screenshots/farsiquick-edit.png index eddcdf25f94..ee657886d7c 100644 Binary files a/samples/fa-ir/Getting Started/screenshots/farsiquick-edit.png and b/samples/fa-ir/Getting Started/screenshots/farsiquick-edit.png differ diff --git a/samples/fi/Aloitus/main.css b/samples/fi/Aloitus/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/fi/Aloitus/main.css +++ b/samples/fi/Aloitus/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/fr/Premiers pas/main.css b/samples/fr/Premiers pas/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/fr/Premiers pas/main.css +++ b/samples/fr/Premiers pas/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/id/Memulai/main.css b/samples/id/Memulai/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/id/Memulai/main.css +++ b/samples/id/Memulai/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/it/Primi passi/main.css b/samples/it/Primi passi/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/it/Primi passi/main.css +++ b/samples/it/Primi passi/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/ja/Getting Started/main.css b/samples/ja/Getting Started/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/ja/Getting Started/main.css +++ b/samples/ja/Getting Started/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/ja/Getting Started/screenshots/quick-edit.png b/samples/ja/Getting Started/screenshots/quick-edit.png index c7fcae4b18a..af865aaf337 100644 Binary files a/samples/ja/Getting Started/screenshots/quick-edit.png and b/samples/ja/Getting Started/screenshots/quick-edit.png differ diff --git a/samples/nl/Aan-de-slag/main.css b/samples/nl/Aan-de-slag/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/nl/Aan-de-slag/main.css +++ b/samples/nl/Aan-de-slag/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/pl/Szybki Start/main.css b/samples/pl/Szybki Start/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/pl/Szybki Start/main.css +++ b/samples/pl/Szybki Start/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/pt-br/Primeiros Passos/main.css b/samples/pt-br/Primeiros Passos/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/pt-br/Primeiros Passos/main.css +++ b/samples/pt-br/Primeiros Passos/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/pt-pt/Primeiros Passos/main.css b/samples/pt-pt/Primeiros Passos/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/pt-pt/Primeiros Passos/main.css +++ b/samples/pt-pt/Primeiros Passos/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/root/Getting Started/main.css b/samples/root/Getting Started/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/root/Getting Started/main.css +++ b/samples/root/Getting Started/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/ru/Getting Started/main.css b/samples/ru/Getting Started/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/ru/Getting Started/main.css +++ b/samples/ru/Getting Started/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/sv/Kom igang/main.css b/samples/sv/Kom igang/main.css index eeccb2e5423..dd4ef6c937a 100644 --- a/samples/sv/Kom igang/main.css +++ b/samples/sv/Kom igang/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/zh-tw/Getting Started/main.css b/samples/zh-tw/Getting Started/main.css index d3b2e28bb3a..a7ef1e49deb 100644 --- a/samples/zh-tw/Getting Started/main.css +++ b/samples/zh-tw/Getting Started/main.css @@ -39,8 +39,7 @@ samp { } img { - -webkit-animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; - animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; + animation: colorize 2s cubic-bezier(0, 0, .78, .36) 1; background: transparent; border: 10px solid rgba(0, 0, 0, 0.12); border-radius: 4px; @@ -49,20 +48,13 @@ img { max-width: 95%; } -@-webkit-keyframes colorize { - 0% { - -webkit-filter: grayscale(100%); - } - 100% { - -webkit-filter: grayscale(0%); - } -} - @keyframes colorize { 0% { + -webkit-filter: grayscale(100%); filter: grayscale(100%); } 100% { + -webkit-filter: grayscale(0%); filter: grayscale(0%); } } \ No newline at end of file diff --git a/samples/zh-tw/Getting Started/screenshots/quick-edit.png b/samples/zh-tw/Getting Started/screenshots/quick-edit.png index 02cab4e27c7..82a984b5255 100644 Binary files a/samples/zh-tw/Getting Started/screenshots/quick-edit.png and b/samples/zh-tw/Getting Started/screenshots/quick-edit.png differ diff --git a/src/LiveDevelopment/Agents/CSSAgent.js b/src/LiveDevelopment/Agents/CSSAgent.js index ffb57d1809d..dc0b30bc0ad 100644 --- a/src/LiveDevelopment/Agents/CSSAgent.js +++ b/src/LiveDevelopment/Agents/CSSAgent.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ +/*jslint forin: true */ /** * CSSAgent keeps track of loaded style sheets and allows reloading them diff --git a/src/LiveDevelopment/Agents/ConsoleAgent.js b/src/LiveDevelopment/Agents/ConsoleAgent.js index 636b24defd0..ebccf693264 100644 --- a/src/LiveDevelopment/Agents/ConsoleAgent.js +++ b/src/LiveDevelopment/Agents/ConsoleAgent.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - /** * ConsoleAgent forwards all console message from the remote console to the * local console. diff --git a/src/LiveDevelopment/Agents/DOMAgent.js b/src/LiveDevelopment/Agents/DOMAgent.js index 21eb1725048..051d5c0069e 100644 --- a/src/LiveDevelopment/Agents/DOMAgent.js +++ b/src/LiveDevelopment/Agents/DOMAgent.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $, XMLHttpRequest */ - /** * DOMAgent constructs and maintains a tree of {DOMNode}s that represents the * rendered DOM tree in the remote browser. Nodes can be accessed by id or diff --git a/src/LiveDevelopment/Agents/DOMHelpers.js b/src/LiveDevelopment/Agents/DOMHelpers.js index 3a1dccad415..6fc4d2ec4cf 100644 --- a/src/LiveDevelopment/Agents/DOMHelpers.js +++ b/src/LiveDevelopment/Agents/DOMHelpers.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ +/*jslint regexp: true */ /** * DOMHelpers is a collection of functions used by the DOMAgent exports `eachNode(src, callback)` diff --git a/src/LiveDevelopment/Agents/DOMNode.js b/src/LiveDevelopment/Agents/DOMNode.js index 17e2e177d3a..6d2f01ac6aa 100644 --- a/src/LiveDevelopment/Agents/DOMNode.js +++ b/src/LiveDevelopment/Agents/DOMNode.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ +/*jslint forin: true */ /** * DOMNode represents a node in the DOM tree. It is constructed from a payload diff --git a/src/LiveDevelopment/Agents/EditAgent.js b/src/LiveDevelopment/Agents/EditAgent.js index f1bb52234ac..2c31ac97cfc 100644 --- a/src/LiveDevelopment/Agents/EditAgent.js +++ b/src/LiveDevelopment/Agents/EditAgent.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - /** * EditAgent propagates changes from the in-document editor to the source * document. diff --git a/src/LiveDevelopment/Agents/GotoAgent.js b/src/LiveDevelopment/Agents/GotoAgent.js index 77649eea834..1f4258158fc 100644 --- a/src/LiveDevelopment/Agents/GotoAgent.js +++ b/src/LiveDevelopment/Agents/GotoAgent.js @@ -22,8 +22,7 @@ */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, brackets, $, window */ +/*jslint forin: true, regexp: true */ /** * GotoAgent constructs and responds to the in-browser goto dialog. diff --git a/src/LiveDevelopment/Agents/HighlightAgent.js b/src/LiveDevelopment/Agents/HighlightAgent.js index e90a2dab822..8a0da6570b9 100644 --- a/src/LiveDevelopment/Agents/HighlightAgent.js +++ b/src/LiveDevelopment/Agents/HighlightAgent.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - /** * HighlightAgent dispatches events for highlight requests from in-browser * highlight requests, and allows highlighting nodes and rules in the browser. diff --git a/src/LiveDevelopment/Agents/NetworkAgent.js b/src/LiveDevelopment/Agents/NetworkAgent.js index ba1bb24b924..f887ac9025d 100644 --- a/src/LiveDevelopment/Agents/NetworkAgent.js +++ b/src/LiveDevelopment/Agents/NetworkAgent.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - /** * NetworkAgent tracks all resources loaded by the remote debugger. Use * `wasURLRequested(url)` to query whether a resource was loaded. diff --git a/src/LiveDevelopment/Agents/RemoteAgent.js b/src/LiveDevelopment/Agents/RemoteAgent.js index 4de0318e583..855b19a1873 100644 --- a/src/LiveDevelopment/Agents/RemoteAgent.js +++ b/src/LiveDevelopment/Agents/RemoteAgent.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $, window */ +/*jslint regexp: true */ /** * RemoteAgent defines and provides an interface for custom remote functions diff --git a/src/LiveDevelopment/Agents/RemoteFunctions.js b/src/LiveDevelopment/Agents/RemoteFunctions.js index 2ef3a64dac5..5f302609f30 100644 --- a/src/LiveDevelopment/Agents/RemoteFunctions.js +++ b/src/LiveDevelopment/Agents/RemoteFunctions.js @@ -21,10 +21,8 @@ * */ - -/*jslint vars: true, plusplus: true, browser: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*jshint unused: false */ -/*global window, navigator, Node, console */ +/*jslint forin: true */ +/*global Node */ /*theseus instrument: false */ /** @@ -47,7 +45,7 @@ function RemoteFunctions(experimental) { // determine whether an event should be processed for Live Development function _validEvent(event) { - if (navigator.platform.substr(0, 3) === "Mac") { + if (window.navigator.platform.substr(0, 3) === "Mac") { // Mac return event.metaKey; } else { @@ -127,7 +125,7 @@ function RemoteFunctions(experimental) { y = offset.top + this.element.offsetHeight; // create the container - this.body = document.createElement("div"); + this.body = window.document.createElement("div"); this.body.style.setProperty("z-index", 2147483647); this.body.style.setProperty("position", "absolute"); this.body.style.setProperty("left", x + "px"); @@ -143,7 +141,7 @@ function RemoteFunctions(experimental) { }, addItem: function (target) { - var item = document.createElement("div"); + var item = window.document.createElement("div"); item.style.setProperty("padding", "2px 6px"); if (this.body.childNodes.length > 0) { item.style.setProperty("border-top", "1px solid #ccc"); @@ -154,7 +152,7 @@ function RemoteFunctions(experimental) { item.addEventListener("click", this.onClick.bind(this, target.url)); if (target.file) { - var file = document.createElement("i"); + var file = window.document.createElement("i"); file.style.setProperty("float", "right"); file.style.setProperty("margin-left", "12px"); file.innerHTML = " " + target.file; @@ -168,16 +166,16 @@ function RemoteFunctions(experimental) { this.body = this.createBody(); } if (!this.body.parentNode) { - document.body.appendChild(this.body); + window.document.body.appendChild(this.body); } - document.addEventListener("click", this.remove); + window.document.addEventListener("click", this.remove); }, remove: function () { if (this.body && this.body.parentNode) { - document.body.removeChild(this.body); + window.document.body.removeChild(this.body); } - document.removeEventListener("click", this.remove); + window.document.removeEventListener("click", this.remove); } }; @@ -315,7 +313,7 @@ function RemoteFunctions(experimental) { }, add: function (element, doAnimation) { - if (this._elementExists(element) || element === document) { + if (this._elementExists(element) || element === window.document) { return; } if (this.trigger) { @@ -395,7 +393,7 @@ function RemoteFunctions(experimental) { function onMouseMove(event) { onMouseOver(event); - document.removeEventListener("mousemove", onMouseMove); + window.document.removeEventListener("mousemove", onMouseMove); } function onClick(event) { @@ -412,11 +410,11 @@ function RemoteFunctions(experimental) { function onKeyUp(event) { if (_setup && !_validEvent(event)) { - document.removeEventListener("keyup", onKeyUp); - document.removeEventListener("mouseover", onMouseOver); - document.removeEventListener("mouseout", onMouseOut); - document.removeEventListener("mousemove", onMouseMove); - document.removeEventListener("click", onClick); + window.document.removeEventListener("keyup", onKeyUp); + window.document.removeEventListener("mouseover", onMouseOver); + window.document.removeEventListener("mouseout", onMouseOut); + window.document.removeEventListener("mousemove", onMouseMove); + window.document.removeEventListener("click", onClick); _localHighlight.clear(); _localHighlight = undefined; _setup = false; @@ -425,11 +423,11 @@ function RemoteFunctions(experimental) { function onKeyDown(event) { if (!_setup && _validEvent(event)) { - document.addEventListener("keyup", onKeyUp); - document.addEventListener("mouseover", onMouseOver); - document.addEventListener("mouseout", onMouseOut); - document.addEventListener("mousemove", onMouseMove); - document.addEventListener("click", onClick); + window.document.addEventListener("keyup", onKeyUp); + window.document.addEventListener("mouseover", onMouseOver); + window.document.addEventListener("mouseout", onMouseOut); + window.document.addEventListener("mousemove", onMouseMove); + window.document.addEventListener("click", onClick); _localHighlight = new Highlight("#ecc", true); _setup = true; } @@ -479,7 +477,7 @@ function RemoteFunctions(experimental) { // highlight a rule function highlightRule(rule) { hideHighlight(); - var i, nodes = document.querySelectorAll(rule); + var i, nodes = window.document.querySelectorAll(rule); for (i = 0; i < nodes.length; i++) { highlight(nodes[i]); } @@ -500,7 +498,7 @@ function RemoteFunctions(experimental) { function _scrollHandler(e) { // Document scrolls can be updated immediately. Any other scrolls // need to be updated on a timer to ensure the layout is correct. - if (e.target === document) { + if (e.target === window.document) { redrawHighlights(); } else { if (_remoteHighlight || _localHighlight) { @@ -817,7 +815,7 @@ function RemoteFunctions(experimental) { } function getSimpleDOM() { - return JSON.stringify(_domElementToJSON(document.documentElement)); + return JSON.stringify(_domElementToJSON(window.document.documentElement)); } // init diff --git a/src/LiveDevelopment/Agents/ScriptAgent.js b/src/LiveDevelopment/Agents/ScriptAgent.js index 8dfa750a538..a9b6e5e73cd 100644 --- a/src/LiveDevelopment/Agents/ScriptAgent.js +++ b/src/LiveDevelopment/Agents/ScriptAgent.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ - /** * ScriptAgent tracks all executed scripts, defines internal breakpoints, and * interfaces with the remote debugger. diff --git a/src/LiveDevelopment/Documents/CSSDocument.js b/src/LiveDevelopment/Documents/CSSDocument.js index bef5adee54a..85e56919a84 100644 --- a/src/LiveDevelopment/Documents/CSSDocument.js +++ b/src/LiveDevelopment/Documents/CSSDocument.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ +/*jslint forin: true */ /** * CSSDocument manages a single CSS source document diff --git a/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js b/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js index 3a13c2a2fc8..855600c0cae 100644 --- a/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js +++ b/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * CSSPreprocessorDocument manages a single LESS or SASS source document * diff --git a/src/LiveDevelopment/Documents/HTMLDocument.js b/src/LiveDevelopment/Documents/HTMLDocument.js index d459fba4729..2b6e9ded4b7 100644 --- a/src/LiveDevelopment/Documents/HTMLDocument.js +++ b/src/LiveDevelopment/Documents/HTMLDocument.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - /** * HTMLDocument manages a single HTML source document * diff --git a/src/LiveDevelopment/Documents/JSDocument.js b/src/LiveDevelopment/Documents/JSDocument.js index 2be95dfdc0e..35fe8f82c50 100644 --- a/src/LiveDevelopment/Documents/JSDocument.js +++ b/src/LiveDevelopment/Documents/JSDocument.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ +/*jslint forin: true */ /** * JSDocument manages a single JavaScript source document diff --git a/src/LiveDevelopment/Inspector/Inspector.js b/src/LiveDevelopment/Inspector/Inspector.js index 8adf73e1675..12508db2306 100644 --- a/src/LiveDevelopment/Inspector/Inspector.js +++ b/src/LiveDevelopment/Inspector/Inspector.js @@ -21,10 +21,8 @@ * */ - - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $, WebSocket, FileError, XMLHttpRequest */ +/*jslint forin: true */ +/*global FileError */ /** * Inspector manages the connection to Chrome/Chromium's remote debugger. diff --git a/src/LiveDevelopment/LiveDevMultiBrowser.js b/src/LiveDevelopment/LiveDevMultiBrowser.js index 3bdee31e7d8..3582ea7f91f 100644 --- a/src/LiveDevelopment/LiveDevMultiBrowser.js +++ b/src/LiveDevelopment/LiveDevMultiBrowser.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ - /** * LiveDevelopment allows Brackets to launch a browser with a "live preview" that's * connected to the current editor. @@ -310,7 +307,7 @@ define(function (require, exports, module) { docPromise.done(function (doc) { if ((_classForDocument(doc) === LiveCSSDocument) && (!_liveDocument || (doc !== _liveDocument.doc))) { - var liveDoc = _createLiveDocument(doc, null, roots); + var liveDoc = _createLiveDocument(doc, doc._masterEditor, roots); if (liveDoc) { _server.add(liveDoc); _relatedDocuments[doc.url] = liveDoc; diff --git a/src/LiveDevelopment/LiveDevServerManager.js b/src/LiveDevelopment/LiveDevServerManager.js index c94f666f2d0..5663ce0e131 100644 --- a/src/LiveDevelopment/LiveDevServerManager.js +++ b/src/LiveDevelopment/LiveDevServerManager.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * LiveDevServerManager Overview: * diff --git a/src/LiveDevelopment/LiveDevelopment.js b/src/LiveDevelopment/LiveDevelopment.js index 9c4f5fb31d2..cd54b987b85 100644 --- a/src/LiveDevelopment/LiveDevelopment.js +++ b/src/LiveDevelopment/LiveDevelopment.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $, brackets, window, open */ +/*global open */ /** * LiveDevelopment manages the Inspector, all Agents, and the active LiveDocument diff --git a/src/LiveDevelopment/LiveDevelopmentUtils.js b/src/LiveDevelopment/LiveDevelopmentUtils.js index df45ff584f6..6a12f4ec836 100644 --- a/src/LiveDevelopment/LiveDevelopmentUtils.js +++ b/src/LiveDevelopment/LiveDevelopmentUtils.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Set of utilities for working with files and text content. */ diff --git a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js index 68d547f8daf..f98431bffe7 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js +++ b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ +/*jslint regexp: true */ /** * LiveCSSDocument manages a single CSS source document @@ -49,7 +47,8 @@ define(function LiveCSSDocumentModule(require, exports, module) { var _ = require("thirdparty/lodash"), CSSUtils = require("language/CSSUtils"), EventDispatcher = require("utils/EventDispatcher"), - LiveDocument = require("LiveDevelopment/MultiBrowserImpl/documents/LiveDocument"); + LiveDocument = require("LiveDevelopment/MultiBrowserImpl/documents/LiveDocument"), + PathUtils = require("thirdparty/path-utils/path-utils"); /** * @constructor @@ -72,6 +71,9 @@ define(function LiveCSSDocumentModule(require, exports, module) { this.doc.on("change.LiveCSSDocument", this.onChange); this.doc.on("deleted.LiveCSSDocument", this.onDeleted); + if (editor) { + this._attachToEditor(editor); + } }; LiveCSSDocument.prototype = Object.create(LiveDocument.prototype); @@ -94,14 +96,31 @@ define(function LiveCSSDocumentModule(require, exports, module) { * When the user edits the file, update the stylesheet in the browser and redraw highlights. */ LiveCSSDocument.prototype._updateBrowser = function () { - var i; + var i, + docUrl = this.doc.url; + + // Determines whether an url() line contains a relative or absolute URL, and makes + // the URL absolute to the CSS file if it is relative + function makeUrlsRelativeToCss(match, quotationMark, url) { + if (PathUtils.isRelativeUrl(url)) { + var absUrl = PathUtils.makeUrlAbsolute(url, docUrl); + return "url(" + quotationMark + absUrl + quotationMark + ")"; + } + return match; + } + for (i = 0; i < this.roots.length; i++) { - if (this.doc.url !== this.roots[i].toString()) { + if (docUrl !== this.roots[i].toString()) { // if it's not directly included through , // reload the original doc this.trigger("updateDoc", this.roots[i]); } else { - this.protocol.setStylesheetText(this.doc.url, this.doc.getText()); + var docText = this.doc.getText(); + + // Replace all occurrences of url() where the URL is relative to the CSS file with + // an absolute URL so it is relative to the CSS file, not the HTML file (see #11936) + docText = docText.replace(/\burl\(\s*(["']?)([^)\n]+)\1\s*\)/ig, makeUrlsRelativeToCss); + this.protocol.setStylesheetText(docUrl, docText); } } this.redrawHighlights(); diff --git a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveDocument.js b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveDocument.js index e3bc7355371..7c3ed7329e7 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveDocument.js +++ b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveDocument.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument.js b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument.js index 311ae4f414f..c42cc3a2f4b 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument.js +++ b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - /** * LiveHTMLDocument manages a single HTML source document. Edits to the HTML are applied live in * the browser, and the DOM node corresponding to the selection is highlighted. diff --git a/src/LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation.js b/src/LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation.js index ee51bec0b2a..1020d6fc346 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation.js +++ b/src/LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation.js @@ -21,9 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ /*unittests: HTML Instrumentation*/ /** diff --git a/src/LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM.js b/src/LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM.js index ca0653dbf92..fe7397138f6 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM.js +++ b/src/LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM.js @@ -21,9 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ /*unittests: HTML Instrumentation*/ define(function (require, exports, module) { diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js index 754a7f04bee..0d7c452c2bc 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js @@ -21,10 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - - define(function (require, exports, module) { "use strict"; diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/LauncherDomain.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/LauncherDomain.js index 566d59072f3..f1d202253db 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/LauncherDomain.js +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/LauncherDomain.js @@ -21,53 +21,50 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, node: true */ +/*eslint-env node */ +/*jslint node: true */ +"use strict"; -(function () { - "use strict"; +var open = require("opn"); - var open = require("open"); - - /** - * @private - * The Brackets domain manager for registering node extensions. - * @type {?DomainManager} - */ - var _domainManager; +/** + * @private + * The Brackets domain manager for registering node extensions. + * @type {?DomainManager} + */ +var _domainManager; - /** - * Launch the given URL in the system default browser. - * TODO: it now launching just on default browser, add launchers for specific browsers. - * @param {string} url - */ - function _cmdLaunch(url) { - open(url); - } +/** + * Launch the given URL in the system default browser. + * TODO: it now launching just on default browser, add launchers for specific browsers. + * @param {string} url + */ +function _cmdLaunch(url) { + open(url); +} - /** - * Initializes the domain and registers commands. - * @param {DomainManager} domainManager The DomainManager for the server - */ - function init(domainManager) { - _domainManager = domainManager; - if (!domainManager.hasDomain("launcher")) { - domainManager.registerDomain("launcher", {major: 0, minor: 1}); - } - domainManager.registerCommand( - "launcher", // domain name - "launch", // command name - _cmdLaunch, // command handler function - false, // this command is synchronous in Node - "Launches a given HTML file in the browser for live development", - [ - { name: "url", type: "string", description: "file:// url to the HTML file" }, - { name: "browser", type: "string", description: "browser name"} - ], - [] - ); +/** + * Initializes the domain and registers commands. + * @param {DomainManager} domainManager The DomainManager for the server + */ +function init(domainManager) { + _domainManager = domainManager; + if (!domainManager.hasDomain("launcher")) { + domainManager.registerDomain("launcher", {major: 0, minor: 1}); } + domainManager.registerCommand( + "launcher", // domain name + "launch", // command name + _cmdLaunch, // command handler function + false, // this command is synchronous in Node + "Launches a given HTML file in the browser for live development", + [ + { name: "url", type: "string", description: "file:// url to the HTML file" }, + { name: "browser", type: "string", description: "browser name"} + ], + [] + ); +} - exports.init = init; - -}()); +exports.init = init; diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/index.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/index.js new file mode 100644 index 00000000000..508504840dc --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/index.js @@ -0,0 +1,83 @@ +'use strict'; +/* eslint-disable no-unused-vars */ +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (e) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (Object.getOwnPropertySymbols) { + symbols = Object.getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/license b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/license new file mode 100644 index 00000000000..654d0bfe943 --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/package.json b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/package.json new file mode 100644 index 00000000000..068b9088c79 --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + "object-assign@^4.0.1", + "/Users/Filippo/Documents/git/brackets/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn" + ] + ], + "_from": "object-assign@>=4.0.1 <5.0.0", + "_id": "object-assign@4.1.0", + "_inCache": true, + "_installable": true, + "_location": "/object-assign", + "_nodeVersion": "4.1.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/object-assign-4.1.0.tgz_1462212593641_0.3332549517508596" + }, + "_npmUser": { + "email": "ben@benalpert.com", + "name": "spicyj" + }, + "_npmVersion": "2.14.19", + "_phantomChildren": {}, + "_requested": { + "name": "object-assign", + "raw": "object-assign@^4.0.1", + "rawSpec": "^4.0.1", + "scope": null, + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/opn" + ], + "_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "_shasum": "7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0", + "_shrinkwrap": null, + "_spec": "object-assign@^4.0.1", + "_where": "/Users/Filippo/Documents/git/brackets/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn", + "author": { + "email": "sindresorhus@gmail.com", + "name": "Sindre Sorhus", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/object-assign/issues" + }, + "dependencies": {}, + "description": "ES2015 Object.assign() ponyfill", + "devDependencies": { + "lodash": "^4.8.2", + "matcha": "^0.7.0", + "mocha": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0", + "tarball": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "72fe21c86911758f3342fdf41c2a57860d5829bc", + "homepage": "https://github.com/sindresorhus/object-assign#readme", + "keywords": [ + "object", + "assign", + "extend", + "properties", + "es2015", + "ecmascript", + "harmony", + "ponyfill", + "prollyfill", + "polyfill", + "shim", + "browser" + ], + "license": "MIT", + "maintainers": [ + { + "email": "sindresorhus@gmail.com", + "name": "sindresorhus" + }, + { + "email": "ben@benalpert.com", + "name": "spicyj" + } + ], + "name": "object-assign", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/object-assign.git" + }, + "scripts": { + "bench": "matcha bench.js", + "test": "xo && mocha" + }, + "version": "4.1.0" +} diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/readme.md b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/readme.md new file mode 100644 index 00000000000..13c097734cf --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/object-assign/readme.md @@ -0,0 +1,56 @@ +# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign) + +> ES2015 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) ponyfill + +> Ponyfill: A polyfill that doesn't overwrite the native method + + +## Install + +``` +$ npm install --save object-assign +``` + + +## Usage + +```js +const objectAssign = require('object-assign'); + +objectAssign({foo: 0}, {bar: 1}); +//=> {foo: 0, bar: 1} + +// multiple sources +objectAssign({foo: 0}, {bar: 1}, {baz: 2}); +//=> {foo: 0, bar: 1, baz: 2} + +// overwrites equal keys +objectAssign({foo: 0}, {foo: 1}, {foo: 2}); +//=> {foo: 2} + +// ignores null and undefined sources +objectAssign({foo: 0}, null, {bar: 1}, undefined); +//=> {foo: 0, bar: 1} +``` + + +## API + +### objectAssign(target, source, [source, ...]) + +Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones. + + +## Resources + +- [ES2015 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign) + + +## Related + +- [deep-assign](https://github.com/sindresorhus/deep-assign) - Recursive `Object.assign()` + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.jshintignore b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.jshintignore deleted file mode 100644 index 651665bbd97..00000000000 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.jshintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.git diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.jshintrc b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.jshintrc deleted file mode 100644 index 765fb34a1ec..00000000000 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.jshintrc +++ /dev/null @@ -1,27 +0,0 @@ -{ - "bitwise": true, - "curly": true, - "eqeqeq": true, - "forin": true, - "immed": true, - "latedef": false, - "newcap": true, - "noarg": true, - "noempty": false, - "nonew": true, - "plusplus": false, - "regexp": false, - "undef": true, - "strict": false, - "trailing": true, - - "eqnull": true, - "laxcomma": true, - - "node": true, - - "onevar": true, - "white": true, - - "indent": 2 -} diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.npmignore b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.npmignore deleted file mode 100644 index 9daeafb9864..00000000000 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/LICENSE b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/LICENSE deleted file mode 100644 index 58b5cd2414f..00000000000 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2012 Jay Jordan - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/README.md b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/README.md deleted file mode 100644 index 4fc0d54ecea..00000000000 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# open - -Open a file or url in the user's preferred application. - -# Usage - -```javascript -var open = require("open"); -open("http://www.google.com"); -``` - -`open` taks an optional argument specifying the program to be used to open the -file or URL. - -```javascript -open("http://www.google.com", "firefox"); -``` - -# Installation - - npm install open - -# How it works - -- on `win32` uses `start` -- on `darwin` uses `open` -- otherwise uses the `xdg-open` script from [freedesktop.org](http://portland.freedesktop.org/xdg-utils-1.0/xdg-open.html) - -# Warning - -The same care should be taken when calling open as if you were calling -[child_process.exec](http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) -directly. If it is an executable it will run in a new shell. diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/lib/open.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/lib/open.js deleted file mode 100644 index 3b77c3f3bb9..00000000000 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/lib/open.js +++ /dev/null @@ -1,60 +0,0 @@ -var exec = require('child_process').exec - , path = require('path') - ; - - -/** - * open a file or uri using the default application for the file type. - * - * @return {ChildProcess} - the child process object. - * @param {string} target - the file/uri to open. - * @param {string} appName - (optional) the application to be used to open the - * file (for example, "chrome", "firefox") - * @param {function(Error)} callback - called with null on success, or - * an error object that contains a property 'code' with the exit - * code of the process. - */ - -module.exports = open; - -function open(target, appName, callback) { - var opener; - - if (typeof(appName) === 'function') { - callback = appName; - appName = null; - } - - switch (process.platform) { - case 'darwin': - if (appName) { - opener = 'open -a "' + escape(appName) + '"'; - } else { - opener = 'open'; - } - break; - case 'win32': - // if the first parameter to start is quoted, it uses that as the title - // so we pass a blank title so we can quote the file we are opening - if (appName) { - opener = 'start "" "' + escape(appName) + '"'; - } else { - opener = 'start ""'; - } - break; - default: - if (appName) { - opener = escape(appName); - } else { - // use Portlands xdg-open everywhere else - opener = path.join(__dirname, '../vendor/xdg-open'); - } - break; - } - - return exec(opener + ' "' + escape(target) + '"', callback); -} - -function escape(s) { - return s.replace(/"/g, '\\\"'); -} diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/package.json b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/package.json deleted file mode 100644 index 0999270937b..00000000000 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "open", - "version": "0.0.4", - "description": "open a file or url in the user's preferred application", - "keywords": [ - "start", - "open", - "browser", - "editor", - "default" - ], - "homepage": "https://github.com/jjrdn/node-open", - "author": { - "name": "J Jordan", - "email": "jjrdn@styosis.com" - }, - "license": "MIT", - "contributors": [ - { - "name": "Victor Costan", - "email": "victor@costan.us", - "url": "http://www.costan.us" - } - ], - "repository": { - "type": "git", - "url": "https://github.com/pwnall/node-open.git" - }, - "bugs": { - "url": "https://github.com/pwnall/node-open/issues" - }, - "engines": { - "node": ">= 0.6.0" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "*" - }, - "optionalDependencies": {}, - "main": "lib/open.js", - "scripts": { - "test": "node_modules/mocha/bin/mocha" - }, - "readme": "# open\n\nOpen a file or url in the user's preferred application.\n\n# Usage\n\n```javascript\nvar open = require(\"open\");\nopen(\"http://www.google.com\");\n```\n\n`open` taks an optional argument specifying the program to be used to open the\nfile or URL.\n\n```javascript\nopen(\"http://www.google.com\", \"firefox\");\n```\n\n# Installation\n\n npm install open\n\n# How it works\n\n- on `win32` uses `start`\n- on `darwin` uses `open`\n- otherwise uses the `xdg-open` script from [freedesktop.org](http://portland.freedesktop.org/xdg-utils-1.0/xdg-open.html)\n\n# Warning\n\nThe same care should be taken when calling open as if you were calling\n[child_process.exec](http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)\ndirectly. If it is an executable it will run in a new shell.\n", - "readmeFilename": "README.md", - "_id": "open@0.0.4", - "_from": "open@0.0.4" -} diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/index.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/index.js new file mode 100644 index 00000000000..13dcb66fb12 --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/index.js @@ -0,0 +1,95 @@ +'use strict'; +var path = require('path'); +var childProcess = require('child_process'); +var objectAssign = require('object-assign'); +var Promise = require('pinkie-promise'); + +module.exports = function (target, opts) { + if (typeof target !== 'string') { + return Promise.reject(new Error('Expected a `target`')); + } + + opts = objectAssign({wait: true}, opts); + + var cmd; + var appArgs = []; + var args = []; + var cpOpts = {}; + + if (Array.isArray(opts.app)) { + appArgs = opts.app.slice(1); + opts.app = opts.app[0]; + } + + if (process.platform === 'darwin') { + cmd = 'open'; + + if (opts.wait) { + args.push('-W'); + } + + if (opts.app) { + args.push('-a', opts.app); + } + } else if (process.platform === 'win32') { + cmd = 'cmd'; + args.push('/c', 'start', '""'); + target = target.replace(/&/g, '^&'); + + if (opts.wait) { + args.push('/wait'); + } + + if (opts.app) { + args.push(opts.app); + } + + if (appArgs.length > 0) { + args = args.concat(appArgs); + } + } else { + if (opts.app) { + cmd = opts.app; + } else { + cmd = path.join(__dirname, 'xdg-open'); + } + + if (appArgs.length > 0) { + args = args.concat(appArgs); + } + + if (!opts.wait) { + // xdg-open will block the process unless + // stdio is ignored even if it's unref'd + cpOpts.stdio = 'ignore'; + } + } + + args.push(target); + + if (process.platform === 'darwin' && appArgs.length > 0) { + args.push('--args'); + args = args.concat(appArgs); + } + + var cp = childProcess.spawn(cmd, args, cpOpts); + + if (opts.wait) { + return new Promise(function (resolve, reject) { + cp.once('error', reject); + + cp.once('close', function (code) { + if (code > 0) { + reject(new Error('Exited with code ' + code)); + return; + } + + resolve(cp); + }); + }); + } + + cp.unref(); + + return Promise.resolve(cp); +}; diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/LICENSE b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/license similarity index 93% rename from src/filesystem/impls/appshell/node/node_modules/fsevents/LICENSE rename to src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/license index 9cfd7eae0ef..ced6f6b30dd 100644 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/LICENSE +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/license @@ -1,7 +1,6 @@ -MIT License ------------ +The MIT License (MIT) -Copyright (C) 2010-2013 Philipp Dunkel +Copyright (c) Sindre Sorhus Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/package.json b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/package.json new file mode 100644 index 00000000000..1f9d62546b4 --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/package.json @@ -0,0 +1,116 @@ +{ + "_args": [ + [ + "opn@4.0.2", + "/Users/Filippo/Documents/git/brackets/src/LiveDevelopment/MultiBrowserImpl/launchers/node" + ] + ], + "_from": "opn@4.0.2", + "_id": "opn@4.0.2", + "_inCache": true, + "_installable": true, + "_location": "/opn", + "_nodeVersion": "4.4.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/opn-4.0.2.tgz_1463477356148_0.1645404922310263" + }, + "_npmUser": { + "email": "sindresorhus@gmail.com", + "name": "sindresorhus" + }, + "_npmVersion": "3.9.0", + "_phantomChildren": {}, + "_requested": { + "name": "opn", + "raw": "opn@4.0.2", + "rawSpec": "4.0.2", + "scope": null, + "spec": "4.0.2", + "type": "version" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", + "_shasum": "7abc22e644dff63b0a96d5ab7f2790c0f01abc95", + "_shrinkwrap": null, + "_spec": "opn@4.0.2", + "_where": "/Users/Filippo/Documents/git/brackets/src/LiveDevelopment/MultiBrowserImpl/launchers/node", + "author": { + "email": "sindresorhus@gmail.com", + "name": "Sindre Sorhus", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/opn/issues" + }, + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "description": "A better node-open. Opens stuff like websites, files, executables. Cross-platform.", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "7abc22e644dff63b0a96d5ab7f2790c0f01abc95", + "tarball": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "xdg-open" + ], + "gitHead": "b56b0e981ee377d3b04c57a4e6748ad2793ada17", + "homepage": "https://github.com/sindresorhus/opn#readme", + "keywords": [ + "app", + "open", + "opn", + "opener", + "opens", + "launch", + "start", + "xdg-open", + "xdg", + "default", + "cmd", + "browser", + "editor", + "executable", + "exe", + "url", + "urls", + "arguments", + "args", + "spawn", + "exec", + "child", + "process", + "website", + "file" + ], + "license": "MIT", + "maintainers": [ + { + "email": "sindresorhus@gmail.com", + "name": "sindresorhus" + } + ], + "name": "opn", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/opn.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "4.0.2" +} diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/readme.md b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/readme.md new file mode 100644 index 00000000000..76d543933cd --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/readme.md @@ -0,0 +1,89 @@ +# opn + +> A better [node-open](https://github.com/pwnall/node-open). Opens stuff like websites, files, executables. Cross-platform. + + +#### Why? + +- Actively maintained +- Supports app arguments +- Safer as it uses `spawn` instead of `exec` +- Fixes most of the open `node-open` issues +- Includes the latest [`xdg-open` script](http://cgit.freedesktop.org/xdg/xdg-utils/commit/?id=c55122295c2a480fa721a9614f0e2d42b2949c18) for Linux + + +## Install + +``` +$ npm install --save opn +``` + + +## Usage + +```js +const opn = require('opn'); + +// opens the image in the default image viewer +opn('unicorn.png').then(() => { + // image viewer closed +}); + +// opens the url in the default browser +opn('http://sindresorhus.com'); + +// specify the app to open in +opn('http://sindresorhus.com', {app: 'firefox'}); + +// specify app arguments +opn('http://sindresorhus.com', {app: ['google chrome', '--incognito']}); +``` + + +## API + +Uses the command `open` on OS X, `start` on Windows and `xdg-open` on other platforms. + +### opn(target, [options]) + +Returns a promise for the [spawned child process](https://nodejs.org/api/child_process.html#child_process_class_childprocess). You'd normally not need to use this for anything, but it can be useful if you'd like to attach custom event listeners or perform other operations directly on the spawned process. + +#### target + +*Required* +Type: `string` + +The thing you want to open. Can be a URL, file, or executable. + +Opens in the default app for the file type. Eg. URLs opens in your default browser. + +#### options + +Type: `object` + +##### wait + +Type: `boolean` +Default: `true` + +Wait for the opened app to exit before calling the `callback`. If `false` it's called immediately when opening the app. + +On Windows you have to explicitly specify an app for it to be able to wait. + +##### app + +Type: `string`, `array` + +Specify the app to open the `target` with, or an array with the app and app arguments. + +The app name is platform dependent. Don't hard code it in reusable modules. Eg. Chrome is `google chrome` on OS X, `google-chrome` on Linux and `chrome` on Windows. + + +## Related + +- [opn-cli](https://github.com/sindresorhus/opn-cli) - CLI for this module + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/vendor/xdg-open b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/xdg-open similarity index 81% rename from src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/vendor/xdg-open rename to src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/xdg-open index 13caac1a43f..9be7f32f63e 100755 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/open/vendor/xdg-open +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn/xdg-open @@ -38,7 +38,7 @@ manualpage() cat << _MANUALPAGE Name - xdg-open -- opens a file or URL in the user's preferred + xdg-open - opens a file or URL in the user's preferred application Synopsis @@ -104,7 +104,7 @@ _MANUALPAGE usage() { cat << _USAGE - xdg-open -- opens a file or URL in the user's preferred + xdg-open - opens a file or URL in the user's preferred application Synopsis @@ -296,7 +296,7 @@ check_vendor_prefix() [ -n "$file_label" ] || file_label="filename" file=`basename "$1"` case "$file" in - [a-zA-Z]*-*) + [[:alpha:]]*-*) return ;; esac @@ -346,7 +346,7 @@ check_common_commands() ;; --version) - echo "xdg-open 1.1.0 rc1" + echo "xdg-open 1.1.0 rc3" exit_success ;; esac @@ -375,6 +375,9 @@ detectDE() if [ -n "${XDG_CURRENT_DESKTOP}" ]; then case "${XDG_CURRENT_DESKTOP}" in + ENLIGHTENMENT) + DE=enlightenment; + ;; GNOME) DE=gnome; ;; @@ -384,19 +387,24 @@ detectDE() LXDE) DE=lxde; ;; + MATE) + DE=mate; + ;; XFCE) DE=xfce + ;; esac fi if [ x"$DE" = x"" ]; then # classic fallbacks - if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; fi fi @@ -409,6 +417,9 @@ detectDE() LXDE|Lubuntu) DE=lxde; ;; + MATE) + DE=mate; + ;; xfce|xfce4|'Xfce Session') DE=xfce; ;; @@ -449,16 +460,42 @@ kfmclient_fix_exit_code() } # This handles backslashes but not quote marks. -first_word() +last_word() { read first rest - echo "$first" + echo "$rest" } -last_word() +# Get the value of a key in a desktop file's Desktop Entry group. +# Example: Use get_key foo.desktop Exec +# to get the values of the Exec= key for the Desktop Entry group. +get_key() { - read first rest - echo "$rest" + local file="${1}" + local key="${2}" + local desktop_entry="" + + IFS_="${IFS}" + IFS="" + while read line + do + case "$line" in + "[Desktop Entry]") + desktop_entry="y" + ;; + # Reset match flag for other groups + "["*) + desktop_entry="" + ;; + "${key}="*) + # Only match Desktop Entry group + if [ -n "${desktop_entry}" ] + then + echo "${line}" | cut -d= -f 2- + fi + esac + done < "${file}" + IFS="${IFS_}" } open_darwin() @@ -474,15 +511,18 @@ open_darwin() open_kde() { - if kde-open -v 2>/dev/null 1>&2; then - kde-open "$1" + if [ -n "${KDE_SESSION_VERSION}" ]; then + case "${KDE_SESSION_VERSION}" in + 4) + kde-open "$1" + ;; + 5) + kde-open${KDE_SESSION_VERSION} "$1" + ;; + esac else - if [ x"$KDE_SESSION_VERSION" = x"4" ]; then - kfmclient openURL "$1" - else - kfmclient exec "$1" - kfmclient_fix_exit_code $? - fi + kfmclient exec "$1" + kfmclient_fix_exit_code $? fi if [ $? -eq 0 ]; then @@ -533,6 +573,17 @@ open_xfce() fi } +open_enlightenment() +{ + enlightenment_open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + #----------------------------------------- # Recursively search .desktop file @@ -540,7 +591,7 @@ search_desktop_file() { local default="$1" local dir="$2" - local arg="$3" + local target="$3" local file="" # look for both vendor-app.desktop, vendor/app.desktop @@ -551,29 +602,56 @@ search_desktop_file() fi if [ -r "$file" ] ; then - command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="$(get_key "${file}" "Exec" | first_word)" command_exec=`which $command 2>/dev/null` - arguments="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | last_word`" - arg_one="`echo $arg | sed 's/&/\\\\&/g'`" - arguments_exec="`echo $arguments | sed -e 's*%[fFuU]*"'"$arg_one"'"*g'`" - - if [ -x "$command_exec" ] ; then - if echo $arguments | grep -iq '%[fFuU]' ; then - echo START $command_exec $arguments_exec - eval $command_exec $arguments_exec - else - echo START $command_exec $arguments_exec "$arg" - eval $command_exec $arguments_exec "$arg" - fi + icon="$(get_key "${file}" "Icon")" + # FIXME: Actually LC_MESSAGES should be used as described in + # http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html + localised_name="$(get_key "${file}" "Name")" + set -- $(get_key "${file}" "Exec" | last_word) + # We need to replace any occurrence of "%f", "%F" and + # the like by the target file. We examine each + # argument and append the modified argument to the + # end then shift. + local args=$# + local replaced=0 + while [ $args -gt 0 ]; do + case $1 in + %[c]) + replaced=1 + arg="${localised_name}" + shift + set -- "$@" "$arg" + ;; + %[fFuU]) + replaced=1 + arg="$target" + shift + set -- "$@" "$arg" + ;; + %[i]) + replaced=1 + shift + set -- "$@" "--icon" "$icon" + ;; + *) + arg="$1" + shift + set -- "$@" "$arg" + ;; + esac + args=$(( $args - 1 )) + done + [ $replaced -eq 1 ] || set -- "$@" "$target" + "$command_exec" "$@" - if [ $? -eq 0 ]; then - exit_success - fi + if [ $? -eq 0 ]; then + exit_success fi fi for d in $dir/*/; do - [ -d "$d" ] && search_desktop_file "$default" "$d" "$arg" + [ -d "$d" ] && search_desktop_file "$default" "$d" "$target" done } @@ -624,12 +702,14 @@ open_generic() file=${file#file://} file="$(printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')")" fi - check_input_file "$file" + file_check=${file%%#*} + file_check=${file_check%%\?*} + check_input_file "$file_check" - open_generic_xdg_file_mime "$file" + filetype=`xdg-mime query filetype "$file_check" | sed "s/;.*//"` + open_generic_xdg_mime "$file" "$filetype" - if [ -f /etc/debian_version ] && - which run-mailcap 2>/dev/null 1>&2; then + if which run-mailcap 2>/dev/null 1>&2; then run-mailcap --action=view "$file" if [ $? -eq 0 ]; then exit_success @@ -656,7 +736,7 @@ open_generic() fi if [ x"$browser_with_arg" = x"$browser" ]; then - eval '$browser $1'$xdg_redirect_output; + eval '$browser "$1"'$xdg_redirect_output; else eval '$browser_with_arg'$xdg_redirect_output; fi @@ -675,10 +755,10 @@ open_lxde() if (echo "$1" | grep -q '^file://' || ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:') then - local file="$(echo "$1" | sed 's%^file://%%')" + local file="$1" # handle relative paths - if ! echo "$file" | grep -q '^/'; then + if ! echo "$file" | egrep -q '^(file://)?/'; then file="$(pwd)/$file" fi @@ -728,6 +808,16 @@ fi DEBUG 2 "Selected DE $DE" +# sanitize BROWSER (avoid caling ourselves in particular) +case "${BROWSER}" in + *:"xdg-open"|"xdg-open":*) + BROWSER=$(echo $BROWSER | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g') + ;; + "xdg-open") + BROWSER= + ;; +esac + # if BROWSER variable is not set, check some well known browsers instead if [ x"$BROWSER" = x"" ]; then BROWSER=links2:elinks:links:lynx:w3m @@ -757,6 +847,10 @@ case "$DE" in open_lxde "$url" ;; + enlightenment) + open_enlightenment "$url" + ;; + generic) open_generic "$url" ;; diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/index.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/index.js new file mode 100644 index 00000000000..777377a1f77 --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = typeof Promise === 'function' ? Promise : require('pinkie'); diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/license b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/license new file mode 100644 index 00000000000..1aeb74fd25e --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Vsevolod Strukchinsky (github.com/floatdrop) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/package.json b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/package.json new file mode 100644 index 00000000000..a02e8f465e0 --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/package.json @@ -0,0 +1,94 @@ +{ + "_args": [ + [ + "pinkie-promise@^2.0.0", + "/Users/Filippo/Documents/git/brackets/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn" + ] + ], + "_from": "pinkie-promise@>=2.0.0 <3.0.0", + "_id": "pinkie-promise@2.0.1", + "_inCache": true, + "_installable": true, + "_location": "/pinkie-promise", + "_nodeVersion": "4.4.1", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/pinkie-promise-2.0.1.tgz_1460309839126_0.3422858319245279" + }, + "_npmUser": { + "email": "floatdrop@gmail.com", + "name": "floatdrop" + }, + "_npmVersion": "2.14.20", + "_phantomChildren": {}, + "_requested": { + "name": "pinkie-promise", + "raw": "pinkie-promise@^2.0.0", + "rawSpec": "^2.0.0", + "scope": null, + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/opn" + ], + "_resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "_shasum": "2135d6dfa7a358c069ac9b178776288228450ffa", + "_shrinkwrap": null, + "_spec": "pinkie-promise@^2.0.0", + "_where": "/Users/Filippo/Documents/git/brackets/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/opn", + "author": { + "email": "floatdrop@gmail.com", + "name": "Vsevolod Strukchinsky", + "url": "github.com/floatdrop" + }, + "bugs": { + "url": "https://github.com/floatdrop/pinkie-promise/issues" + }, + "dependencies": { + "pinkie": "^2.0.0" + }, + "description": "ES2015 Promise ponyfill", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "2135d6dfa7a358c069ac9b178776288228450ffa", + "tarball": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "4a936c09c34ad591a25db93f1216d242de0d6184", + "homepage": "https://github.com/floatdrop/pinkie-promise", + "keywords": [ + "promise", + "promises", + "es2015", + "es6", + "polyfill", + "ponyfill" + ], + "license": "MIT", + "maintainers": [ + { + "email": "floatdrop@gmail.com", + "name": "floatdrop" + } + ], + "name": "pinkie-promise", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/floatdrop/pinkie-promise.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "2.0.1" +} diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/readme.md b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/readme.md new file mode 100644 index 00000000000..78477f4297d --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise/readme.md @@ -0,0 +1,28 @@ +# pinkie-promise [![Build Status](https://travis-ci.org/floatdrop/pinkie-promise.svg?branch=master)](https://travis-ci.org/floatdrop/pinkie-promise) + +> [ES2015 Promise](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) ponyfill + +Module exports global Promise object (if available) or [`pinkie`](http://github.com/floatdrop/pinkie) Promise polyfill. + +## Install + +``` +$ npm install --save pinkie-promise +``` + +## Usage + +```js +var Promise = require('pinkie-promise'); + +new Promise(function (resolve) { resolve('unicorns'); }); +//=> Promise { 'unicorns' } +``` + +## Related + +- [pify](https://github.com/sindresorhus/pify) - Promisify a callback-style function + +## License + +MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop) diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/index.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/index.js new file mode 100644 index 00000000000..14ce1bfe3d4 --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/index.js @@ -0,0 +1,292 @@ +'use strict'; + +var PENDING = 'pending'; +var SETTLED = 'settled'; +var FULFILLED = 'fulfilled'; +var REJECTED = 'rejected'; +var NOOP = function () {}; +var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; + +var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; +var asyncQueue = []; +var asyncTimer; + +function asyncFlush() { + // run promise callbacks + for (var i = 0; i < asyncQueue.length; i++) { + asyncQueue[i][0](asyncQueue[i][1]); + } + + // reset async asyncQueue + asyncQueue = []; + asyncTimer = false; +} + +function asyncCall(callback, arg) { + asyncQueue.push([callback, arg]); + + if (!asyncTimer) { + asyncTimer = true; + asyncSetTimer(asyncFlush, 0); + } +} + +function invokeResolver(resolver, promise) { + function resolvePromise(value) { + resolve(promise, value); + } + + function rejectPromise(reason) { + reject(promise, reason); + } + + try { + resolver(resolvePromise, rejectPromise); + } catch (e) { + rejectPromise(e); + } +} + +function invokeCallback(subscriber) { + var owner = subscriber.owner; + var settled = owner._state; + var value = owner._data; + var callback = subscriber[settled]; + var promise = subscriber.then; + + if (typeof callback === 'function') { + settled = FULFILLED; + try { + value = callback(value); + } catch (e) { + reject(promise, e); + } + } + + if (!handleThenable(promise, value)) { + if (settled === FULFILLED) { + resolve(promise, value); + } + + if (settled === REJECTED) { + reject(promise, value); + } + } +} + +function handleThenable(promise, value) { + var resolved; + + try { + if (promise === value) { + throw new TypeError('A promises callback cannot return that same promise.'); + } + + if (value && (typeof value === 'function' || typeof value === 'object')) { + // then should be retrieved only once + var then = value.then; + + if (typeof then === 'function') { + then.call(value, function (val) { + if (!resolved) { + resolved = true; + + if (value === val) { + fulfill(promise, val); + } else { + resolve(promise, val); + } + } + }, function (reason) { + if (!resolved) { + resolved = true; + + reject(promise, reason); + } + }); + + return true; + } + } + } catch (e) { + if (!resolved) { + reject(promise, e); + } + + return true; + } + + return false; +} + +function resolve(promise, value) { + if (promise === value || !handleThenable(promise, value)) { + fulfill(promise, value); + } +} + +function fulfill(promise, value) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = value; + + asyncCall(publishFulfillment, promise); + } +} + +function reject(promise, reason) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = reason; + + asyncCall(publishRejection, promise); + } +} + +function publish(promise) { + promise._then = promise._then.forEach(invokeCallback); +} + +function publishFulfillment(promise) { + promise._state = FULFILLED; + publish(promise); +} + +function publishRejection(promise) { + promise._state = REJECTED; + publish(promise); + if (!promise._handled && isNode) { + global.process.emit('unhandledRejection', promise._data, promise); + } +} + +function notifyRejectionHandled(promise) { + global.process.emit('rejectionHandled', promise); +} + +/** + * @class + */ +function Promise(resolver) { + if (typeof resolver !== 'function') { + throw new TypeError('Promise resolver ' + resolver + ' is not a function'); + } + + if (this instanceof Promise === false) { + throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); + } + + this._then = []; + + invokeResolver(resolver, this); +} + +Promise.prototype = { + constructor: Promise, + + _state: PENDING, + _then: null, + _data: undefined, + _handled: false, + + then: function (onFulfillment, onRejection) { + var subscriber = { + owner: this, + then: new this.constructor(NOOP), + fulfilled: onFulfillment, + rejected: onRejection + }; + + if ((onRejection || onFulfillment) && !this._handled) { + this._handled = true; + if (this._state === REJECTED && isNode) { + asyncCall(notifyRejectionHandled, this); + } + } + + if (this._state === FULFILLED || this._state === REJECTED) { + // already resolved, call callback async + asyncCall(invokeCallback, subscriber); + } else { + // subscribe + this._then.push(subscriber); + } + + return subscriber.then; + }, + + catch: function (onRejection) { + return this.then(null, onRejection); + } +}; + +Promise.all = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.all().'); + } + + return new Promise(function (resolve, reject) { + var results = []; + var remaining = 0; + + function resolver(index) { + remaining++; + return function (value) { + results[index] = value; + if (!--remaining) { + resolve(results); + } + }; + } + + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; + + if (promise && typeof promise.then === 'function') { + promise.then(resolver(i), reject); + } else { + results[i] = promise; + } + } + + if (!remaining) { + resolve(results); + } + }); +}; + +Promise.race = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.race().'); + } + + return new Promise(function (resolve, reject) { + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; + + if (promise && typeof promise.then === 'function') { + promise.then(resolve, reject); + } else { + resolve(promise); + } + } + }); +}; + +Promise.resolve = function (value) { + if (value && typeof value === 'object' && value.constructor === Promise) { + return value; + } + + return new Promise(function (resolve) { + resolve(value); + }); +}; + +Promise.reject = function (reason) { + return new Promise(function (resolve, reject) { + reject(reason); + }); +}; + +module.exports = Promise; diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/license b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/license new file mode 100644 index 00000000000..1aeb74fd25e --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Vsevolod Strukchinsky (github.com/floatdrop) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/package.json b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/package.json new file mode 100644 index 00000000000..096b2057a3a --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/package.json @@ -0,0 +1,92 @@ +{ + "_args": [ + [ + "pinkie@^2.0.0", + "/Users/Filippo/Documents/git/brackets/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise" + ] + ], + "_from": "pinkie@>=2.0.0 <3.0.0", + "_id": "pinkie@2.0.4", + "_inCache": true, + "_installable": true, + "_location": "/pinkie", + "_nodeVersion": "4.2.4", + "_npmUser": { + "email": "floatdrop@gmail.com", + "name": "floatdrop" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "name": "pinkie", + "raw": "pinkie@^2.0.0", + "rawSpec": "^2.0.0", + "scope": null, + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/pinkie-promise" + ], + "_resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "_shasum": "72556b80cfa0d48a974e80e77248e80ed4f7f870", + "_shrinkwrap": null, + "_spec": "pinkie@^2.0.0", + "_where": "/Users/Filippo/Documents/git/brackets/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie-promise", + "author": { + "email": "floatdrop@gmail.com", + "name": "Vsevolod Strukchinsky", + "url": "github.com/floatdrop" + }, + "bugs": { + "url": "https://github.com/floatdrop/pinkie/issues" + }, + "dependencies": {}, + "description": "Itty bitty little widdle twinkie pinkie ES2015 Promise implementation", + "devDependencies": { + "core-assert": "^0.1.1", + "coveralls": "^2.11.4", + "mocha": "*", + "nyc": "^3.2.2", + "promises-aplus-tests": "*", + "xo": "^0.10.1" + }, + "directories": {}, + "dist": { + "shasum": "72556b80cfa0d48a974e80e77248e80ed4f7f870", + "tarball": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "8d4a92447a5c62bff9f89756caeb4c9c8770579b", + "homepage": "https://github.com/floatdrop/pinkie", + "keywords": [ + "promise", + "promises", + "es2015", + "es6" + ], + "license": "MIT", + "maintainers": [ + { + "email": "floatdrop@gmail.com", + "name": "floatdrop" + } + ], + "name": "pinkie", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/floatdrop/pinkie.git" + }, + "scripts": { + "coverage": "nyc report --reporter=text-lcov | coveralls", + "test": "xo && nyc mocha" + }, + "version": "2.0.4" +} diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/readme.md b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/readme.md new file mode 100644 index 00000000000..1565f958896 --- /dev/null +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/node_modules/pinkie/readme.md @@ -0,0 +1,83 @@ +

+
+ pinkie +
+
+

+ +> Itty bitty little widdle twinkie pinkie [ES2015 Promise](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) implementation + +[![Build Status](https://travis-ci.org/floatdrop/pinkie.svg?branch=master)](https://travis-ci.org/floatdrop/pinkie) [![Coverage Status](https://coveralls.io/repos/floatdrop/pinkie/badge.svg?branch=master&service=github)](https://coveralls.io/github/floatdrop/pinkie?branch=master) + +There are [tons of Promise implementations](https://github.com/promises-aplus/promises-spec/blob/master/implementations.md#standalone) out there, but all of them focus on browser compatibility and are often bloated with functionality. + +This module is an exact Promise specification polyfill (like [native-promise-only](https://github.com/getify/native-promise-only)), but in Node.js land (it should be browserify-able though). + + +## Install + +``` +$ npm install --save pinkie +``` + + +## Usage + +```js +var fs = require('fs'); +var Promise = require('pinkie'); + +new Promise(function (resolve, reject) { + fs.readFile('foo.json', 'utf8', function (err, data) { + if (err) { + reject(err); + return; + } + + resolve(data); + }); +}); +//=> Promise +``` + + +### API + +`pinkie` exports bare [ES2015 Promise](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) implementation and polyfills [Node.js rejection events](https://nodejs.org/api/process.html#process_event_unhandledrejection). In case you forgot: + +#### new Promise(executor) + +Returns new instance of `Promise`. + +##### executor + +*Required* +Type: `function` + +Function with two arguments `resolve` and `reject`. The first argument fulfills the promise, the second argument rejects it. + +#### pinkie.all(promises) + +Returns a promise that resolves when all of the promises in the `promises` Array argument have resolved. + +#### pinkie.race(promises) + +Returns a promise that resolves or rejects as soon as one of the promises in the `promises` Array resolves or rejects, with the value or reason from that promise. + +#### pinkie.reject(reason) + +Returns a Promise object that is rejected with the given `reason`. + +#### pinkie.resolve(value) + +Returns a Promise object that is resolved with the given `value`. If the `value` is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the `value`. + + +## Related + +- [pinkie-promise](https://github.com/floatdrop/pinkie-promise) - Returns the native Promise or this module + + +## License + +MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop) diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/package.json b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/package.json index 83cdf737498..994a54144c5 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/package.json +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/package.json @@ -1,6 +1,6 @@ { "name": "livedev-multibrowser-launchers", "dependencies": { - "open": "0.0.4" + "opn": "4.0.2" } } diff --git a/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js b/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js index 750fa4d5511..56d0874294e 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js +++ b/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ - /** * Provides the protocol that Brackets uses to talk to a browser instance for live development. * Protocol methods are converted to a JSON message format, which is then sent over a provided diff --git a/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js b/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js index e81cac6fb50..e067c257395 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js +++ b/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js @@ -21,7 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ /*global setInterval, clearInterval */ (function (global) { @@ -84,8 +83,8 @@ } }; //iterate on document.stylesheets (StyleSheetList doesn't provide forEach iterator). - for (j = 0; j < document.styleSheets.length; j++) { - s = document.styleSheets[j]; + for (j = 0; j < window.document.styleSheets.length; j++) { + s = window.document.styleSheets[j]; traverseRules(s, s.href); } return rel; @@ -141,8 +140,8 @@ // TODO: This is just a temporary 'cross-browser' solution, it needs optimization. var loadInterval = setInterval(function () { var i; - for (i = 0; i < document.styleSheets.length; i++) { - if (document.styleSheets[i].href === href) { + for (i = 0; i < window.document.styleSheets.length; i++) { + if (window.document.styleSheets[i].href === href) { //clear interval clearInterval(loadInterval); // notify stylesheets added @@ -155,7 +154,7 @@ onStylesheetRemoved : function (url) { // get style node created when setting new text for stylesheet. - var s = document.getElementById(url); + var s = window.document.getElementById(url); // remove if (s && s.parentNode && s.parentNode.removeChild) { s.parentNode.removeChild(s); @@ -285,10 +284,10 @@ }); } else { // use MutationEvents as fallback - document.addEventListener('DOMNodeInserted', function niLstnr(e) { + window.document.addEventListener('DOMNodeInserted', function niLstnr(e) { _onNodesAdded([e.target]); }); - document.addEventListener('DOMNodeRemoved', function nrLstnr(e) { + window.document.addEventListener('DOMNodeRemoved', function nrLstnr(e) { _onNodesRemoved([e.target]); }); } diff --git a/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js b/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js index 2dd0cfda511..da2d0ad324e 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js +++ b/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js @@ -21,7 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ /*jslint evil: true */ // This is the script that Brackets live development injects into HTML pages in order to @@ -165,14 +164,14 @@ var i, node; - var head = document.getElementsByTagName('head')[0]; + var head = window.document.getElementsByTagName('head')[0]; // create an style element to replace the one loaded with - var s = document.createElement('style'); + var s = window.document.createElement('style'); s.type = 'text/css'; - s.appendChild(document.createTextNode(msg.params.text)); + s.appendChild(window.document.createTextNode(msg.params.text)); - for (i = 0; i < document.styleSheets.length; i++) { - node = document.styleSheets[i]; + for (i = 0; i < window.document.styleSheets.length; i++) { + node = window.document.styleSheets[i]; if (node.ownerNode.id === msg.params.url) { head.insertBefore(s, node.ownerNode); // insert the style element here // now can remove the style element previously created (if any) @@ -195,8 +194,8 @@ var i, sheet, text = ""; - for (i = 0; i < document.styleSheets.length; i++) { - sheet = document.styleSheets[i]; + for (i = 0; i < window.document.styleSheets.length; i++) { + sheet = window.document.styleSheets[i]; // if it was already 'reloaded' if (sheet.ownerNode.id === msg.params.url) { text = sheet.ownerNode.textContent; @@ -207,7 +206,7 @@ // Deal with Firefox's SecurityError when accessing sheets // from other domains, and Chrome returning `undefined`. try { - rules = document.styleSheets[i].cssRules; + rules = window.document.styleSheets[i].cssRules; } catch (e) { if (e.name !== "SecurityError") { throw e; @@ -286,10 +285,10 @@ }, onClose: function () { - var body = document.getElementsByTagName("body")[0], - overlay = document.createElement("div"), - background = document.createElement("div"), - status = document.createElement("div"); + var body = window.document.getElementsByTagName("body")[0], + overlay = window.document.createElement("div"), + background = window.document.createElement("div"), + status = window.document.createElement("div"); overlay.style.width = "100%"; overlay.style.height = "100%"; @@ -321,7 +320,7 @@ body.appendChild(overlay); // change the title as well - document.title = "(Brackets Live Preview: closed) " + document.title; + window.document.title = "(Brackets Live Preview: closed) " + window.document.title; }, setDocumentObserver: function (documentOberver) { diff --git a/src/LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport.js b/src/LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport.js index effa7f1b197..8da368ecf31 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport.js +++ b/src/LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - // This transport provides a WebSocket connection between Brackets and a live browser preview. // This is just a thin wrapper around the Node extension (NodeSocketTransportDomain) that actually // provides the WebSocket server and handles the communication. We also rely on an injected script in diff --git a/src/LiveDevelopment/MultiBrowserImpl/transports/node/NodeSocketTransportDomain.js b/src/LiveDevelopment/MultiBrowserImpl/transports/node/NodeSocketTransportDomain.js index 53c5b75ce3d..3e98ae10eb4 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/transports/node/NodeSocketTransportDomain.js +++ b/src/LiveDevelopment/MultiBrowserImpl/transports/node/NodeSocketTransportDomain.js @@ -21,227 +21,224 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, node: true */ - -(function () { - "use strict"; - - var WebSocketServer = require("ws").Server, - _ = require("lodash"); - - /** - * @private - * The WebSocket server we listen for incoming connections on. - * @type {?WebSocketServer} - */ - var _wsServer; - - /** - * @private - * The Brackets domain manager for registering node extensions. - * @type {?DomainManager} - */ - var _domainManager; - - /** - * @private - * The ID that should be allocated to the next client that connects to the transport. - * @type {number} - */ - var _nextClientId = 1; - - /** - * @private - * A map of client IDs to the URL and WebSocket for the given ID. - * @type {Object.} - */ - var _clients = {}; - - // This must match the port declared in NodeSocketTransport.js. - // TODO: randomize this? - var SOCKET_PORT = 8123; - - /** - * @private - * Returns the client info for a given WebSocket, or null if that socket isn't registered. - * @param {WebSocket} ws - * @return {?{id: number, url: string, socket: WebSocket}} - */ - function _clientForSocket(ws) { - return _.find(_clients, function (client) { - return (client.socket === ws); - }); - } +/*eslint-env node */ +/*jslint node: true */ +"use strict"; - /** - * @private - * Creates the WebSocketServer and handles incoming connections. - */ - function _createServer() { - if (!_wsServer) { - // TODO: make port configurable, or use random port - _wsServer = new WebSocketServer({port: SOCKET_PORT}); - _wsServer.on("connection", function (ws) { - ws.on("message", function (msg) { - console.log("WebSocketServer - received - " + msg); - var msgObj; - try { - msgObj = JSON.parse(msg); - } catch (e) { - console.error("nodeSocketTransport: Error parsing message: " + msg); - return; - } +var WebSocketServer = require("ws").Server, + _ = require("lodash"); - // See the comment in NodeSocketTransportRemote.connect() for why we have an extra - // layer of transport-layer message objects surrounding the protocol messaging. - - if (msgObj.type === "connect") { - if (!msgObj.url) { - console.error("nodeSocketTransport: Malformed connect message: " + msg); - return; - } - var clientId = _nextClientId++; - _clients[clientId] = { - id: clientId, - url: msgObj.url, - socket: ws - }; - console.log("emitting connect event"); - _domainManager.emitEvent("nodeSocketTransport", "connect", [clientId, msgObj.url]); - } else if (msgObj.type === "message") { - var client = _clientForSocket(ws); - if (client) { - _domainManager.emitEvent("nodeSocketTransport", "message", [client.id, msgObj.message]); - } else { - console.error("nodeSocketTransport: Couldn't locate client for message: " + msg); - } - } else { - console.error("nodeSocketTransport: Got bad socket message type: " + msg); +/** + * @private + * The WebSocket server we listen for incoming connections on. + * @type {?WebSocketServer} + */ +var _wsServer; + +/** + * @private + * The Brackets domain manager for registering node extensions. + * @type {?DomainManager} + */ +var _domainManager; + +/** + * @private + * The ID that should be allocated to the next client that connects to the transport. + * @type {number} + */ +var _nextClientId = 1; + +/** + * @private + * A map of client IDs to the URL and WebSocket for the given ID. + * @type {Object.} + */ +var _clients = {}; + +// This must match the port declared in NodeSocketTransport.js. +// TODO: randomize this? +var SOCKET_PORT = 8123; + +/** + * @private + * Returns the client info for a given WebSocket, or null if that socket isn't registered. + * @param {WebSocket} ws + * @return {?{id: number, url: string, socket: WebSocket}} + */ +function _clientForSocket(ws) { + return _.find(_clients, function (client) { + return (client.socket === ws); + }); +} + +/** + * @private + * Creates the WebSocketServer and handles incoming connections. + */ +function _createServer() { + if (!_wsServer) { + // TODO: make port configurable, or use random port + _wsServer = new WebSocketServer({port: SOCKET_PORT}); + _wsServer.on("connection", function (ws) { + ws.on("message", function (msg) { + console.log("WebSocketServer - received - " + msg); + var msgObj; + try { + msgObj = JSON.parse(msg); + } catch (e) { + console.error("nodeSocketTransport: Error parsing message: " + msg); + return; + } + + // See the comment in NodeSocketTransportRemote.connect() for why we have an extra + // layer of transport-layer message objects surrounding the protocol messaging. + + if (msgObj.type === "connect") { + if (!msgObj.url) { + console.error("nodeSocketTransport: Malformed connect message: " + msg); + return; } - }).on("error", function (e) { - // TODO: emit error event - var client = _clientForSocket(ws); - console.error("nodeSocketTransport: Error on socket for client " + JSON.stringify(client) + ": " + e); - }).on("close", function () { + var clientId = _nextClientId++; + _clients[clientId] = { + id: clientId, + url: msgObj.url, + socket: ws + }; + console.log("emitting connect event"); + _domainManager.emitEvent("nodeSocketTransport", "connect", [clientId, msgObj.url]); + } else if (msgObj.type === "message") { var client = _clientForSocket(ws); if (client) { - _domainManager.emitEvent("nodeSocketTransport", "close", [client.id]); - delete _clients[client.id]; + _domainManager.emitEvent("nodeSocketTransport", "message", [client.id, msgObj.message]); } else { - console.error("nodeSocketTransport: Socket closed, but couldn't locate client"); + console.error("nodeSocketTransport: Couldn't locate client for message: " + msg); } - }); + } else { + console.error("nodeSocketTransport: Got bad socket message type: " + msg); + } }).on("error", function (e) { // TODO: emit error event - console.error("nodeSocketTransport: Error on live preview server creation: " + e); + var client = _clientForSocket(ws); + console.error("nodeSocketTransport: Error on socket for client " + JSON.stringify(client) + ": " + e); + }).on("close", function () { + var client = _clientForSocket(ws); + if (client) { + _domainManager.emitEvent("nodeSocketTransport", "close", [client.id]); + delete _clients[client.id]; + } else { + console.error("nodeSocketTransport: Socket closed, but couldn't locate client"); + } }); - } + }).on("error", function (e) { + // TODO: emit error event + console.error("nodeSocketTransport: Error on live preview server creation: " + e); + }); } +} - /** - * Initializes the socket server. - * @param {string} url - */ - function _cmdStart(url) { - _createServer(); +/** + * Initializes the socket server. + * @param {string} url + */ +function _cmdStart(url) { + _createServer(); +} + +/** + * Sends a transport-layer message over the socket. + * @param {number|Array.} idOrArray A client ID or array of client IDs to send the message to. + * @param {string} msgStr The message to send as a JSON string. + */ +function _cmdSend(idOrArray, msgStr) { + if (!Array.isArray(idOrArray)) { + idOrArray = [idOrArray]; } - - /** - * Sends a transport-layer message over the socket. - * @param {number|Array.} idOrArray A client ID or array of client IDs to send the message to. - * @param {string} msgStr The message to send as a JSON string. - */ - function _cmdSend(idOrArray, msgStr) { - if (!Array.isArray(idOrArray)) { - idOrArray = [idOrArray]; + idOrArray.forEach(function (id) { + var client = _clients[id]; + if (!client) { + console.error("nodeSocketTransport: Couldn't find client ID: " + id); + } else { + client.socket.send(msgStr); } - idOrArray.forEach(function (id) { - var client = _clients[id]; - if (!client) { - console.error("nodeSocketTransport: Couldn't find client ID: " + id); - } else { - client.socket.send(msgStr); - } - }); - } + }); +} - /** - * Closes the connection for a given client ID. - * @param {number} clientId - */ - function _cmdClose(clientId) { - var client = _clients[clientId]; - if (client) { - client.socket.close(); - delete _clients[clientId]; - } +/** + * Closes the connection for a given client ID. + * @param {number} clientId + */ +function _cmdClose(clientId) { + var client = _clients[clientId]; + if (client) { + client.socket.close(); + delete _clients[clientId]; } +} - /** - * Initializes the domain and registers commands. - * @param {DomainManager} domainManager The DomainManager for the server - */ - function init(domainManager) { - _domainManager = domainManager; - if (!domainManager.hasDomain("nodeSocketTransport")) { - domainManager.registerDomain("nodeSocketTransport", {major: 0, minor: 1}); - } - domainManager.registerCommand( - "nodeSocketTransport", // domain name - "start", // command name - _cmdStart, // command handler function - false, // this command is synchronous in Node - "Creates the WS server", - [] - ); - domainManager.registerCommand( - "nodeSocketTransport", // domain name - "send", // command name - _cmdSend, // command handler function - false, // this command is synchronous in Node - "Sends a message to a given client or list of clients", - [ - {name: "idOrArray", type: "number|Array.", description: "id or array of ids to send the message to"}, - {name: "message", type: "string", description: "JSON message to send"} - ], - [] - ); - domainManager.registerCommand( - "nodeSocketTransport", // domain name - "close", // command name - _cmdClose, // command handler function - false, // this command is synchronous in Node - "Closes the connection to a given client", - [ - {name: "id", type: "number", description: "id of connection to close"} - ], - [] - ); - domainManager.registerEvent( - "nodeSocketTransport", - "connect", - [ - {name: "clientID", type: "number", description: "ID of live preview page connecting to live development"}, - {name: "url", type: "string", description: "URL of page that live preview is connecting from"} - ] - ); - domainManager.registerEvent( - "nodeSocketTransport", - "message", - [ - {name: "clientID", type: "number", description: "ID of live preview page sending message"}, - {name: "msg", type: "string", description: "JSON message from client page"} - ] - ); - domainManager.registerEvent( - "nodeSocketTransport", - "close", - [ - {name: "clientID", type: "number", description: "ID of live preview page being closed"} - ] - ); +/** + * Initializes the domain and registers commands. + * @param {DomainManager} domainManager The DomainManager for the server + */ +function init(domainManager) { + _domainManager = domainManager; + if (!domainManager.hasDomain("nodeSocketTransport")) { + domainManager.registerDomain("nodeSocketTransport", {major: 0, minor: 1}); } - - exports.init = init; - -}()); + domainManager.registerCommand( + "nodeSocketTransport", // domain name + "start", // command name + _cmdStart, // command handler function + false, // this command is synchronous in Node + "Creates the WS server", + [] + ); + domainManager.registerCommand( + "nodeSocketTransport", // domain name + "send", // command name + _cmdSend, // command handler function + false, // this command is synchronous in Node + "Sends a message to a given client or list of clients", + [ + {name: "idOrArray", type: "number|Array.", description: "id or array of ids to send the message to"}, + {name: "message", type: "string", description: "JSON message to send"} + ], + [] + ); + domainManager.registerCommand( + "nodeSocketTransport", // domain name + "close", // command name + _cmdClose, // command handler function + false, // this command is synchronous in Node + "Closes the connection to a given client", + [ + {name: "id", type: "number", description: "id of connection to close"} + ], + [] + ); + domainManager.registerEvent( + "nodeSocketTransport", + "connect", + [ + {name: "clientID", type: "number", description: "ID of live preview page connecting to live development"}, + {name: "url", type: "string", description: "URL of page that live preview is connecting from"} + ] + ); + domainManager.registerEvent( + "nodeSocketTransport", + "message", + [ + {name: "clientID", type: "number", description: "ID of live preview page sending message"}, + {name: "msg", type: "string", description: "JSON message from client page"} + ] + ); + domainManager.registerEvent( + "nodeSocketTransport", + "close", + [ + {name: "clientID", type: "number", description: "ID of live preview page being closed"} + ] + ); +} + +exports.init = init; diff --git a/src/LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js b/src/LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js index fc9fbf4e0ab..1e338bfe5f0 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js +++ b/src/LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js @@ -21,9 +21,6 @@ * */ -/*jslint browser: true, vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global WebSocket */ - // This is a transport injected into the browser via a script that handles the low // level communication between the live development protocol handlers on both sides. // This transport provides a web socket mechanism. It's injected separately from the diff --git a/src/LiveDevelopment/Servers/BaseServer.js b/src/LiveDevelopment/Servers/BaseServer.js index ae290c73e13..9337b79dfc8 100644 --- a/src/LiveDevelopment/Servers/BaseServer.js +++ b/src/LiveDevelopment/Servers/BaseServer.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $ */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; diff --git a/src/LiveDevelopment/Servers/FileServer.js b/src/LiveDevelopment/Servers/FileServer.js index 6e0214747f2..916e4d3a687 100644 --- a/src/LiveDevelopment/Servers/FileServer.js +++ b/src/LiveDevelopment/Servers/FileServer.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/LiveDevelopment/Servers/UserServer.js b/src/LiveDevelopment/Servers/UserServer.js index cdb626d490f..322ae9d7c9c 100644 --- a/src/LiveDevelopment/Servers/UserServer.js +++ b/src/LiveDevelopment/Servers/UserServer.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/LiveDevelopment/main.js b/src/LiveDevelopment/main.js index eedfb8d6969..dd48f245148 100644 --- a/src/LiveDevelopment/main.js +++ b/src/LiveDevelopment/main.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ -/*global define, $, less, window */ +/*global less */ /** * main integrates LiveDevelopment into Brackets diff --git a/src/brackets.js b/src/brackets.js index 7fb832ee3ca..3700412e5ae 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets: true, $, window, navigator, jQuery */ +/*global jQuery */ // TODO: (issue #264) break out the definition of brackets into a separate module from the application controller logic @@ -244,7 +242,7 @@ define(function (require, exports, module) { // Use quiet scrollbars if we aren't on Lion. If we're on Lion, only // use native scroll bars when the mouse is not plugged in or when // using the "Always" scroll bar setting. - var osxMatch = /Mac OS X 10\D([\d+])\D/.exec(navigator.userAgent); + var osxMatch = /Mac OS X 10\D([\d+])\D/.exec(window.navigator.userAgent); if (osxMatch && osxMatch[1] && Number(osxMatch[1]) >= 7) { // test a scrolling div for scrollbars var $testDiv = $("
").appendTo(window.document.body); diff --git a/src/command/CommandManager.js b/src/command/CommandManager.js index 062451a4a1a..c598c2e24d5 100644 --- a/src/command/CommandManager.js +++ b/src/command/CommandManager.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * Manages global application commands that can be called from menu items, key bindings, or subparts * of the application. diff --git a/src/command/Commands.js b/src/command/Commands.js index 6306839e53f..03b1ec8d271 100644 --- a/src/command/Commands.js +++ b/src/command/Commands.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/command/DefaultMenus.js b/src/command/DefaultMenus.js index af0ca30f3ab..17f66609b2b 100644 --- a/src/command/DefaultMenus.js +++ b/src/command/DefaultMenus.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, $, brackets, window */ - /** * Initializes the default brackets menu items. */ @@ -255,6 +251,12 @@ define(function (require, exports, module) { // editor_cmenu.addMenuItem(Commands.NAVIGATE_JUMPTO_DEFINITION); editor_cmenu.addMenuItem(Commands.TOGGLE_QUICK_EDIT); editor_cmenu.addMenuItem(Commands.TOGGLE_QUICK_DOCS); + editor_cmenu.addMenuDivider(); + editor_cmenu.addMenuItem(Commands.EDIT_CUT); + editor_cmenu.addMenuItem(Commands.EDIT_COPY); + editor_cmenu.addMenuItem(Commands.EDIT_PASTE); + + editor_cmenu.addMenuDivider(); editor_cmenu.addMenuItem(Commands.EDIT_SELECT_ALL); var inline_editor_cmenu = Menus.registerContextMenu(Menus.ContextMenuIds.INLINE_EDITOR_MENU); @@ -283,17 +285,13 @@ define(function (require, exports, module) { inlineWidget = EditorManager.getFocusedInlineWidget(); if (editor) { - // If there's just an insertion point select the word token at the cursor pos so - // it's more clear what the context menu applies to. - if (!editor.hasSelection()) { - editor.selectWordAt(editor.getCursorPos()); - + //if (!editor.hasSelection()) { // Prevent menu from overlapping text by moving it down a little // Temporarily backout this change for now to help mitigate issue #1111, // which only happens if mouse is not over context menu. Better fix // requires change to bootstrap, which is too risky for now. //e.pageY += 6; - } + //} // Inline text editors have a different context menu (safe to assume it's not some other // type of inline widget since we already know an Editor has focus) diff --git a/src/command/KeyBindingManager.js b/src/command/KeyBindingManager.js index 6d22616bc8e..8a2b95e070e 100644 --- a/src/command/KeyBindingManager.js +++ b/src/command/KeyBindingManager.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, $, brackets, window */ +/*jslint regexp: true */ /*unittests: KeyBindingManager */ /** diff --git a/src/command/Menus.js b/src/command/Menus.js index e1bdc973b5b..1a9ad4bc066 100644 --- a/src/command/Menus.js +++ b/src/command/Menus.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, window */ - define(function (require, exports, module) { "use strict"; @@ -182,6 +178,19 @@ define(function (require, exports, module) { return contextMenuMap[id]; } + /** + * Removes the attached event listeners from the corresponding object. + * @param {ManuItem} menuItem + */ + function removeMenuItemEventListeners(menuItem) { + menuItem._command + .off("enabledStateChange", menuItem._enabledChanged) + .off("checkedStateChange", menuItem._checkedChanged) + .off("nameChange", menuItem._nameChanged) + .off("keyBindingAdded", menuItem._keyBindingAdded) + .off("keyBindingRemoved", menuItem._keyBindingRemoved); + } + /** * Check whether a ContextMenu exists for the given id. * @param {string} id @@ -448,13 +457,15 @@ define(function (require, exports, module) { console.error("removeMenuItem(): command not found: " + command); return; } - commandID = command; } else { commandID = command.getID(); } menuItemID = this._getMenuItemId(commandID); + var menuItem = getMenuItem(menuItemID); + removeMenuItemEventListeners(menuItem); + if (_isHTMLMenu(this.id)) { // Targeting parent to get the menu item and the
  • that contains it $(_getHTMLMenuItem(menuItemID)).parent().remove(); diff --git a/src/config.json b/src/config.json index 0f67e9a58fb..e769d723bcd 100644 --- a/src/config.json +++ b/src/config.json @@ -23,8 +23,8 @@ "healthDataServerURL": "https://healthdev.brackets.io/healthDataLog" }, "name": "Brackets", - "version": "1.7.0-0", - "apiVersion": "1.7.0", + "version": "1.8.0-0", + "apiVersion": "1.8.0", "homepage": "http://brackets.io", "issues": { "url": "http://github.com/adobe/brackets/issues" @@ -35,7 +35,13 @@ "branch": "", "SHA": "" }, + "dependencies": { + "anymatch": "1.3.0", + "chokidar": "1.6.0", + "lodash": "4.15.0" + }, "devDependencies": { + "glob": "7.0.6", "grunt": "0.4.5", "jasmine-node": "1.11.0", "grunt-jasmine-node": "0.1.0", diff --git a/src/dependencies.js b/src/dependencies.js index afea3d43a2e..9da47afebfb 100644 --- a/src/dependencies.js +++ b/src/dependencies.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, evil:true */ -/*global window, document */ - /** * Check for missing dependencies */ @@ -48,6 +45,6 @@ window.setTimeout(function () { "

    If you're still having problems, please contact us via one of the channels mentioned at the bottom of the README.

    " + "

    Reload Brackets

    "; - document.write(str); + window.document.write(str); } }, 1000); diff --git a/src/document/ChangedDocumentTracker.js b/src/document/ChangedDocumentTracker.js index 36be7ea859d..ed36fd13a25 100644 --- a/src/document/ChangedDocumentTracker.js +++ b/src/document/ChangedDocumentTracker.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * Defines a ChangedDocumentTracker class to monitor changes to files in the current project. */ diff --git a/src/document/Document.js b/src/document/Document.js index 433b2dec688..a2ae75f52dc 100644 --- a/src/document/Document.js +++ b/src/document/Document.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/document/DocumentCommandHandlers.js b/src/document/DocumentCommandHandlers.js index 7d019e0ba2f..81ad7c55a4e 100644 --- a/src/document/DocumentCommandHandlers.js +++ b/src/document/DocumentCommandHandlers.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, $, brackets, window, WebSocket */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; @@ -1525,35 +1523,31 @@ define(function (require, exports, module) { /** Delete file command handler **/ function handleFileDelete() { var entry = ProjectManager.getSelectedItem(); - if (entry.isDirectory) { - Dialogs.showModalDialog( - DefaultDialogs.DIALOG_ID_EXT_DELETED, - Strings.CONFIRM_FOLDER_DELETE_TITLE, - StringUtils.format( - Strings.CONFIRM_FOLDER_DELETE, - StringUtils.breakableUrl(entry.name) - ), - [ - { - className : Dialogs.DIALOG_BTN_CLASS_NORMAL, - id : Dialogs.DIALOG_BTN_CANCEL, - text : Strings.CANCEL - }, - { - className : Dialogs.DIALOG_BTN_CLASS_PRIMARY, - id : Dialogs.DIALOG_BTN_OK, - text : Strings.DELETE - } - ] - ) - .done(function (id) { - if (id === Dialogs.DIALOG_BTN_OK) { - ProjectManager.deleteItem(entry); - } - }); - } else { - ProjectManager.deleteItem(entry); - } + Dialogs.showModalDialog( + DefaultDialogs.DIALOG_ID_EXT_DELETED, + Strings.CONFIRM_DELETE_TITLE, + StringUtils.format( + entry.isFile ? Strings.CONFIRM_FILE_DELETE : Strings.CONFIRM_FOLDER_DELETE, + StringUtils.breakableUrl(entry.name) + ), + [ + { + className : Dialogs.DIALOG_BTN_CLASS_NORMAL, + id : Dialogs.DIALOG_BTN_CANCEL, + text : Strings.CANCEL + }, + { + className : Dialogs.DIALOG_BTN_CLASS_PRIMARY, + id : Dialogs.DIALOG_BTN_OK, + text : Strings.DELETE + } + ] + ) + .done(function (id) { + if (id === Dialogs.DIALOG_BTN_OK) { + ProjectManager.deleteItem(entry); + } + }); } /** Show the selected sidebar (tree or workingset) item in Finder/Explorer */ diff --git a/src/document/DocumentManager.js b/src/document/DocumentManager.js index 94c20a6cd86..5f1958999db 100644 --- a/src/document/DocumentManager.js +++ b/src/document/DocumentManager.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * DocumentManager maintains a list of currently 'open' Documents. The DocumentManager is responsible * for coordinating document operations and dispatching certain document events. diff --git a/src/document/InMemoryFile.js b/src/document/InMemoryFile.js index babe149525d..4da2f23da34 100644 --- a/src/document/InMemoryFile.js +++ b/src/document/InMemoryFile.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Represents a file that will never exist on disk - a placeholder backing file for untitled Documents. NO ONE * other than DocumentManager should create instances of InMemoryFile. It is valid to test for one (`instanceof diff --git a/src/document/TextRange.js b/src/document/TextRange.js index fadd5a8691d..7eb5d9aa7e2 100644 --- a/src/document/TextRange.js +++ b/src/document/TextRange.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** */ define(function (require, exports, module) { diff --git a/src/editor/CSSInlineEditor.js b/src/editor/CSSInlineEditor.js index ec4f68edeab..363f722ed9c 100644 --- a/src/editor/CSSInlineEditor.js +++ b/src/editor/CSSInlineEditor.js @@ -21,10 +21,6 @@ * */ - -/*jslint regexp: true, vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/editor/CodeHintList.js b/src/editor/CodeHintList.js index dc73d8aadf6..0af254dafd7 100644 --- a/src/editor/CodeHintList.js +++ b/src/editor/CodeHintList.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - define(function (require, exports, module) { "use strict"; @@ -307,14 +304,21 @@ define(function (require, exports, module) { }; /** - * Check whether keyCode is one of the keys that we handle or not. + * Check whether Event is one of the keys that we handle or not. * - * @param {number} keyCode + * @param {KeyBoardEvent|keyBoardEvent.keyCode} keyEvent */ - CodeHintList.prototype.isHandlingKeyCode = function (keyCode) { + CodeHintList.prototype.isHandlingKeyCode = function (keyCodeOrEvent) { + var keyCode = typeof keyCodeOrEvent === "object" ? keyCodeOrEvent.keyCode : keyCodeOrEvent; + var ctrlKey = typeof keyCodeOrEvent === "object" ? keyCodeOrEvent.ctrlKey : false; + + return (keyCode === KeyEvent.DOM_VK_UP || keyCode === KeyEvent.DOM_VK_DOWN || keyCode === KeyEvent.DOM_VK_PAGE_UP || keyCode === KeyEvent.DOM_VK_PAGE_DOWN || keyCode === KeyEvent.DOM_VK_RETURN || + keyCode === KeyEvent.DOM_VK_CONTROL || + keyCode === KeyEvent.DOM_VK_ESCAPE || + (ctrlKey && keyCode === KeyEvent.DOM_VK_SPACE) || (keyCode === KeyEvent.DOM_VK_TAB && this.insertHintOnTab)); }; @@ -385,21 +389,26 @@ define(function (require, exports, module) { } // (page) up, (page) down, enter and tab key are handled by the list - if (event.type === "keydown" && this.isHandlingKeyCode(event.keyCode)) { + if (event.type === "keydown" && this.isHandlingKeyCode(event)) { keyCode = event.keyCode; - if (event.shiftKey && + if (event.keyCode === KeyEvent.DOM_VK_ESCAPE) { + event.stopImmediatePropagation(); + this.handleClose(); + + return false; + } else if (event.shiftKey && (event.keyCode === KeyEvent.DOM_VK_UP || event.keyCode === KeyEvent.DOM_VK_DOWN || event.keyCode === KeyEvent.DOM_VK_PAGE_UP || event.keyCode === KeyEvent.DOM_VK_PAGE_DOWN)) { this.handleClose(); - // Let the event bubble. return false; } else if (keyCode === KeyEvent.DOM_VK_UP) { _rotateSelection.call(this, -1); - } else if (keyCode === KeyEvent.DOM_VK_DOWN) { + } else if (keyCode === KeyEvent.DOM_VK_DOWN || + (event.ctrlKey && keyCode === KeyEvent.DOM_VK_SPACE)) { _rotateSelection.call(this, 1); } else if (keyCode === KeyEvent.DOM_VK_PAGE_UP) { _rotateSelection.call(this, -_itemsPerPage()); @@ -481,8 +490,6 @@ define(function (require, exports, module) { .css({"left": hintPos.left, "top": hintPos.top, "width": hintPos.width + "px"}); this.opened = true; - PopUpManager.addPopUp(this.$hintMenu, this.handleClose, true); - KeyBindingManager.addGlobalKeydownHook(this._keydownHook); } }; @@ -504,7 +511,16 @@ define(function (require, exports, module) { "width": hintPos.width + "px"}); } }; - + /** + * Calls the move up keybind to move hint suggestion selector + * + * @param {KeyBoardEvent} keyEvent + */ + CodeHintList.prototype.callMoveUp = function (event) { + delete event.type; + event.type = "keydown"; + this._keydownHook(event); + }; /** * Closes the hint list */ diff --git a/src/editor/CodeHintManager.js b/src/editor/CodeHintManager.js index c12cf27cabf..19d307aab81 100644 --- a/src/editor/CodeHintManager.js +++ b/src/editor/CodeHintManager.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /* * __CodeHintManager Overview:__ * @@ -249,7 +246,8 @@ define(function (require, exports, module) { hintList = null, deferredHints = null, keyDownEditor = null, - codeHintsEnabled = true; + codeHintsEnabled = true, + codeHintOpened = false; PreferencesManager.definePreference("showCodeHints", "boolean", true, { @@ -379,6 +377,7 @@ define(function (require, exports, module) { } hintList.close(); hintList = null; + codeHintOpened = false; keyDownEditor = null; sessionProvider = null; sessionEditor = null; @@ -410,19 +409,25 @@ define(function (require, exports, module) { } return false; } - /** * From an active hinting session, get hints from the current provider and * render the hint list window. * * Assumes that it is called when a session is active (i.e. sessionProvider is not null). */ - function _updateHintList() { + function _updateHintList(callMoveUpEvent) { + + callMoveUpEvent = typeof callMoveUpEvent === "undefined" ? false : callMoveUpEvent; + if (deferredHints) { deferredHints.reject(); deferredHints = null; } + if (callMoveUpEvent) { + return hintList.callMoveUp(callMoveUpEvent); + } + var response = sessionProvider.getHints(lastChar); lastChar = null; @@ -433,6 +438,7 @@ define(function (require, exports, module) { // if the response is true, end the session and begin another if (response === true) { var previousEditor = sessionEditor; + _endSession(); _beginSession(previousEditor); } else if (response.hasOwnProperty("hints")) { // a synchronous response @@ -469,6 +475,7 @@ define(function (require, exports, module) { * @param {Editor} editor */ _beginSession = function (editor) { + if (!codeHintsEnabled) { return; } @@ -500,7 +507,6 @@ define(function (require, exports, module) { } sessionEditor = editor; - hintList = new CodeHintList(sessionEditor, insertHintOnTab, maxCodeHints); hintList.onSelect(function (hint) { var restart = sessionProvider.insertHint(hint), @@ -518,26 +524,6 @@ define(function (require, exports, module) { } }; - /** - * Explicitly start a new session. If we have an existing session, - * then close the current one and restart a new one. - * @param {Editor} editor - */ - function _startNewSession(editor) { - if (!editor) { - editor = EditorManager.getFocusedEditor(); - } - - if (editor) { - lastChar = null; - if (_inSession(editor)) { - _endSession(); - } - // Begin a new explicit session - _beginSession(editor); - } - } - /** * Handles keys related to displaying, searching, and navigating the hint list. * This gets called before handleChange. @@ -574,7 +560,8 @@ define(function (require, exports, module) { function _handleKeyupEvent(jqEvent, editor, event) { keyDownEditor = editor; if (_inSession(editor)) { - if (event.keyCode === KeyEvent.DOM_VK_HOME || event.keyCode === KeyEvent.DOM_VK_END) { + if (event.keyCode === KeyEvent.DOM_VK_HOME || + event.keyCode === KeyEvent.DOM_VK_END) { _endSession(); } else if (event.keyCode === KeyEvent.DOM_VK_LEFT || event.keyCode === KeyEvent.DOM_VK_RIGHT || @@ -583,6 +570,8 @@ define(function (require, exports, module) { // We do this in "keyup" because we want the cursor position to be updated before // we redraw the list. _updateHintList(); + } else if (event.ctrlKey && event.keyCode === KeyEvent.DOM_VK_SPACE) { + _updateHintList(event); } } } @@ -667,6 +656,30 @@ define(function (require, exports, module) { return (hintList && hintList.isOpen()); } + /** + * Explicitly start a new session. If we have an existing session, + * then close the current one and restart a new one. + * @param {Editor} editor + */ + function _startNewSession(editor) { + if (isOpen()) { + return; + } + + if (!editor) { + editor = EditorManager.getFocusedEditor(); + } + if (editor) { + lastChar = null; + if (_inSession(editor)) { + _endSession(); + } + + // Begin a new explicit session + _beginSession(editor); + } + } + /** * Expose CodeHintList for unit testing */ @@ -696,12 +709,16 @@ define(function (require, exports, module) { activeEditorChangeHandler(null, EditorManager.getActiveEditor(), null); EditorManager.on("activeEditorChange", activeEditorChangeHandler); - - // Dismiss code hints before executing any command since the command + + // Dismiss code hints before executing any command other than showing code hints since the command // may make the current hinting session irrevalent after execution. // For example, when the user hits Ctrl+K to open Quick Doc, it is - // pointless to keep the hint list since the user wants to view the Quick Doc. - CommandManager.on("beforeExecuteCommand", _endSession); + // pointless to keep the hint list since the user wants to view the Quick Doc + CommandManager.on("beforeExecuteCommand", function (event, commandId) { + if (commandId !== Commands.SHOW_CODE_HINTS) { + _endSession(); + } + }); CommandManager.register(Strings.CMD_SHOW_CODE_HINTS, Commands.SHOW_CODE_HINTS, _startNewSession); diff --git a/src/editor/Editor.js b/src/editor/Editor.js index 7cf92d98beb..99203dc8341 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * Editor is a 1-to-1 wrapper for a CodeMirror editor instance. It layers on Brackets-specific * functionality and provides APIs that cleanly pass through the bits of CodeMirror that the rest @@ -88,6 +84,7 @@ define(function (require, exports, module) { CLOSE_TAGS = "closeTags", DRAG_DROP = "dragDropText", HIGHLIGHT_MATCHES = "highlightMatches", + LINEWISE_COPY_CUT = "lineWiseCopyCut", SCROLL_PAST_END = "scrollPastEnd", SHOW_CURSOR_SELECT = "showCursorWhenSelecting", SHOW_LINE_NUMBERS = "showLineNumbers", @@ -120,6 +117,7 @@ define(function (require, exports, module) { cmOptions[CLOSE_TAGS] = "autoCloseTags"; cmOptions[DRAG_DROP] = "dragDrop"; cmOptions[HIGHLIGHT_MATCHES] = "highlightSelectionMatches"; + cmOptions[LINEWISE_COPY_CUT] = "lineWiseCopyCut"; cmOptions[SCROLL_PAST_END] = "scrollPastEnd"; cmOptions[SHOW_CURSOR_SELECT] = "showCursorWhenSelecting"; cmOptions[SHOW_LINE_NUMBERS] = "lineNumbers"; @@ -174,6 +172,9 @@ define(function (require, exports, module) { } } }); + PreferencesManager.definePreference(LINEWISE_COPY_CUT, "boolean", true, { + description: Strings.DESCRIPTION_LINEWISE_COPY_CUT + }); PreferencesManager.definePreference(SCROLL_PAST_END, "boolean", false, { description: Strings.DESCRIPTION_SCROLL_PAST_END }); @@ -401,6 +402,7 @@ define(function (require, exports, module) { indentWithTabs : currentOptions[USE_TAB_CHAR], inputStyle : "textarea", // the "contenteditable" mode used on mobiles could cause issues lineNumbers : currentOptions[SHOW_LINE_NUMBERS], + lineWiseCopyCut : currentOptions[LINEWISE_COPY_CUT], lineWrapping : currentOptions[WORD_WRAP], matchBrackets : { maxScanLineLength: 50000, maxScanLines: 1000 }, matchTags : { bothTags: true }, @@ -1032,10 +1034,10 @@ define(function (require, exports, module) { }); // For word wrap. Code adapted from https://codemirror.net/demo/indentwrap.html# this._codeMirror.on("renderLine", function (cm, line, elt) { - var charWidth = self._codeMirror.defaultCharWidth(), basePadding = 4; + var charWidth = self._codeMirror.defaultCharWidth(); var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth; elt.style.textIndent = "-" + off + "px"; - elt.style.paddingLeft = (basePadding + off) + "px"; + elt.style.paddingLeft = off + "px"; }); }; @@ -1045,6 +1047,12 @@ define(function (require, exports, module) { * @param {!string} text */ Editor.prototype._resetText = function (text) { + var currentText = this._codeMirror.getValue(); + if (text === currentText) { + // there's nothing to reset + return; + } + var perfTimerName = PerfUtils.markStart("Editor._resetText()\t" + (!this.document || this.document.file.fullPath)); var cursorPos = this.getCursorPos(), diff --git a/src/editor/EditorCommandHandlers.js b/src/editor/EditorCommandHandlers.js index c3aa73859bb..3a0dcf7c457 100644 --- a/src/editor/EditorCommandHandlers.js +++ b/src/editor/EditorCommandHandlers.js @@ -21,10 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - - /** * Text-editing commands that apply to whichever Editor is currently focused */ @@ -210,7 +206,7 @@ define(function (require, exports, module) { line = doc.getLine(startLine); var originalCursorPosition = line.search(/\S|$/); - var firstCharPosition,cursorPosition = originalCursorPosition; + var firstCharPosition, cursorPosition = originalCursorPosition; for (i = startLine; i <= endLine; i++) { //check if preference for indent line comment is available otherwise go back to default indentation @@ -227,7 +223,7 @@ define(function (require, exports, module) { cursorPosition = originalCursorPosition; } - editGroup.push({text: prefixes[0], start: {line: i, ch: cursorPosition}}); + editGroup.push({text: prefixes[0], start: {line: i, ch: cursorPosition}}); } else { editGroup.push({text: prefixes[0], start: {line: i, ch: 0}}); } @@ -1117,17 +1113,7 @@ define(function (require, exports, module) { return handleUndoRedo("redo"); } - /** - * Special command handler that just ignores the command. This is used for Cut, Copy, and Paste. - * These menu items are handled natively, but need to be registered in our JavaScript code so the - * menu items can be created. - */ - function ignoreCommand() { - // Do nothing. The shell will call the native handler for the command. - return (new $.Deferred()).reject().promise(); - } - - function _handleSelectAll() { + function _handleSelectAll() { var result = new $.Deferred(), editor = EditorManager.getFocusedEditor(); @@ -1141,6 +1127,19 @@ define(function (require, exports, module) { return result.promise(); } + function _execCommand(cmd) { + window.document.execCommand(cmd); + } + function _execCommandCut() { + _execCommand("cut"); + } + function _execCommandCopy() { + _execCommand("copy"); + } + function _execCommandPaste() { + _execCommand("paste"); + } + // Register commands CommandManager.register(Strings.CMD_INDENT, Commands.EDIT_INDENT, indentText); CommandManager.register(Strings.CMD_UNINDENT, Commands.EDIT_UNINDENT, unindentText); @@ -1159,8 +1158,8 @@ define(function (require, exports, module) { CommandManager.register(Strings.CMD_UNDO, Commands.EDIT_UNDO, handleUndo); CommandManager.register(Strings.CMD_REDO, Commands.EDIT_REDO, handleRedo); - CommandManager.register(Strings.CMD_CUT, Commands.EDIT_CUT, ignoreCommand); - CommandManager.register(Strings.CMD_COPY, Commands.EDIT_COPY, ignoreCommand); - CommandManager.register(Strings.CMD_PASTE, Commands.EDIT_PASTE, ignoreCommand); + CommandManager.register(Strings.CMD_CUT, Commands.EDIT_CUT, _execCommandCut); + CommandManager.register(Strings.CMD_COPY, Commands.EDIT_COPY, _execCommandCopy); + CommandManager.register(Strings.CMD_PASTE, Commands.EDIT_PASTE, _execCommandPaste); CommandManager.register(Strings.CMD_SELECT_ALL, Commands.EDIT_SELECT_ALL, _handleSelectAll); }); diff --git a/src/editor/EditorManager.js b/src/editor/EditorManager.js index 2b1f4d53f39..026713a36a6 100644 --- a/src/editor/EditorManager.js +++ b/src/editor/EditorManager.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * EditorManager owns the UI for the editor area. This essentially mirrors the 'current document' * property maintained by DocumentManager's model. diff --git a/src/editor/EditorOptionHandlers.js b/src/editor/EditorOptionHandlers.js index 46152921f8e..216e9e2467f 100644 --- a/src/editor/EditorOptionHandlers.js +++ b/src/editor/EditorOptionHandlers.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/editor/EditorStatusBar.js b/src/editor/EditorStatusBar.js index 7baf9e407ec..9cec5fddaef 100644 --- a/src/editor/EditorStatusBar.js +++ b/src/editor/EditorStatusBar.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * Manages parts of the status bar related to the current editor's state. */ diff --git a/src/editor/ImageViewer.js b/src/editor/ImageViewer.js index 250e09831c6..ba24847b739 100644 --- a/src/editor/ImageViewer.js +++ b/src/editor/ImageViewer.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/editor/InlineTextEditor.js b/src/editor/InlineTextEditor.js index fd70e1439f4..62dfd36b121 100644 --- a/src/editor/InlineTextEditor.js +++ b/src/editor/InlineTextEditor.js @@ -23,8 +23,6 @@ // FUTURE: Merge part (or all) of this class with MultiRangeInlineEditor -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ define(function (require, exports, module) { "use strict"; diff --git a/src/editor/InlineWidget.js b/src/editor/InlineWidget.js index 2e7688934d3..0b00c50755b 100644 --- a/src/editor/InlineWidget.js +++ b/src/editor/InlineWidget.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/editor/MultiRangeInlineEditor.js b/src/editor/MultiRangeInlineEditor.js index 17154137ff5..1c055b0f2c3 100644 --- a/src/editor/MultiRangeInlineEditor.js +++ b/src/editor/MultiRangeInlineEditor.js @@ -23,9 +23,6 @@ // FUTURE: Merge part (or all) of this class with InlineTextEditor -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * An inline editor for displaying and editing multiple text ranges. Each range corresponds to a * contiguous set of lines in a file. diff --git a/src/extensibility/ExtensionManager.js b/src/extensibility/ExtensionManager.js index 47ffb9f5ee8..b6cc2d8ef01 100644 --- a/src/extensibility/ExtensionManager.js +++ b/src/extensibility/ExtensionManager.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets */ +/*jslint regexp: true */ /*unittests: ExtensionManager*/ /** diff --git a/src/extensibility/ExtensionManagerDialog.js b/src/extensibility/ExtensionManagerDialog.js index c692372923c..acfd61873fb 100644 --- a/src/extensibility/ExtensionManagerDialog.js +++ b/src/extensibility/ExtensionManagerDialog.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global brackets, define, $ */ - define(function (require, exports, module) { "use strict"; @@ -255,7 +252,7 @@ define(function (require, exports, module) { // new install or an update. Package.validate(path, { requirePackageJSON: true }).done(function (info) { if (info.errors.length) { - result.reject(Package.formatError(info.errors)); + result.reject(info.errors.map(Package.formatError).join(" ")); return; } @@ -312,6 +309,7 @@ define(function (require, exports, module) { views = [], $search, $searchClear, + $modalDlg, context = { Strings: Strings, showRegistry: !!brackets.config.extension_registry }, models = []; @@ -338,6 +336,7 @@ define(function (require, exports, module) { $search.val(""); views.forEach(function (view, index) { view.filter(""); + $modalDlg.scrollTop(0); }); if (!updateSearchDisabled()) { @@ -363,14 +362,15 @@ define(function (require, exports, module) { $dlg = dialog.getElement(); $search = $(".search", $dlg); $searchClear = $(".search-clear", $dlg); + $modalDlg = $(".modal-body", $dlg); function setActiveTab($tab) { if (models[_activeTabIndex]) { - models[_activeTabIndex].scrollPos = $(".modal-body", $dlg).scrollTop(); + models[_activeTabIndex].scrollPos = $modalDlg.scrollTop(); } $tab.tab("show"); if (models[_activeTabIndex]) { - $(".modal-body", $dlg).scrollTop(models[_activeTabIndex].scrollPos || 0); + $modalDlg.scrollTop(models[_activeTabIndex].scrollPos || 0); clearSearch(); } } @@ -437,7 +437,7 @@ define(function (require, exports, module) { $(".spinner", $dlg).remove(); views.forEach(function (view) { - view.$el.appendTo($(".modal-body", $dlg)); + view.$el.appendTo($modalDlg); }); // Update search UI before new tab is shown @@ -457,6 +457,7 @@ define(function (require, exports, module) { var query = $(this).val(); views.forEach(function (view) { view.filter(query); + $modalDlg.scrollTop(0); }); }).on("click", ".search-clear", clearSearch); diff --git a/src/extensibility/ExtensionManagerView.js b/src/extensibility/ExtensionManagerView.js index 8afe722964a..0bac5cdde1a 100644 --- a/src/extensibility/ExtensionManagerView.js +++ b/src/extensibility/ExtensionManagerView.js @@ -21,8 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, $, brackets, Mustache, PathUtils */ /*unittests: ExtensionManager*/ define(function (require, exports, module) { @@ -44,7 +42,7 @@ define(function (require, exports, module) { /** * Create a detached link element, so that we can use it later to extract url details like 'protocol' */ - var _tmpLink = document.createElement('a'); + var _tmpLink = window.document.createElement('a'); /** * Creates a view enabling the user to install and manage extensions. Must be initialized diff --git a/src/extensibility/ExtensionManagerViewModel.js b/src/extensibility/ExtensionManagerViewModel.js index a95b7cd3a65..90d30fe512e 100644 --- a/src/extensibility/ExtensionManagerViewModel.js +++ b/src/extensibility/ExtensionManagerViewModel.js @@ -21,8 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, $ */ /*unittests: ExtensionManager*/ define(function (require, exports, module) { diff --git a/src/extensibility/InstallExtensionDialog.js b/src/extensibility/InstallExtensionDialog.js index 631c78f2267..e11cace4324 100644 --- a/src/extensibility/InstallExtensionDialog.js +++ b/src/extensibility/InstallExtensionDialog.js @@ -21,8 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, window, $, brackets, document */ /*unittests: Install Extension Dialog*/ define(function (require, exports, module) { @@ -260,7 +258,7 @@ define(function (require, exports, module) { break; case STATE_CLOSED: - $(document.body).off(".installDialog"); + $(window.document.body).off(".installDialog"); // Only resolve as successful if we actually installed something. Dialogs.cancelModalDialogIfOpen("install-extension-dialog"); diff --git a/src/extensibility/Package.js b/src/extensibility/Package.js index f75453eb05b..1119f6779b2 100644 --- a/src/extensibility/Package.js +++ b/src/extensibility/Package.js @@ -21,10 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, regexp: true, -indent: 4, maxerr: 50 */ -/*global define, $, brackets */ +/*jslint regexp: true */ /** * Functions for working with extension packages diff --git a/src/extensibility/node/ExtensionManagerDomain.js b/src/extensibility/node/ExtensionManagerDomain.js index 6fa70e12ce8..3ebf219175d 100644 --- a/src/extensibility/node/ExtensionManagerDomain.js +++ b/src/extensibility/node/ExtensionManagerDomain.js @@ -21,9 +21,8 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, node: true, nomen: true, -indent: 4, maxerr: 50 */ +/*eslint-env node */ +/*jslint node: true */ "use strict"; diff --git a/src/extensibility/node/package-validator.js b/src/extensibility/node/package-validator.js index 3d086152224..b2b65458994 100644 --- a/src/extensibility/node/package-validator.js +++ b/src/extensibility/node/package-validator.js @@ -21,9 +21,8 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, node: true, nomen: true, -indent: 4, maxerr: 50, regexp: true */ +/*eslint-env node */ +/*jslint node: true, regexp: true */ "use strict"; diff --git a/src/extensibility/node/spec/Installation.spec.js b/src/extensibility/node/spec/Installation.spec.js index 7fad313a125..d86d71251da 100644 --- a/src/extensibility/node/spec/Installation.spec.js +++ b/src/extensibility/node/spec/Installation.spec.js @@ -21,9 +21,8 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, node: true, nomen: true, -indent: 4, maxerr: 50 */ +/*eslint-env node */ +/*jslint node: true */ /*global expect, describe, it, beforeEach, afterEach */ "use strict"; diff --git a/src/extensibility/node/spec/Validation.spec.js b/src/extensibility/node/spec/Validation.spec.js index ef85e5860e4..ab90688d012 100644 --- a/src/extensibility/node/spec/Validation.spec.js +++ b/src/extensibility/node/spec/Validation.spec.js @@ -21,9 +21,8 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, node: true, nomen: true, -indent: 4, maxerr: 50 */ +/*eslint-env node */ +/*jslint node: true */ /*global expect, describe, it, afterEach */ "use strict"; diff --git a/src/extensibility/registry_utils.js b/src/extensibility/registry_utils.js index 365ef38935b..57be44c6e29 100644 --- a/src/extensibility/registry_utils.js +++ b/src/extensibility/registry_utils.js @@ -29,9 +29,6 @@ * In the future, we should have a better mechanism for sharing code between the two. */ -/*jslint vars: true, plusplus: true, nomen: true, indent: 4, maxerr: 50 */ -/*global brackets, define*/ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/CSSCodeHints/CSSProperties.json b/src/extensions/default/CSSCodeHints/CSSProperties.json index 21c4c96e810..253729a1153 100644 --- a/src/extensions/default/CSSCodeHints/CSSProperties.json +++ b/src/extensions/default/CSSCodeHints/CSSProperties.json @@ -95,6 +95,7 @@ "flow-into": {"values": ["none"], "type": "named-flow"}, "flow-from": {"values": ["none", "inherit"], "type": "named-flow"}, "font": {"values": []}, + "font-display": {"values": ["auto", "block", "swap", "fallback", "optional"]}, "font-family": {"values": ["cursive", "fantasy", "inherit", "monospace", "sans-serif", "serif"]}, "font-feature-settings": {"values": ["normal"]}, "font-kerning": {"values": ["auto", "none", "normal"]}, @@ -112,6 +113,23 @@ "font-variant-numeric": {"values": ["normal"]}, "font-variant-position": {"values": ["normal", "sub", "super"]}, "font-weight": {"values": ["bold", "bolder", "lighter", "normal", "100", "200", "300", "400", "500", "600", "700", "800", "900", "inherit"]}, + "grid": {"values": []}, + "grid-area": {"values": []}, + "grid-auto-columns": {"values": []}, + "grid-auto-flow": {"values": ["row", "column", "dense"]}, + "grid-auto-rows": {"values": []}, + "grid-column": {"values": ["auto"]}, + "grid-column-end": {"values": []}, + "grid-column-gap": {"values": []}, + "grid-column-start": {"values": []}, + "grid-gap": {"values": []}, + "grid-row": {"values": ["auto"]}, + "grid-row-end": {"values": []}, + "grid-row-start": {"values": []}, + "grid-row-gap": {"values": []}, + "grid-template-areas": {"values": []}, + "grid-template-columns": {"values": ["auto"]}, + "grid-template-rows": {"values": ["auto"]}, "height": {"values": ["auto", "inherit"]}, "hyphens": {"values": ["auto", "manual", "none"]}, "image-orientation": {"values": []}, @@ -120,7 +138,7 @@ "left": {"values": ["auto", "inherit"]}, "letter-spacing": {"values": ["normal", "inherit"]}, "line-height": {"values": ["normal", "inherit"]}, - "list-style": {"values": ["armenian", "circle", "decimal", "decimal-leading-zero", "disc", "georgian", "inherit", "inside", "lower-alpha", "lower-greek", "lower-latin", "lower-roman", "none", "outside", "square", "upper-alpha", "upper-latin", "upper-roman", "url()"]}, + "list-style": {"values": ["none", "inherit", "initial", "unset", "url()", "armenian", "circle", "decimal", "decimal-leading-zero", "disc", "georgian", "inside", "lower-alpha", "lower-greek", "lower-latin", "lower-roman", "outside", "square", "upper-alpha", "upper-latin", "upper-roman"]}, "list-style-image": {"values": ["none", "url()", "inherit"]}, "list-style-position": {"values": ["inside", "outside", "inherit"]}, "list-style-type": {"values": ["armenian", "circle", "decimal", "decimal-leading-zero", "disc", "georgian", "lower-alpha", "lower-greek", "lower-latin", "lower-roman", "none", "square", "upper-alpha", "upper-latin", "upper-roman", "inherit"]}, diff --git a/src/extensions/default/CSSCodeHints/main.js b/src/extensions/default/CSSCodeHints/main.js index 94a61213f3f..4006d837b2f 100644 --- a/src/extensions/default/CSSCodeHints/main.js +++ b/src/extensions/default/CSSCodeHints/main.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, brackets, $ */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; @@ -334,6 +333,12 @@ define(function (require, exports, module) { selectInitial = true; } + if (lastContext === CSSUtils.PROP_VALUE) { + // close the session if we're coming from a property value + // see https://github.com/adobe/brackets/issues/9496 + return null; + } + lastContext = CSSUtils.PROP_NAME; needle = needle.substr(0, this.info.offset); diff --git a/src/extensions/default/CSSCodeHints/unittests.js b/src/extensions/default/CSSCodeHints/unittests.js index 715e2b752b2..e3d5febfeb9 100644 --- a/src/extensions/default/CSSCodeHints/unittests.js +++ b/src/extensions/default/CSSCodeHints/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, xit, expect, beforeEach, afterEach, $, brackets */ +/*global describe, it, xit, expect, beforeEach, afterEach */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/CloseOthers/main.js b/src/extensions/default/CloseOthers/main.js index f9122b60068..50947782cbf 100644 --- a/src/extensions/default/CloseOthers/main.js +++ b/src/extensions/default/CloseOthers/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/CloseOthers/unittests.js b/src/extensions/default/CloseOthers/unittests.js index 3dc411955d2..01e288af1a5 100644 --- a/src/extensions/default/CloseOthers/unittests.js +++ b/src/extensions/default/CloseOthers/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, afterEach, runs, brackets, waitsForDone, spyOn */ +/*global describe, it, expect, beforeEach, afterEach, runs, waitsForDone, spyOn */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/CodeFolding/Prefs.js b/src/extensions/default/CodeFolding/Prefs.js index 9903198c3da..8f498584ed8 100644 --- a/src/extensions/default/CodeFolding/Prefs.js +++ b/src/extensions/default/CodeFolding/Prefs.js @@ -4,8 +4,7 @@ * @author Patrick Oladimeji * @date 3/22/14 20:39:53 PM */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets*/ + define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/CodeFolding/foldhelpers/foldSelected.js b/src/extensions/default/CodeFolding/foldhelpers/foldSelected.js index ec22aa59f4a..f8d3da83e05 100644 --- a/src/extensions/default/CodeFolding/foldhelpers/foldSelected.js +++ b/src/extensions/default/CodeFolding/foldhelpers/foldSelected.js @@ -3,7 +3,7 @@ * @author Patrick Oladimeji * @date 31/07/2015 00:11:53 */ -/*global define*/ + define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/CodeFolding/foldhelpers/foldcode.js b/src/extensions/default/CodeFolding/foldhelpers/foldcode.js index bd90228de08..5d188f3df67 100644 --- a/src/extensions/default/CodeFolding/foldhelpers/foldcode.js +++ b/src/extensions/default/CodeFolding/foldhelpers/foldcode.js @@ -2,8 +2,7 @@ // Distributed under an MIT license: http://codemirror.net/LICENSE // Based on http://codemirror.net/addon/fold/foldcode.js // Modified by Patrick Oladimeji for Brackets -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, document*/ + define(function (require, exports, module) { "use strict"; var CodeMirror = brackets.getModule("thirdparty/CodeMirror/lib/codemirror"), @@ -36,7 +35,7 @@ define(function (require, exports, module) { lastMark, foldMarks; for (i = 0; i < marks.length; ++i) { - if (marks[i].__isFold && force !== "fold") { + if (marks[i].__isFold) { if (!allowFolded) { return null; } @@ -60,7 +59,7 @@ define(function (require, exports, module) { } function makeWidget() { - var widget = document.createElement("span"); + var widget = window.document.createElement("span"); widget.className = "CodeMirror-foldmarker"; return widget; } @@ -90,18 +89,25 @@ define(function (require, exports, module) { }); textRange.on("clear", function (from, to) { - delete cm._lineFolds[pos.line]; - CodeMirror.signal(cm, "unfold", cm, from, to, pos.line); + delete cm._lineFolds[from.line]; + CodeMirror.signal(cm, "unfold", cm, from, to); }); if (force === "fold") { delete range.cleared; - cm._lineFolds[pos.line] = range; + // In some cases such as in xml style files, the start of line folds can span multiple lines. + // For instance the attributes of an element can span multiple lines. In these cases when folding + // we want to render a gutter marker for both the beginning and end of the opening xml tag. + if (pos.line < range.from.line) { + cm._lineFolds[range.from.line] = range; + } else { + cm._lineFolds[pos.line] = range; + } } else { delete cm._lineFolds[pos.line]; } - CodeMirror.signal(cm, force, cm, range.from, range.to, pos.line); + CodeMirror.signal(cm, force, cm, range.from, range.to); return range; } diff --git a/src/extensions/default/CodeFolding/foldhelpers/foldgutter.js b/src/extensions/default/CodeFolding/foldhelpers/foldgutter.js index c8476ffa188..7aa319e59c0 100644 --- a/src/extensions/default/CodeFolding/foldhelpers/foldgutter.js +++ b/src/extensions/default/CodeFolding/foldhelpers/foldgutter.js @@ -2,8 +2,7 @@ // Distributed under an MIT license: http://codemirror.net/LICENSE // Based on http://codemirror.net/addon/fold/foldgutter.js // Modified by Patrick Oladimeji for Brackets -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, document, window, $*/ + define(function (require, exports, module) { "use strict"; var CodeMirror = brackets.getModule("thirdparty/CodeMirror/lib/codemirror"), @@ -28,7 +27,7 @@ define(function (require, exports, module) { * @return {HTMLElement} a htmlelement representing the fold marker */ function marker(spec) { - var elt = document.createElement("div"); + var elt = window.document.createElement("div"); elt.className = spec; return elt; } @@ -100,6 +99,7 @@ define(function (require, exports, module) { i = sr.to.line + 1; } else { range = cm._lineFolds[i] || (func && func(cm, pos)); + if (!fade || (fade && $gutter.is(":hover"))) { if (cm.isFolded(i)) { // expand fold if invalid @@ -355,14 +355,10 @@ define(function (require, exports, module) { * @param {!CodeMirror} cm the CodeMirror instance for the active editor * @param {!Object} from the ch and line position that designates the start of the region * @param {!Object} to the ch and line position that designates the end of the region - * @param {?Number} gutterLineNumber the gutter line number that was clicked to signal the fold event */ - function onFold(cm, from, to, gutterLineNumber) { - var state = cm.state.foldGutter, - line = isNaN(gutterLineNumber) ? from.line : gutterLineNumber; - if (line >= state.from && line < state.to) { - updateFoldInfo(cm, line, line + 1); - } + function onFold(cm, from, to) { + var state = cm.state.foldGutter; + updateFoldInfo(cm, from.line, from.line + 1); } /** @@ -370,15 +366,12 @@ define(function (require, exports, module) { * @param {!CodeMirror} cm the CodeMirror instance for the active editor * @param {!{line:number, ch:number}} from the ch and line position that designates the start of the region * @param {!{line:number, ch:number}} to the ch and line position that designates the end of the region - * @param {?Number} gutterLineNumber the gutter line number that was clicked to signal the fold event */ - function onUnFold(cm, from, to, gutterLineNumber) { - var state = cm.state.foldGutter, - line = isNaN(gutterLineNumber) ? from.line : gutterLineNumber; + function onUnFold(cm, from, to) { + var state = cm.state.foldGutter; var vp = cm.getViewport(); - if (line >= state.from && line < state.to) { - updateFoldInfo(cm, line, Math.min(vp.to, to.line)); - } + delete cm._lineFolds[from.line]; + updateFoldInfo(cm, from.line, to.line || vp.to); } /** diff --git a/src/extensions/default/CodeFolding/foldhelpers/handlebarsFold.js b/src/extensions/default/CodeFolding/foldhelpers/handlebarsFold.js new file mode 100644 index 00000000000..96213f186fe --- /dev/null +++ b/src/extensions/default/CodeFolding/foldhelpers/handlebarsFold.js @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2016 - present Adobe Systems Incorporated. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/** + * Fold range finder for handlebars/mustache template type files. + * @author Patrick Oladimeji + * @date 14/08/2016 22:04:21 + */ + +define(function (require, exports, module) { + "use strict"; + var CodeMirror = brackets.getModule("thirdparty/CodeMirror/lib/codemirror"), + _ = brackets.getModule("thirdparty/lodash"), + StringUtils = brackets.getModule("utils/StringUtils"); + + /** + * Utility function for scanning the text in a document until a certain condition is met + * @param {object} cm The code mirror object representing the document + * @param {string} startCh The start character position for the scan operation + * @param {number} startLine The start line position for the scan operation + * @param {function (string): boolean} condition A predicate function that takes in the text seen so far and returns true if the scanning process should be halted + * @returns {{from:CodeMirror.Pos, to: CodeMirror.Pos, string: string}} An object representing the range of text scanned. + */ + function scanTextUntil(cm, startCh, startLine, condition) { + var line = cm.getLine(startLine), + seen = "", + characterIndex = startCh, + currentLine = startLine, + range; + while (currentLine <= cm.lastLine()) { + if (line.length === 0) { + characterIndex = 0; + line = cm.getLine(++currentLine); + } else { + seen = seen.concat(line[characterIndex] || ""); + if (condition(seen)) { + range = { + from: {ch: startCh, line: startLine}, + to: {ch: characterIndex, line: currentLine}, + string: seen + }; + return range; + } else if (characterIndex >= line.length) { + seen = seen.concat(cm.lineSeparator()); + if (condition(seen)) { + range = { + from: {ch: startCh, line: startLine}, + to: {ch: characterIndex, line: currentLine}, + string: seen + }; + return range; + } + characterIndex = 0; + line = cm.getLine(++currentLine); + } else { + ++characterIndex; + } + } + } + } + + /** + * Utility function used to detect the end of a helper name when scanning a series of text. + * The end of a helper name is signalled by a space character or the `}` + * @param {string} seen The string seen so far + * @returns {boolean} True when the end of a helper name has been detected. + */ + function endHelperName(seen) { + return (/\s$/).test(seen) || StringUtils.endsWith(seen, "}"); + } + + /** + * Returns a predicate function that returns true when a specific character is found + * @param {string} character the character to use in the match function + * @returns {function} A function that checks if the last character of the parameter string matches the parameter character + */ + function readUntil(character) { + return function (seen) { + return seen[seen.length - 1] === character; + }; + } + + function getRange(cm, start) { + var currentLine = start.line, + text = cm.getLine(currentLine) || "", + i = 0, + tagStack = [], + braceStack = [], + found, + openTag, + openPos, + currentCharacter, + openTagIndex = text.indexOf("{{"), + range; + + if (openTagIndex < 0 || text[openTagIndex + 2] === "/") { + return; + } + + found = scanTextUntil(cm, openTagIndex + 2, currentLine, endHelperName); + if (!found) { + return; + } + + openPos = { + from: {line: currentLine, ch: openTagIndex}, + to: found.to + }; + openTag = found.string.substring(0, found.string.length - 1); + if (openTag[0] === "#" || openTag[0] === "~" || openTag[0] === "^") { + found = scanTextUntil(cm, openPos.to.ch, openPos.to.line, function (seen) { + return seen.length > 1 && seen.substr(-2) === "}}"; + }); + if (found) { + openPos.to = {line: found.to.line, ch: found.to.ch + 1}; + } + tagStack.push(openTag.substr(1)); + } else { + braceStack.push("{{"); + } + + i = found.to.ch; + currentLine = found.to.line; + + while (currentLine <= cm.lastLine()) { + text = cm.getLine(currentLine); + currentCharacter = (text && text[i]) || ""; + switch (currentCharacter) { + case "{": + if (text[i + 1] === "{") { + found = scanTextUntil(cm, i + 2, currentLine, endHelperName); + if (found) { + var tag = found.string.substring(0, found.string.length - 1); + if (tag[0] === "#" || tag[0] === "~" || tag[0] === "^") { + tagStack.push(tag.substr(1)); + } else if (tag[0] === "/" && + (_.last(tagStack) === tag.substr(1) || _.last(tagStack) === "*" + tag.substr(1))) { + tagStack.pop(); + if (tagStack.length === 0 && braceStack.length === 0) { + range = { + from: openPos.to, + to: {ch: i, line: currentLine} + }; + return range; + } + } else { + braceStack.push("{{"); + } + } + } + break; + case "}": + if (text[i + 1] === "}") { + braceStack.pop(); + if (braceStack.length === 0 && tagStack.length === 0) { + range = { + from: openPos.to, + to: {ch: i, line: currentLine} + }; + return range; + } + } + break; + case "\"": + case "'": + found = scanTextUntil(cm, i + 1, currentLine, readUntil(text[i])); + if (found) { + i = found.to.ch; + currentLine = found.to.line; + } + break; + default: + break; + } + + ++i; + if (i >= text.length) { + ++currentLine; + i = 0; + } + } + } + + module.exports = getRange; +}); diff --git a/src/extensions/default/CodeFolding/foldhelpers/indentFold.js b/src/extensions/default/CodeFolding/foldhelpers/indentFold.js index 736a9df94ae..d2fa6f63cee 100644 --- a/src/extensions/default/CodeFolding/foldhelpers/indentFold.js +++ b/src/extensions/default/CodeFolding/foldhelpers/indentFold.js @@ -3,8 +3,6 @@ * @author Patrick Oladimeji * @date 12/27/13 21:54:41 PM */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets*/ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/CodeFolding/main.js b/src/extensions/default/CodeFolding/main.js index 3eb80dd8c32..bc224b32fe1 100644 --- a/src/extensions/default/CodeFolding/main.js +++ b/src/extensions/default/CodeFolding/main.js @@ -25,8 +25,7 @@ * @author Patrick Oladimeji * @date 10/24/13 9:35:26 AM */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets*/ + define(function (require, exports, module) { "use strict"; @@ -69,6 +68,7 @@ define(function (require, exports, module) { var foldGutter = require("foldhelpers/foldgutter"), foldCode = require("foldhelpers/foldcode"), indentFold = require("foldhelpers/indentFold"), + handlebarsFold = require("foldhelpers/handlebarsFold"), selectionFold = require("foldhelpers/foldSelected"); @@ -394,8 +394,9 @@ define(function (require, exports, module) { return prefs.getSetting("alwaysUseIndentFold"); }, indentFold); - CodeMirror.registerHelper("fold", "django", CodeMirror.helpers.fold.brace); - CodeMirror.registerHelper("fold", "tornado", CodeMirror.helpers.fold.brace); + CodeMirror.registerHelper("fold", "handlebars", handlebarsFold); + CodeMirror.registerHelper("fold", "htmlhandlebars", handlebarsFold); + CodeMirror.registerHelper("fold", "htmlmixed", handlebarsFold); EditorManager.on("activeEditorChange.CodeFolding", onActiveEditorChanged); DocumentManager.on("documentRefreshed.CodeFolding", function (event, doc) { diff --git a/src/extensions/default/CodeFolding/unittest-files/test.hbs b/src/extensions/default/CodeFolding/unittest-files/test.hbs new file mode 100644 index 00000000000..17181463dbf --- /dev/null +++ b/src/extensions/default/CodeFolding/unittest-files/test.hbs @@ -0,0 +1,47 @@ +{{!-- + comments + go + here +--}} + +{{#test}} + + +{{/test}} + +

    Comments

    + +
    + + {{#each comments}} + {{../permalink + + }} + + {{#if title}} + {{../permalink}} + {{/if}} + {{/each}} + + {{#each comments}} +

    {{title}}

    +
    + {{ + body + }} +
    + {{~person}} +
    Name: {{firstName}} {{lastName}}
    +
    Email: {{email}}
    +
    Phone: {{phone}}
    + {{/person}} + {{#*inline "myPartial"}} + My Content + {{/inline}} + {{^relationships}} + Relationship details go here + {{/relationships}} +
    +
    + {{/each}} +
    diff --git a/src/extensions/default/CodeFolding/unittest-files/test.html b/src/extensions/default/CodeFolding/unittest-files/test.html new file mode 100644 index 00000000000..25f9d4232f1 --- /dev/null +++ b/src/extensions/default/CodeFolding/unittest-files/test.html @@ -0,0 +1,38 @@ + + + + + + +
    +
    + + +
    + + + + + + + + + + + +
    +
    +

    Radio Button Choice

    + + + + + + +
    +
    + + diff --git a/src/extensions/default/CodeFolding/unittest-files/test.js b/src/extensions/default/CodeFolding/unittest-files/test.js index f5e4bb4665c..e921abe57c0 100644 --- a/src/extensions/default/CodeFolding/unittest-files/test.js +++ b/src/extensions/default/CodeFolding/unittest-files/test.js @@ -1,33 +1,36 @@ /** - * Synchronises the code folding states in the CM doc to cm._lineFolds cache. - * When an undo operation is done, if folded code fragments are restored, then - * we need to update cm._lineFolds with the fragments - * @param {Object} cm cm the CodeMirror instance for the active editor - * @param {Object} from starting position in the doc to sync the fold states from - * @param {[[Type]]} lineAdded a number to show how many lines where added to the document - */ - function syncDocToFoldsCache(cm, from, lineAdded) { - var minFoldSize = prefs.getSetting("minFoldSize") || 2; - var opts = cm.state.foldGutter.options || {}; - var rf = opts.rangeFinder || CodeMirror.fold.auto; - var i, pos, folds, fold, range; - if (lineAdded <= 0) { - return; - } + * Synchronises the code folding states in the CM doc to cm._lineFolds cache. + * When an undo operation is done, if folded code fragments are restored, then + * we need to update cm._lineFolds with the fragments + * @param {Object} cm cm the CodeMirror instance for the active editor + * @param {Object} from starting position in the doc to sync the fold states from + * @param {[[Type]]} lineAdded a number to show how many lines where added to the document +*/ +/*global define, brackets, document, window, $, CodeMirror, isFold, prefs*/ + +function syncDocToFoldsCache(cm, from, lineAdded) { + "use strict"; + var minFoldSize = prefs.getSetting("minFoldSize") || 2; + var opts = cm.state.foldGutter.options || {}; + var rf = opts.rangeFinder || CodeMirror.fold.auto; + var i, pos, folds, fold, range; + if (lineAdded <= 0) { + return; + } - for (i = from; i <= from + lineAdded; i = i + 1) { - pos = CodeMirror.Pos(i); - folds = cm.doc.findMarksAt(pos).filter(isFold); - fold = folds.length ? fold = folds[0] : undefined; - if (fold) { - range = rf(cm, CodeMirror.Pos(i)); - if (range && range.to.line - range.from.line >= minFoldSize) { - cm._lineFolds[i] = range; - i = range.to.line; - } else { - delete cm._lineFolds[i]; - } + for (i = from; i <= from + lineAdded; i = i + 1) { + pos = CodeMirror.Pos(i); + folds = cm.doc.findMarksAt(pos).filter(isFold); + fold = folds.length ? fold = folds[0] : undefined; + if (fold) { + range = rf(cm, CodeMirror.Pos(i)); + if (range && range.to.line - range.from.line >= minFoldSize) { + cm._lineFolds[i] = range; + i = range.to.line; + } else { + delete cm._lineFolds[i]; } } - } + +} diff --git a/src/extensions/default/CodeFolding/unittests.js b/src/extensions/default/CodeFolding/unittests.js index 6cddfe37b86..36b76713376 100644 --- a/src/extensions/default/CodeFolding/unittests.js +++ b/src/extensions/default/CodeFolding/unittests.js @@ -3,7 +3,9 @@ * @author Patrick Oladimeji * @date 01/08/2015 18:34 */ -/*global define, brackets, describe, beforeEach, afterEach, it, expect, runs, waitsForDone, waitsFor*/ + +/*global describe, beforeEach, afterEach, it, expect, runs, waitsForDone, waitsFor*/ + define(function (require, exports, module) { "use strict"; var SpecRunnerUtils = brackets.getModule("spec/SpecRunnerUtils"), @@ -22,10 +24,34 @@ define(function (require, exports, module) { foldMarkerOpen = gutterName + "-open", foldMarkerClosed = gutterName + "-folded"; var extensionPath = FileUtils.getNativeModuleDirectoryPath(module), - testDocPath = extensionPath + "/unittest-files/", - testFilePath = testDocPath + "test.js"; - - var open = "open", folded = "folded"; + testDocumentDirectory = extensionPath + "/unittest-files/", + // The line numbers referenced below are dependent on the files in /unittest-files directory. + // Remember to update the numbers if the files change. + testFilesSpec = { + js: { + filePath: testDocumentDirectory + "test.js", + foldableLines: [1, 11, 17, 21, 25, 27, 30], + sameLevelFoldableLines: [17, 21], + firstSelection: {start: {line: 2, ch: 0}, end: {line: 10, ch: 0}}, + secondSelection: {start: {line: 5, ch: 0}, end: {line: 8, ch: 4}} + }, + html: { + filePath: testDocumentDirectory + "test.html", + foldableLines: [1, 2, 5, 7, 8, 12, 13, 14, 18, 19, 24, 27], + sameLevelFoldableLines: [8, 24], + firstSelection: {start: {line: 3, ch: 0}, end: {line: 10, ch: 0}}, + secondSelection: {start: {line: 6, ch: 0}, end: {line: 17, ch: 4}} + }, + hbs: { + filePath: testDocumentDirectory + "test.hbs", + foldableLines: [1, 7, 14, 16, 17, 21, 26, 28, 29, 32, 33, 38, 41], + sameLevelFoldableLines: [1, 7, 14], + firstSelection: {start: {line: 2, ch: 0}, end: {line: 10, ch: 0}}, + secondSelection: {start: {line: 5, ch: 0}, end: {line: 8, ch: 4}} + } + }, + open = "open", + folded = "folded"; /** * Utility to temporarily set preference values in the session scope @@ -69,7 +95,7 @@ define(function (require, exports, module) { runs(function () { //setPreference("saveFoldStates", false); - SpecRunnerUtils.loadProjectInTestWindow(testDocPath); + SpecRunnerUtils.loadProjectInTestWindow(testDocumentDirectory); }); } @@ -94,7 +120,7 @@ define(function (require, exports, module) { * @param {Number} line The line number to fold */ function foldCodeOnLine(line) { - cm.setCursor(line); + cm.setCursor(line - 1); var promise = runCommand("codefolding.collapse"); waitsForDone(promise, "Collapse code", 2000); } @@ -104,7 +130,7 @@ define(function (require, exports, module) { * @param {Number} line The line number to fold */ function expandCodeOnLine(line) { - cm.setCursor(line); + cm.setCursor(line - 1); var promise = runCommand("codefolding.expand"); waitsForDone(promise, "Expand code", 2000); } @@ -129,6 +155,9 @@ define(function (require, exports, module) { * @returns {Object} an object with line and type property */ function gutterMarkState(lineInfo) { + if (!lineInfo || !lineInfo.gutterMarkers) { + return; + } var classes = lineInfo.gutterMarkers[gutterName].classList; if (classes && classes.contains(foldMarkerClosed)) { return {line: lineInfo.line, type: folded}; @@ -141,7 +170,7 @@ define(function (require, exports, module) { /** * Helper function to return the fold markers on the current codeMirror instance * - * @returns {[[Type]]} [[Description]] + * @returns {Array} An array of objects containing the line and the type of marker. */ function getGutterFoldMarks() { testEditor = EditorManager.getCurrentFullEditor(); @@ -222,210 +251,276 @@ define(function (require, exports, module) { tearDown(); }); + Object.keys(testFilesSpec).forEach(function (file) { + var testFilePath = testFilesSpec[file].filePath; + var foldableLines = testFilesSpec[file].foldableLines; + var testFileSpec = testFilesSpec[file]; + describe(file + " - Editor/Gutter", function () { + beforeEach(function () { + runs(function () { + openTestFile(testFilePath); + }); - describe("Rendering folded regions and gutter markers", function () { - beforeEach(function () { - runs(function () { - openTestFile(testFilePath); - }); - - runs(function () { - testEditor = EditorManager.getCurrentFullEditor(); - cm = testEditor._codeMirror; - }); - }); - - afterEach(function () { - testWindow.closeAllFiles(); - }); - - it("Gutter fold marks are rendered on startup", function () { - var marks = getGutterFoldMarks(); - expect(marks.length).toBeGreaterThan(0); - }); - - it("Folding code creates a folded region in editor", function () { - var lineNumber = 1; - runs(function () { - foldCodeOnLine(lineNumber); - }); - - runs(function () { - var marks = getEditorFoldMarks(); - expect(marks.length).toEqual(1); - expect(marks[0].lines[0].lineNo()).toEqual(lineNumber - 1); - }); - }); - - it("Expanding code clears the folded region in editor", function () { - runs(function () { - foldCodeOnLine(1); - }); - runs(function () { - expandCodeOnLine(1); + runs(function () { + testEditor = EditorManager.getCurrentFullEditor(); + cm = testEditor._codeMirror; + }); }); - runs(function () { - var marks = getEditorFoldMarks(); - expect(marks.length).toEqual(0); + afterEach(function () { + testWindow.closeAllFiles(); }); - }); - it("Clearing text marker on folded region in editor expands it and updates the fold gutter", function () { - var lineNumber = 1; - runs(function () { - foldCodeOnLine(lineNumber); - }); - runs(function () { - var marks = getEditorFoldMarks().filter(function (m) { - var range = m.find(); - return range ? range.from.line === lineNumber - 1 : false; + it("renders fold marks on startup", function () { + var marks = getGutterFoldMarks(); + expect(marks.length).toBeGreaterThan(0); + marks.map(getLineNumber).forEach(function (line) { + expect(toZeroIndex(foldableLines)).toContain(line); }); - marks[0].clear(); }); - runs(function () { - var marks = getEditorFoldMarks(); - var gutterMark = getGutterFoldMarks().filter(function (m) { - return m.line === lineNumber - 1 && m.type === open; + it("creates a folded region in editor when fold marker is clicked", function () { + var lineNumber = foldableLines[0]; + runs(function () { + foldCodeOnLine(lineNumber); }); - expect(marks.length).toEqual(0); - expect(gutterMark.length).toEqual(1); - }); - }); - - it("Folded lines have a folded marker in the gutter", function () { - var lineNumbers = [1, 9]; - runs(function () { - lineNumbers.forEach(function (l) { - foldCodeOnLine(l); + runs(function () { + var marks = getEditorFoldMarks(); + expect(marks.length).toEqual(1); + expect(marks[0].lines[0].lineNo()).toEqual(lineNumber - 1); }); }); - runs(function () { - var marks = getGutterFoldMarks().filter(filterFolded); - expect(marks.length).toEqual(lineNumbers.length); - - var gutterNumbers = marks - .map(getLineNumber); - expect(gutterNumbers).toEqual(toZeroIndex(lineNumbers)); - }); - }); - - it("Foldable lines have a foldable maker in the gutter", function () { - var lineNumbers = [1, 9, 14, 18, 22, 24, 27]; - var marks = getGutterFoldMarks(); - var gutterNumbers = marks.filter(filterOpen) - .map(getLineNumber); - expect(gutterNumbers).toEqual(toZeroIndex(lineNumbers)); - }); - - describe("Preferences work as expected", function () { - it("Persistence of fold states works as expected", function () { - runs(function () { - foldCodeOnLine(1); - foldCodeOnLine(14); - foldCodeOnLine(18); - }); + it("clears the folded region in editor when collapsed fold marker is clicked", function () { + var lineNumber = foldableLines[0]; runs(function () { - testWindow.closeAllFiles(); + foldCodeOnLine(lineNumber); }); - runs(function () { - openTestFile(testFilePath); + expandCodeOnLine(lineNumber); }); runs(function () { - //expect line 1 to be folded var marks = getEditorFoldMarks(); - expect(marks.length).toEqual(3); + expect(marks.length).toEqual(0); }); }); - it("Persistence of fold states can be disabled", function () { - setPreference("saveFoldStates", false); + it("expands and updates the fold gutter when text marker for a folded region in editor is cleared", function () { + var lineNumber = foldableLines[0]; runs(function () { - foldCodeOnLine(1); + foldCodeOnLine(lineNumber); }); runs(function () { - testWindow.closeAllFiles(); + var marks = getEditorFoldMarks().filter(function (m) { + var range = m.find(); + return range ? range.from.line === lineNumber - 1 : false; + }); + marks[0].clear(); }); runs(function () { - openTestFile(testFilePath); - }); - - runs(function () { - //expect line 1 to be folded var marks = getEditorFoldMarks(); + var gutterMark = getGutterFoldMarks().filter(function (m) { + return m.line === lineNumber - 1 && m.type === open; + }); expect(marks.length).toEqual(0); + expect(gutterMark.length).toEqual(1); + }); }); - it("Minimum fold size is obeyed", function () { - setPreference("minFoldSize", 20000); + it("renders folded marker in the gutter for folded code regions", function () { + var lineNumbers = testFilesSpec[file].sameLevelFoldableLines; runs(function () { - testWindow.closeAllFiles(); + lineNumbers.forEach(function (l) { + foldCodeOnLine(l); + }); }); runs(function () { - openTestFile(testFilePath); - }); + var marks = getGutterFoldMarks().filter(filterFolded); + expect(marks.length).toEqual(lineNumbers.length); - runs(function () { - var marks = getGutterFoldMarks(); - expect(marks.length).toEqual(0); + var gutterNumbers = marks + .map(getLineNumber); + expect(gutterNumbers).toEqual(toZeroIndex(lineNumbers)); }); }); - it("Code folding can be disabled", function () { - setPreference("enabled", false); - runs(function () { - var marks = getEditorFoldMarks(); - expect(marks.length).toEqual(0); - }); + it("indicates foldable lines in the gutter", function () { + var lineNumbers = foldableLines; + var marks = getGutterFoldMarks(); + var gutterNumbers = marks.filter(filterOpen) + .map(getLineNumber); + expect(gutterNumbers).toEqual(toZeroIndex(lineNumbers)); }); - it("Selecting text triggers fold marks when `makeSelectionsFoldable' is enabled", function () { - var start = {line: 2, ch: 0}, end = {line: 6, ch: 0}; - setPreference("makeSelectionsFoldable", true); + describe("Preferences", function () { + it("persists fold states", function () { + var lineNumbers = testFileSpec.sameLevelFoldableLines; + runs(function () { + lineNumbers.forEach(function (line) { + foldCodeOnLine(line); + }); + }); + runs(function () { + testWindow.closeAllFiles(); + }); + + runs(function () { + openTestFile(testFilePath); + }); + + runs(function () { + var marks = getEditorFoldMarks(); + var gutterNumbers = marks.map(function (mark) { + return mark.lines[0].lineNo(); + }); + expect(gutterNumbers).toEqual(toZeroIndex(lineNumbers)); + }); + }); - selectTextInEditor(start, end); + it("can be disable persistence of fold states", function () { + setPreference("saveFoldStates", false); + runs(function () { + foldCodeOnLine(foldableLines[0]); + }); + runs(function () { + testWindow.closeAllFiles(); + }); + + runs(function () { + openTestFile(testFilePath); + }); + + runs(function () { + var marks = getEditorFoldMarks(); + expect(marks.length).toEqual(0); + }); + }); - runs(function () { - var marks = getGutterFoldMarks().filter(filterOpen).map(getLineNumber); - expect(marks).toContain(start.line); + it("can set the minimum fold size", function () { + setPreference("minFoldSize", 20000); + runs(function () { + testWindow.closeAllFiles(); + }); + + runs(function () { + openTestFile(testFilePath); + }); + + runs(function () { + var marks = getGutterFoldMarks(); + expect(marks.length).toEqual(0); + }); }); - }); - it("Selecting text does not trigger fold marks when `makeSelectionsFoldable' is disabled", function () { - setPreference("makeSelectionsFoldable", false); - var start = {line: 2, ch: 0}, end = {line: 6, ch: 0}; - selectTextInEditor(start, end); + it("can disable code folding", function () { + setPreference("enabled", false); + runs(function () { + var marks = getEditorFoldMarks(); + expect(marks.length).toEqual(0); + }); + }); - runs(function () { - var marks = getGutterFoldMarks().filter(filterOpen) - .map(getLineNumber).filter(function (d) { - return d === start.line; + describe("Fold selected region", function () { + it("can be enabled by setting `makeSelectionsFoldable' to true", function () { + var start = testFileSpec.firstSelection.start, end = testFileSpec.firstSelection.end; + setPreference("makeSelectionsFoldable", true); + + selectTextInEditor(start, end); + + runs(function () { + var marks = getGutterFoldMarks().filter(filterOpen).map(getLineNumber); + expect(marks).toContain(start.line); }); - expect(marks.length).toEqual(0); + }); + + it("can be disabled by setting `makeSelectionsFoldable' to false", function () { + setPreference("makeSelectionsFoldable", false); + var start = testFileSpec.firstSelection.start, end = testFileSpec.firstSelection.end; + selectTextInEditor(start, end); + + runs(function () { + var marks = getGutterFoldMarks().filter(filterOpen) + .map(getLineNumber).filter(function (d) { + return d === start.line; + }); + expect(marks.length).toEqual(0); + }); + }); + + it("shows fold ranges for only the most recent selection", function () { + var firstSelection = testFileSpec.firstSelection, + secondSelection = testFileSpec.secondSelection; + + selectTextInEditor(firstSelection.start, firstSelection.end); + + selectTextInEditor(secondSelection.start, secondSelection.end); + + runs(function () { + var marks = getGutterFoldMarks().filter(filterOpen) + .map(getLineNumber); + expect(marks).toContain(secondSelection.start.line); + expect(marks).not.toContain(firstSelection.start.line); + }); + }); }); - }); - it("Successively selecting text only triggers fold region for the last selection", function () { - var firstSel = {start: {line: 1, ch: 0}, end: {line: 10, ch: 0}}, - secondSel = {start: {line: 3, ch: 0}, end: {line: 8, ch: 4}}; + }); - selectTextInEditor(firstSel.start, firstSel.end); + describe("Editor text changes", function () { + var foldableLine = foldableLines[1], + expandTimeoutElapsed = false; + + // add a line after folding a region preserves the region and the region can be unfolded + it("can unfold a folded region after a line has been added above it", function () { + runs(function () { + foldCodeOnLine(foldableLine); + cm.replaceRange("\r\n", {line: foldableLine - 1, ch: 0}); + }); + + runs(function () { + expandCodeOnLine(foldableLine + 1); + setTimeout(function () { + expandTimeoutElapsed = true; + }, 400); + }); + + waitsFor(function () { + return expandTimeoutElapsed; + }, "waiting a moment for gutter markerts to be re-rendered", 500); + + runs(function () { + var marks = getGutterFoldMarks().filter(filterFolded); + expect(marks.length).toEqual(0); + }); - selectTextInEditor(secondSel.start, secondSel.end); + }); - runs(function () { - var marks = getGutterFoldMarks().filter(filterOpen) - .map(getLineNumber); - expect(marks).toContain(secondSel.start.line); - expect(marks).not.toContain(firstSel.start.line); + it("can unfold a folded region even after a line has been removed above it", function () { + runs(function () { + foldCodeOnLine(foldableLine); + cm.replaceRange("", {line: foldableLine - 1, ch: 0}, {line: foldableLine, ch: 0}); + }); + + runs(function () { + expandCodeOnLine(foldableLine - 1); + setTimeout(function () { + expandTimeoutElapsed = true; + }, 400); + }); + + waitsFor(function () { + return expandTimeoutElapsed; + }, "waiting a moment for gutter markerts to be re-rendered", 500); + + runs(function () { + var marks = getGutterFoldMarks().filter(filterFolded); + expect(marks.length).toEqual(0); + }); }); }); }); diff --git a/src/extensions/default/CommandLineTool/main.js b/src/extensions/default/CommandLineTool/main.js index 87aa3c6d05a..7c23e29784d 100644 --- a/src/extensions/default/CommandLineTool/main.js +++ b/src/extensions/default/CommandLineTool/main.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets, appshell */ +/*global appshell */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/DebugCommands/ErrorNotification.js b/src/extensions/default/DebugCommands/ErrorNotification.js index c7aa4357200..f97202eec97 100644 --- a/src/extensions/default/DebugCommands/ErrorNotification.js +++ b/src/extensions/default/DebugCommands/ErrorNotification.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/DebugCommands/NodeDebugUtils.js b/src/extensions/default/DebugCommands/NodeDebugUtils.js index 988d80fb733..c708578862e 100644 --- a/src/extensions/default/DebugCommands/NodeDebugUtils.js +++ b/src/extensions/default/DebugCommands/NodeDebugUtils.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; @@ -68,7 +65,7 @@ define(function (require, exports, module) { try { _nodeConnection.domains.base.restartNode(); } catch (e) { - alert("Failed trying to restart Node: " + e.message); + window.alert("Failed trying to restart Node: " + e.message); } } @@ -79,7 +76,7 @@ define(function (require, exports, module) { try { _nodeConnection.domains.base.enableDebugger(); } catch (e) { - alert("Failed trying to enable Node debugger: " + e.message); + window.alert("Failed trying to enable Node debugger: " + e.message); } } diff --git a/src/extensions/default/DebugCommands/main.js b/src/extensions/default/DebugCommands/main.js index 3108f037f98..d9c359a24f7 100644 --- a/src/extensions/default/DebugCommands/main.js +++ b/src/extensions/default/DebugCommands/main.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, $, brackets, window*/ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HTMLCodeHints/HtmlAttributes.json b/src/extensions/default/HTMLCodeHints/HtmlAttributes.json index d7d24e12b78..71255174c86 100644 --- a/src/extensions/default/HTMLCodeHints/HtmlAttributes.json +++ b/src/extensions/default/HTMLCodeHints/HtmlAttributes.json @@ -8,29 +8,29 @@ "dropzone": { "attribOption": ["copy", "move", "link"], "global": "true" }, "hidden": { "attribOption": ["hidden"], "global": "true" }, "id": { "attribOption": [], "global": "true", "type": "cssId" }, - "lang": { "attribOption": ["ab", "aa", "af", "sq", "am", "ar", "an", "hy", "as", "ay", "az", "ba", "eu", "bn", "dz", "bh", "bi", "br", - "bg", "my", "be", "km", "ca", "zh", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fo", "fa", "fi", "fr", - "fy", "gl", "gd", "gv", "ka", "de", "el", "kl", "gn", "gu", "ht", "ha", "he", "hi", "hu", "is", "io", "id", - "ia", "ie", "iu", "ik", "ga", "it", "ja", "jv", "kn", "ks", "kk", "rw", "ky", "rn", "ko", "ku", "lo", "la", - "lv", "li", "ln", "lt", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mo", "mn", "na", "ne", "no", "oc", "or", - "om", "ps", "pl", "pt", "pa", "qu", "rm", "ro", "ru", "sz", "sm", "sg", "sa", "sr", "sh", "st", "tn", "sn", - "ii", "sd", "si", "ss", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", "th", "bo", - "ti", "to", "ts", "tr", "tk", "tw", "ug", "uk", "ur", "uz", "vi", "vo", "wa", "cy", "wo", "xh", "yi", "yo", - "zu"], + "lang": { "attribOption": ["ab", "aa", "af", "sq", "am", "ar", "an", "hy", "as", "ay", "az", "ba", "eu", "bn", "dz", "bh", "bi", "br", + "bg", "my", "be", "km", "ca", "zh", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fo", "fa", "fi", "fr", + "fy", "gl", "gd", "gv", "ka", "de", "el", "kl", "gn", "gu", "ht", "ha", "he", "hi", "hu", "is", "io", "id", + "ia", "ie", "iu", "ik", "ga", "it", "ja", "jv", "kn", "ks", "kk", "rw", "ky", "rn", "ko", "ku", "lo", "la", + "lv", "li", "ln", "lt", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mo", "mn", "na", "ne", "no", "oc", "or", + "om", "ps", "pl", "pt", "pa", "qu", "rm", "ro", "ru", "sz", "sm", "sg", "sa", "sr", "sh", "st", "tn", "sn", + "ii", "sd", "si", "ss", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", "th", "bo", + "ti", "to", "ts", "tr", "tk", "tw", "ug", "uk", "ur", "uz", "vi", "vo", "wa", "cy", "wo", "xh", "yi", "yo", + "zu"], "global": "true" }, - "role": { "attribOption": ["alert", "alertdialog", "article", "application", "banner", "button", "checkbox", "columnheader", "combobox", - "complementary", "contentinfo", "definition", "directory", "dialog", "document", "form", "grid", "gridcell", - "group", "heading", "img", "link", "list", "listbox", "listitem", "log", "main", "marquee", "math", "menu", - "menubar", "menuitem", "menuitemcheckbox", "menuitemradio", "navigation", "note", "option", "presentation", - "progressbar", "radio", "radiogroup", "region", "row", "rowgroup", "rowheader", "scrollbar", "search", - "separator", "slider", "spinbutton", "status", "tab", "tablist", "tabpanel", "textbox", "timer", "toolbar", - "tooltip", "tree", "treegrid", "treeitem"], + "role": { "attribOption": ["alert", "alertdialog", "article", "application", "banner", "button", "checkbox", "columnheader", "combobox", + "complementary", "contentinfo", "definition", "directory", "dialog", "document", "form", "grid", "gridcell", + "group", "heading", "img", "link", "list", "listbox", "listitem", "log", "main", "marquee", "math", "menu", + "menubar", "menuitem", "menuitemcheckbox", "menuitemradio", "navigation", "note", "option", "presentation", + "progressbar", "radio", "radiogroup", "region", "row", "rowgroup", "rowheader", "scrollbar", "search", + "separator", "slider", "spinbutton", "status", "tab", "tablist", "tabpanel", "textbox", "timer", "toolbar", + "tooltip", "tree", "treegrid", "treeitem"], "global": "true" }, "spellcheck": { "attribOption": [], "global": "true", "type": "boolean" }, "style": { "attribOption": [], "global": "true", "type": "style" }, "tabindex": { "attribOption": [], "global": "true" }, "title": { "attribOption": [], "global": "true" }, - + "onabort": { "attribOption": [], "global": "true" }, "onblur": { "attribOption": [], "global": "true" }, "oncanplay": { "attribOption": [], "global": "true" }, @@ -85,7 +85,42 @@ "ontimeupdate": { "attribOption": [], "global": "true" }, "onvolumechange": { "attribOption": [], "global": "true" }, "onwaiting": { "attribOption": [], "global": "true" }, - + + "aria-autocomplete": { "attribOption": ["inline", "list", "both", "none"] }, + "aria-activedescendant": { "attribOption": [], "global": "true" }, + "aria-atomic": { "attribOption": ["true", "false"], "global": "true", "type": "boolean" }, + "aria-busy": { "attribOption": [], "global": "true", "type": "boolean" }, + "aria-checked": { "attribOption": ["true", "false", "mixed", "undefined"] }, + "aria-controls": { "attribOption": [], "global": "true" }, + "aria-describedby": { "attribOption": [], "global": "true" }, + "aria-disabled": { "attribOption": ["true", "false"], "global": "true" }, + "aria-dropeffect": { "attribOption": ["copy", "move", "link", "execute", "popup", "none"], "global": "true" }, + "aria-expanded": { "attribOption": ["true", "false", "undefined"] }, + "aria-flowto": { "attribOption": [], "global": "true" }, + "aria-grabbed": { "attribOption": ["true", "false", "undefined"], "global": "true" }, + "aria-haspopup": { "attribOption": ["true", "false"], "global": "true", "type": "boolean" }, + "aria-hidden": { "attribOption": ["true", "false"], "global": "true", "type": "boolean" }, + "aria-invalid": { "attribOption": ["grammar", "false", "spelling", "true"], "global": "true" }, + "aria-label": { "attribOption": [], "global": "true" }, + "aria-labelledby": { "attribOption": [], "global": "true" }, + "aria-level": { "attribOption": [] }, + "aria-live": { "attribOption": ["off", "polite", "assertive"], "global": "true" }, + "aria-multiline": { "attribOption": ["true", "false"], "type": "boolean" }, + "aria-multiselectable": { "attribOption": ["true", "false"], "type": "boolean" }, + "aria-orientation": { "attribOption": ["vertical", "horizontal"] }, + "aria-owns": { "attribOption": [], "global": "true" }, + "aria-posinset": { "attribOption": [] }, + "aria-pressed": { "attribOption": ["true", "false", "mixed", "undefined"] }, + "aria-readonly": { "attribOption": ["true", "false"] }, + "aria-relevant": { "attribOption": ["additions", "removals", "text", "all", "additions text"], "global": "true" }, + "aria-required": { "attribOption": ["true", "false"], "type": "boolean" }, + "aria-selected": { "attribOption": ["true", "false", "undefined"] }, + "aria-setsize": { "attribOption": [] }, + "aria-sort": { "attribOption": ["ascending", "descending", "none", "other"] }, + "aria-valuemax": { "attribOption": [] }, + "aria-valuemin": { "attribOption": [] }, + "aria-valuenow": { "attribOption": [] }, + "aria-valuetext": { "attribOption": [] }, "accept": { "attribOption": ["text/html", "text/plain", "application/msword", "application/msexcel", "application/postscript", "application/x-zip-compressed", "application/pdf", "application/rtf", "video/x-msvideo", "video/quicktime", "video/x-mpeg2", "audio/x-pn/realaudio", "audio/x-mpeg", "audio/x-waw", "audio/x-aiff", "audio/basic", @@ -97,18 +132,26 @@ "alt": { "attribOption": [] }, "archive": { "attribOption": [] }, "async": { "attribOption": [], "type": "flag" }, - "autocomplete": { "attribOption": ["off", "on"] }, + "autocomplete": { "attribOption": ["additional-name", "address-level1", "address-level2", "address-level3", "address-level4", "address-line1", + "address-line2", "address-line3", "bday", "bday-year", "bday-day", "bday-month", "billing", + "cc-additional-name", "cc-csc", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-family-name", "cc-given-name", + "cc-name", "cc-number", "cc-type", "country", "country-name", "current-password", "email", "family-name", + "fax", "given-name", "home", "honorific-prefix", "honorific-suffix", "impp", "language", "mobile", "name", + "new-password", "nickname", "off", "on", "organization", "organization-title", "pager", "photo", "postal-code", "sex", + "shipping", "street-address", "tel-area-code", "tel", "tel-country-code", "tel-extension", + "tel-local", "tel-local-prefix", "tel-local-suffix", "tel-national", "transaction-amount", + "transaction-currency", "url", "username", "work"] }, "autofocus": { "attribOption": [], "type": "flag" }, "autoplay": { "attribOption": [], "type": "flag" }, "behavior": { "attribOption": ["scroll", "slide", "alternate"] }, "bgcolor": { "attribOption": [], "type": "color" }, "border": { "attribOption": [] }, "challenge": { "attribOption": [] }, - "charset": { "attribOption": ["iso-8859-1", "utf-8", "shift_jis", "euc-jp", "big5", "gb2312", "euc-kr", "din_66003-kr", "ns_4551-1-kr", - "sen_850200_b", "csISO2022jp", "hz-gb-2312", "ibm852", "ibm866", "irv", "iso-2022-kr", "iso-8859-2", - "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-9", "koi8-r", - "ks_c_5601", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", - "windows-1256", "windows-1257", "windows-1258", "windows-874", "x-euc", "asmo-708", "dos-720", "dos-862", + "charset": { "attribOption": ["iso-8859-1", "utf-8", "shift_jis", "euc-jp", "big5", "gb2312", "euc-kr", "din_66003-kr", "ns_4551-1-kr", + "sen_850200_b", "csISO2022jp", "hz-gb-2312", "ibm852", "ibm866", "irv", "iso-2022-kr", "iso-8859-2", + "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-9", "koi8-r", + "ks_c_5601", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", + "windows-1256", "windows-1257", "windows-1258", "windows-874", "x-euc", "asmo-708", "dos-720", "dos-862", "dos-874", "cp866", "cp1256"] }, "checked": { "attribOption": [], "type": "flag" }, "cite": { "attribOption": [] }, @@ -177,9 +220,9 @@ "preload": { "attribOption": ["auto", "metadata", "none"] }, "pubdate": { "attribOption": [] }, "radiogroup": { "attribOption": [] }, - "rel": { "attribOption": ["alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", + "rel": { "attribOption": ["alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "sidebar", "tag", "external"] }, - "link/rel": { "attribOption": ["alternate", "author", "help", "icon", "license", "next", "pingback", "prefetch", "prev", "search", + "link/rel": { "attribOption": ["alternate", "author", "help", "icon", "license", "next", "pingback", "prefetch", "prev", "search", "sidebar", "stylesheet", "tag"] }, "readonly": { "attribOption": [], "type": "flag" }, "required": { "attribOption": [], "type": "flag" }, @@ -211,7 +254,7 @@ "link/type": { "attribOption": ["text/css"] }, "menu/type": { "attribOption": ["context", "list", "toolbar"] }, "ol/type": { "attribOption": ["1", "a", "A", "i", "I"] }, - "script/type": { "attribOption": ["text/javascript", "text/ecmascript", "text/jscript", "text/livescript", "text/tcl", "text/x-javascript", "text/x-ecmascript", + "script/type": { "attribOption": ["text/javascript", "text/ecmascript", "text/jscript", "text/livescript", "text/tcl", "text/x-javascript", "text/x-ecmascript", "application/x-javascript", "application/x-ecmascript", "application/javascript", "application/ecmascript", "text/babel", "text/jsx"] }, "style/type": { "attribOption": ["text/css"] }, diff --git a/src/extensions/default/HTMLCodeHints/main.js b/src/extensions/default/HTMLCodeHints/main.js index b5998801b81..5f6f6fb9573 100644 --- a/src/extensions/default/HTMLCodeHints/main.js +++ b/src/extensions/default/HTMLCodeHints/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HTMLCodeHints/unittests.js b/src/extensions/default/HTMLCodeHints/unittests.js index d5233efd51b..48a0cf66af3 100644 --- a/src/extensions/default/HTMLCodeHints/unittests.js +++ b/src/extensions/default/HTMLCodeHints/unittests.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, xit, expect, beforeEach, afterEach, $, brackets */ +/*global describe, it, xit, expect, beforeEach, afterEach */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HandlebarsSupport/main.js b/src/extensions/default/HandlebarsSupport/main.js index 3ec744f5149..ef18d3d1d7c 100644 --- a/src/extensions/default/HandlebarsSupport/main.js +++ b/src/extensions/default/HandlebarsSupport/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, nomen: true, regexp: true, maxerr: 50 */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HealthData/HealthDataManager.js b/src/extensions/default/HealthData/HealthDataManager.js index 224ffb62355..811fde8258f 100644 --- a/src/extensions/default/HealthData/HealthDataManager.js +++ b/src/extensions/default/HealthData/HealthDataManager.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, console */ - define(function (require, exports, module) { "use strict"; @@ -66,7 +63,7 @@ define(function (require, exports, module) { oneTimeHealthData.uuid = userUuid; oneTimeHealthData.snapshotTime = Date.now(); oneTimeHealthData.os = brackets.platform; - oneTimeHealthData.userAgent = navigator.userAgent; + oneTimeHealthData.userAgent = window.navigator.userAgent; oneTimeHealthData.osLanguage = brackets.app.language; oneTimeHealthData.bracketsLanguage = brackets.getLocale(); oneTimeHealthData.bracketsVersion = brackets.metadata.version; diff --git a/src/extensions/default/HealthData/HealthDataNotification.js b/src/extensions/default/HealthData/HealthDataNotification.js index 7ab7199f412..5a985d0316e 100644 --- a/src/extensions/default/HealthData/HealthDataNotification.js +++ b/src/extensions/default/HealthData/HealthDataNotification.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HealthData/HealthDataPopup.js b/src/extensions/default/HealthData/HealthDataPopup.js index 3d471fca9a1..741d1cf5615 100644 --- a/src/extensions/default/HealthData/HealthDataPopup.js +++ b/src/extensions/default/HealthData/HealthDataPopup.js @@ -21,11 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global brackets, define, $*/ - - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HealthData/HealthDataPreview.js b/src/extensions/default/HealthData/HealthDataPreview.js index 33f7b1e4f76..a5148c4107b 100644 --- a/src/extensions/default/HealthData/HealthDataPreview.js +++ b/src/extensions/default/HealthData/HealthDataPreview.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HealthData/HealthDataUtils.js b/src/extensions/default/HealthData/HealthDataUtils.js index 1adf72011f2..b14da1a35ba 100644 --- a/src/extensions/default/HealthData/HealthDataUtils.js +++ b/src/extensions/default/HealthData/HealthDataUtils.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HealthData/main.js b/src/extensions/default/HealthData/main.js index 5c732e14b0d..40e65463414 100644 --- a/src/extensions/default/HealthData/main.js +++ b/src/extensions/default/HealthData/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets*/ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HealthData/unittests.js b/src/extensions/default/HealthData/unittests.js index 90fd8c69cc8..0e43475e244 100644 --- a/src/extensions/default/HealthData/unittests.js +++ b/src/extensions/default/HealthData/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $, describe, runs, beforeEach, it, afterEach, expect, waitsForDone, waitsForFail */ +/*global describe, runs, beforeEach, it, afterEach, expect, waitsForDone, waitsForFail */ /*unittests: HealthData*/ define(function (require, exports, module) { diff --git a/src/extensions/default/HtmlEntityCodeHints/main.js b/src/extensions/default/HtmlEntityCodeHints/main.js index d51567340d0..b0ca9b6f6fb 100644 --- a/src/extensions/default/HtmlEntityCodeHints/main.js +++ b/src/extensions/default/HtmlEntityCodeHints/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/HtmlEntityCodeHints/unittests.js b/src/extensions/default/HtmlEntityCodeHints/unittests.js index 35aa2f4f62a..42d45a061e1 100644 --- a/src/extensions/default/HtmlEntityCodeHints/unittests.js +++ b/src/extensions/default/HtmlEntityCodeHints/unittests.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, afterEach, brackets */ +/*global describe, it, expect, beforeEach, afterEach */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/InlineColorEditor/ColorEditor.js b/src/extensions/default/InlineColorEditor/ColorEditor.js index ea1b04b1e22..8e1132be7ce 100644 --- a/src/extensions/default/InlineColorEditor/ColorEditor.js +++ b/src/extensions/default/InlineColorEditor/ColorEditor.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, nomen: true, regexp: true, maxerr: 50 */ -/*global define, brackets, $, window */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/InlineColorEditor/InlineColorEditor.js b/src/extensions/default/InlineColorEditor/InlineColorEditor.js index afe0bc37616..d3cf335ab2b 100644 --- a/src/extensions/default/InlineColorEditor/InlineColorEditor.js +++ b/src/extensions/default/InlineColorEditor/InlineColorEditor.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, nomen: true, regexp: true, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/InlineColorEditor/img/color_thumb_back.png b/src/extensions/default/InlineColorEditor/img/color_thumb_back.png index e107ec26088..2ecda4150d3 100644 Binary files a/src/extensions/default/InlineColorEditor/img/color_thumb_back.png and b/src/extensions/default/InlineColorEditor/img/color_thumb_back.png differ diff --git a/src/extensions/default/InlineColorEditor/img/color_thumb_back@2x.png b/src/extensions/default/InlineColorEditor/img/color_thumb_back@2x.png index 30bf221ae2a..b4b82069cf3 100644 Binary files a/src/extensions/default/InlineColorEditor/img/color_thumb_back@2x.png and b/src/extensions/default/InlineColorEditor/img/color_thumb_back@2x.png differ diff --git a/src/extensions/default/InlineColorEditor/img/color_thumb_back_dark.png b/src/extensions/default/InlineColorEditor/img/color_thumb_back_dark.png index a8ddb83f30d..be0f1993006 100644 Binary files a/src/extensions/default/InlineColorEditor/img/color_thumb_back_dark.png and b/src/extensions/default/InlineColorEditor/img/color_thumb_back_dark.png differ diff --git a/src/extensions/default/InlineColorEditor/img/color_thumb_back_dark@2x.png b/src/extensions/default/InlineColorEditor/img/color_thumb_back_dark@2x.png index 381dc5d018d..fcf12a1dda5 100644 Binary files a/src/extensions/default/InlineColorEditor/img/color_thumb_back_dark@2x.png and b/src/extensions/default/InlineColorEditor/img/color_thumb_back_dark@2x.png differ diff --git a/src/extensions/default/InlineColorEditor/img/grabber_color-slider.png b/src/extensions/default/InlineColorEditor/img/grabber_color-slider.png index 152b20ba8d4..55be5ba0e5d 100644 Binary files a/src/extensions/default/InlineColorEditor/img/grabber_color-slider.png and b/src/extensions/default/InlineColorEditor/img/grabber_color-slider.png differ diff --git a/src/extensions/default/InlineColorEditor/img/grabber_color-slider@2x.png b/src/extensions/default/InlineColorEditor/img/grabber_color-slider@2x.png index a399b2178c4..91c123617ff 100644 Binary files a/src/extensions/default/InlineColorEditor/img/grabber_color-slider@2x.png and b/src/extensions/default/InlineColorEditor/img/grabber_color-slider@2x.png differ diff --git a/src/extensions/default/InlineColorEditor/img/grabber_color-well.png b/src/extensions/default/InlineColorEditor/img/grabber_color-well.png index bafdf526172..66b9a55da61 100644 Binary files a/src/extensions/default/InlineColorEditor/img/grabber_color-well.png and b/src/extensions/default/InlineColorEditor/img/grabber_color-well.png differ diff --git a/src/extensions/default/InlineColorEditor/img/grabber_color-well@2x.png b/src/extensions/default/InlineColorEditor/img/grabber_color-well@2x.png index 277085a2727..99dab51c33a 100644 Binary files a/src/extensions/default/InlineColorEditor/img/grabber_color-well@2x.png and b/src/extensions/default/InlineColorEditor/img/grabber_color-well@2x.png differ diff --git a/src/extensions/default/InlineColorEditor/img/grabber_gradient.png b/src/extensions/default/InlineColorEditor/img/grabber_gradient.png index dda2cab4be1..a4e9d28e226 100644 Binary files a/src/extensions/default/InlineColorEditor/img/grabber_gradient.png and b/src/extensions/default/InlineColorEditor/img/grabber_gradient.png differ diff --git a/src/extensions/default/InlineColorEditor/img/grabber_gradient@2x.png b/src/extensions/default/InlineColorEditor/img/grabber_gradient@2x.png index cc164f60213..b57a3363ca7 100644 Binary files a/src/extensions/default/InlineColorEditor/img/grabber_gradient@2x.png and b/src/extensions/default/InlineColorEditor/img/grabber_gradient@2x.png differ diff --git a/src/extensions/default/InlineColorEditor/main.js b/src/extensions/default/InlineColorEditor/main.js index 5b03f0ee695..34aed1f0b5b 100644 --- a/src/extensions/default/InlineColorEditor/main.js +++ b/src/extensions/default/InlineColorEditor/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, nomen: true, regexp: true, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/InlineColorEditor/unittests.js b/src/extensions/default/InlineColorEditor/unittests.js index eda6b40af06..1257c07c052 100644 --- a/src/extensions/default/InlineColorEditor/unittests.js +++ b/src/extensions/default/InlineColorEditor/unittests.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, afterEach, waits, runs, $, brackets, waitsForDone, spyOn */ +/*global describe, it, expect, beforeEach, afterEach, waits, runs, waitsForDone, spyOn */ define(function (require, exports, module) { "use strict"; @@ -357,7 +355,7 @@ define(function (require, exports, module) { * @param {boolean=} hide Whether to hide the color picker; default is true. */ function makeUI(initialColor, callback, swatches, hide) { - colorEditor = new ColorEditor($(document.body), + colorEditor = new ColorEditor($(window.document.body), initialColor, callback || function () { }, swatches || defaultSwatches); diff --git a/src/extensions/default/InlineTimingFunctionEditor/BezierCurveEditor.js b/src/extensions/default/InlineTimingFunctionEditor/BezierCurveEditor.js index cb247452fe5..da947b719c9 100644 --- a/src/extensions/default/InlineTimingFunctionEditor/BezierCurveEditor.js +++ b/src/extensions/default/InlineTimingFunctionEditor/BezierCurveEditor.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, nomen: true, regexp: true, maxerr: 50 */ -/*global define, brackets, $, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/InlineTimingFunctionEditor/InlineTimingFunctionEditor.js b/src/extensions/default/InlineTimingFunctionEditor/InlineTimingFunctionEditor.js index dff4fae164b..117ba3ac3cc 100644 --- a/src/extensions/default/InlineTimingFunctionEditor/InlineTimingFunctionEditor.js +++ b/src/extensions/default/InlineTimingFunctionEditor/InlineTimingFunctionEditor.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, nomen: true, regexp: true, maxerr: 50 */ -/*global define, brackets, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/InlineTimingFunctionEditor/StepEditor.js b/src/extensions/default/InlineTimingFunctionEditor/StepEditor.js index 1fdaf92bbeb..0342b999a30 100644 --- a/src/extensions/default/InlineTimingFunctionEditor/StepEditor.js +++ b/src/extensions/default/InlineTimingFunctionEditor/StepEditor.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, nomen: true, regexp: true, maxerr: 50 */ -/*global define, brackets, $, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/InlineTimingFunctionEditor/TimingFunctionUtils.js b/src/extensions/default/InlineTimingFunctionEditor/TimingFunctionUtils.js index db53d59aab8..552e1a714af 100644 --- a/src/extensions/default/InlineTimingFunctionEditor/TimingFunctionUtils.js +++ b/src/extensions/default/InlineTimingFunctionEditor/TimingFunctionUtils.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets */ +/*jslint regexp: true */ /** * Utilities functions related to color matching diff --git a/src/extensions/default/InlineTimingFunctionEditor/grid-dark.png b/src/extensions/default/InlineTimingFunctionEditor/grid-dark.png index c78e9fdf6fc..90b1ed16c10 100644 Binary files a/src/extensions/default/InlineTimingFunctionEditor/grid-dark.png and b/src/extensions/default/InlineTimingFunctionEditor/grid-dark.png differ diff --git a/src/extensions/default/InlineTimingFunctionEditor/grid.png b/src/extensions/default/InlineTimingFunctionEditor/grid.png index 2237c658e55..fdbe74582fd 100644 Binary files a/src/extensions/default/InlineTimingFunctionEditor/grid.png and b/src/extensions/default/InlineTimingFunctionEditor/grid.png differ diff --git a/src/extensions/default/InlineTimingFunctionEditor/main.js b/src/extensions/default/InlineTimingFunctionEditor/main.js index 71f04f7e71a..b65c70fdc69 100644 --- a/src/extensions/default/InlineTimingFunctionEditor/main.js +++ b/src/extensions/default/InlineTimingFunctionEditor/main.js @@ -40,9 +40,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/InlineTimingFunctionEditor/unittests.js b/src/extensions/default/InlineTimingFunctionEditor/unittests.js index 99ec4f57b56..c51f68c80d5 100644 --- a/src/extensions/default/InlineTimingFunctionEditor/unittests.js +++ b/src/extensions/default/InlineTimingFunctionEditor/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, afterEach, runs, $, brackets, waitsForDone */ +/*global describe, it, expect, beforeEach, afterEach, runs, waitsForDone */ define(function (require, exports, module) { "use strict"; @@ -503,7 +502,7 @@ define(function (require, exports, module) { * callback. If none is supplied, a dummy function is passed. */ function makeTimingFuncUI(initialTimingFunction, callback) { - var parent = $(document.body), + var parent = $(window.document.body), match = TimingFunctionUtils.timingFunctionMatch(initialTimingFunction, true), cb = callback || function () { }; diff --git a/src/extensions/default/JSLint/main.js b/src/extensions/default/JSLint/main.js index e6c5d5af04b..56d4a87439a 100644 --- a/src/extensions/default/JSLint/main.js +++ b/src/extensions/default/JSLint/main.js @@ -21,8 +21,7 @@ * */ - -/*global define, JSLINT, brackets */ +/*global JSLINT */ /** * Provides JSLint results via the core linting extension point diff --git a/src/extensions/default/JSLint/unittests.js b/src/extensions/default/JSLint/unittests.js index 85ef36755e3..b53500642d3 100644 --- a/src/extensions/default/JSLint/unittests.js +++ b/src/extensions/default/JSLint/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, afterEach, runs, brackets, waitsForDone, spyOn */ +/*global describe, it, expect, beforeEach, afterEach, runs, waitsForDone, spyOn */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/JavaScriptCodeHints/.gitignore b/src/extensions/default/JavaScriptCodeHints/.gitignore new file mode 100644 index 00000000000..2ccbe4656c6 --- /dev/null +++ b/src/extensions/default/JavaScriptCodeHints/.gitignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/src/extensions/default/JavaScriptCodeHints/HintUtils.js b/src/extensions/default/JavaScriptCodeHints/HintUtils.js index 8daad57e0cc..92c1b6f2d7a 100644 --- a/src/extensions/default/JavaScriptCodeHints/HintUtils.js +++ b/src/extensions/default/JavaScriptCodeHints/HintUtils.js @@ -21,13 +21,12 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; - var Acorn = require("thirdparty/acorn/acorn"); + var Acorn = require("node_modules/acorn/dist/acorn"); var LANGUAGE_ID = "javascript", HTML_LANGUAGE_ID = "html", @@ -143,7 +142,7 @@ define(function (require, exports, module) { return literals.map(function (t) { t.literal = true; t.kind = kind; - t.origin = "ecma5"; + t.origin = "ecmascript"; if (kind === "string") { if (/[\\\\]*[^\\]"/.test(t.value)) { t.delimiter = SINGLE_QUOTE; @@ -166,7 +165,7 @@ define(function (require, exports, module) { function annotateKeywords(keywords) { return keywords.map(function (t) { t.keyword = true; - t.origin = "ecma5"; + t.origin = "ecmascript"; return t; }); } diff --git a/src/extensions/default/JavaScriptCodeHints/HintUtils2.js b/src/extensions/default/JavaScriptCodeHints/HintUtils2.js index 9eecd2f5747..482849c5f75 100644 --- a/src/extensions/default/JavaScriptCodeHints/HintUtils2.js +++ b/src/extensions/default/JavaScriptCodeHints/HintUtils2.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define */ - /** * HintUtils2 was created as a place to put utilities that do not require third party dependencies so * they can be used by tern-worker.js and other JS files. diff --git a/src/extensions/default/JavaScriptCodeHints/MessageIds.js b/src/extensions/default/JavaScriptCodeHints/MessageIds.js index d0d56c98630..30063df41c3 100644 --- a/src/extensions/default/JavaScriptCodeHints/MessageIds.js +++ b/src/extensions/default/JavaScriptCodeHints/MessageIds.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/JavaScriptCodeHints/ParameterHintManager.js b/src/extensions/default/JavaScriptCodeHints/ParameterHintManager.js index e7bb0ed0c1d..ded191dca98 100644 --- a/src/extensions/default/JavaScriptCodeHints/ParameterHintManager.js +++ b/src/extensions/default/JavaScriptCodeHints/ParameterHintManager.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/JavaScriptCodeHints/Preferences.js b/src/extensions/default/JavaScriptCodeHints/Preferences.js index 7273f8e4e1a..0581cfa838d 100644 --- a/src/extensions/default/JavaScriptCodeHints/Preferences.js +++ b/src/extensions/default/JavaScriptCodeHints/Preferences.js @@ -60,8 +60,7 @@ */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, brackets */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/JavaScriptCodeHints/ScopeManager.js b/src/extensions/default/JavaScriptCodeHints/ScopeManager.js index c4cce8e89e8..008ca169566 100644 --- a/src/extensions/default/JavaScriptCodeHints/ScopeManager.js +++ b/src/extensions/default/JavaScriptCodeHints/ScopeManager.js @@ -28,8 +28,7 @@ * from an outer scope. */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $, Worker, setTimeout */ +/*global Worker */ define(function (require, exports, module) { "use strict"; @@ -56,7 +55,7 @@ define(function (require, exports, module) { var ternEnvironment = [], pendingTernRequests = {}, - builtinFiles = ["ecma5.json", "browser.json", "jquery.json"], + builtinFiles = ["ecmascript.json", "browser.json", "jquery.json"], builtinLibraryNames = [], isDocumentDirty = false, _hintCount = 0, @@ -85,7 +84,7 @@ define(function (require, exports, module) { * Read in the json files that have type information for the builtins, dom,etc */ function initTernEnv() { - var path = ExtensionUtils.getModulePath(module, "thirdparty/tern/defs/"), + var path = ExtensionUtils.getModulePath(module, "node_modules/tern/defs/"), files = builtinFiles, library; diff --git a/src/extensions/default/JavaScriptCodeHints/Session.js b/src/extensions/default/JavaScriptCodeHints/Session.js index f98559f9379..f264cf8b3b8 100644 --- a/src/extensions/default/JavaScriptCodeHints/Session.js +++ b/src/extensions/default/JavaScriptCodeHints/Session.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, brackets, $ */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; @@ -33,8 +32,8 @@ define(function (require, exports, module) { HTMLUtils = brackets.getModule("language/HTMLUtils"), HintUtils = require("HintUtils"), ScopeManager = require("ScopeManager"), - Acorn = require("thirdparty/acorn/acorn"), - Acorn_Loose = require("thirdparty/acorn/acorn_loose"); + Acorn = require("node_modules/acorn/dist/acorn"), + Acorn_Loose = require("node_modules/acorn/dist/acorn_loose"); /** * Session objects encapsulate state associated with a hinting session @@ -670,7 +669,9 @@ define(function (require, exports, module) { var ast; try { ast = Acorn.parse(fragment); - } catch (e) { ast = Acorn_Loose.parse_dammit(fragment); } + } catch (e) { + ast = Acorn_Loose.parse_dammit(fragment, {}); + } // find argument as cursor location and bold it. var startOffset = this.getOffsetFromCursor(start), diff --git a/src/extensions/default/JavaScriptCodeHints/fix-acorn.js b/src/extensions/default/JavaScriptCodeHints/fix-acorn.js new file mode 100644 index 00000000000..a13e550fd4c --- /dev/null +++ b/src/extensions/default/JavaScriptCodeHints/fix-acorn.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013 - present Adobe Systems Incorporated. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/*eslint-env node */ +/*jslint node: true */ + +"use strict"; + +var fs = require("fs"); +var path = require("path"); +var fpath = path.resolve(__dirname, "node_modules", "acorn", "dist", "acorn_loose.js"); +var content = fs.readFileSync(fpath, "utf8"); +content = content.replace(/'\.\/acorn\.js'/g, "'./acorn'"); +fs.writeFileSync(fpath, content, "utf8"); diff --git a/src/extensions/default/JavaScriptCodeHints/main.js b/src/extensions/default/JavaScriptCodeHints/main.js index 1b99f3c0dd4..9482bcd1b0b 100644 --- a/src/extensions/default/JavaScriptCodeHints/main.js +++ b/src/extensions/default/JavaScriptCodeHints/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; @@ -44,7 +41,7 @@ define(function (require, exports, module) { HintUtils = require("HintUtils"), ScopeManager = require("ScopeManager"), Session = require("Session"), - Acorn = require("thirdparty/acorn/acorn"); + Acorn = require("node_modules/acorn/dist/acorn"); var session = null, // object that encapsulates the current session state cachedCursor = null, // last cursor of the current hinting session @@ -593,8 +590,8 @@ define(function (require, exports, module) { // to check this, run the hint through Acorns tokenizer // it should result in one token, and that token should either be // a 'name' or a 'keyword', as javascript allows keywords as property names - var tokenizer = Acorn.tokenize(completion); - var currentToken = tokenizer(); + var tokenizer = Acorn.tokenizer(completion); + var currentToken = tokenizer.getToken(); // the name is invalid if the hint is not a 'name' or 'keyword' token if (currentToken.type !== Acorn.tokTypes.name && !currentToken.type.keyword) { @@ -602,7 +599,7 @@ define(function (require, exports, module) { } else { // check for a second token - if there is one (other than 'eof') // then the hint isn't a valid property name either - currentToken = tokenizer(); + currentToken = tokenizer.getToken(); if (currentToken.type !== Acorn.tokTypes.eof) { invalidPropertyName = true; } diff --git a/src/extensions/default/JavaScriptCodeHints/npm-shrinkwrap.json b/src/extensions/default/JavaScriptCodeHints/npm-shrinkwrap.json new file mode 100644 index 00000000000..1108b36c220 --- /dev/null +++ b/src/extensions/default/JavaScriptCodeHints/npm-shrinkwrap.json @@ -0,0 +1,122 @@ +{ + "name": "brackets-javascript-code-hints", + "dependencies": { + "acorn": { + "version": "3.3.0", + "from": "acorn@3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz" + }, + "buffer-shims": { + "version": "1.0.0", + "from": "buffer-shims@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" + }, + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "enhanced-resolve": { + "version": "2.2.2", + "from": "enhanced-resolve@>=2.2.2 <3.0.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-2.2.2.tgz" + }, + "errno": { + "version": "0.1.4", + "from": "errno@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz" + }, + "glob": { + "version": "3.2.11", + "from": "glob@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "dependencies": { + "minimatch": { + "version": "0.3.0", + "from": "minimatch@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" + } + } + }, + "graceful-fs": { + "version": "4.1.6", + "from": "graceful-fs@>=4.1.2 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.6.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "isarray": { + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "lru-cache": { + "version": "2.7.3", + "from": "lru-cache@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz" + }, + "memory-fs": { + "version": "0.3.0", + "from": "memory-fs@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz" + }, + "minimatch": { + "version": "0.2.14", + "from": "minimatch@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz" + }, + "object-assign": { + "version": "4.1.0", + "from": "object-assign@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" + }, + "prr": { + "version": "0.0.0", + "from": "prr@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz" + }, + "readable-stream": { + "version": "2.1.5", + "from": "readable-stream@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz" + }, + "resolve-from": { + "version": "2.0.0", + "from": "resolve-from@2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" + }, + "sigmund": { + "version": "1.0.1", + "from": "sigmund@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "tapable": { + "version": "0.2.4", + "from": "tapable@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.4.tgz" + }, + "tern": { + "version": "0.20.0", + "from": "tern@0.20.0", + "resolved": "https://registry.npmjs.org/tern/-/tern-0.20.0.tgz" + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + } +} diff --git a/src/extensions/default/JavaScriptCodeHints/package.json b/src/extensions/default/JavaScriptCodeHints/package.json new file mode 100644 index 00000000000..3f665e0693a --- /dev/null +++ b/src/extensions/default/JavaScriptCodeHints/package.json @@ -0,0 +1,10 @@ +{ + "name": "brackets-javascript-code-hints", + "dependencies": { + "acorn": "3.3.0", + "tern": "0.20.0" + }, + "scripts": { + "postinstall": "node ./fix-acorn" + } +} diff --git a/src/extensions/default/JavaScriptCodeHints/tern-worker.js b/src/extensions/default/JavaScriptCodeHints/tern-worker.js index 951f9736735..fbe8d9faaca 100644 --- a/src/extensions/default/JavaScriptCodeHints/tern-worker.js +++ b/src/extensions/default/JavaScriptCodeHints/tern-worker.js @@ -21,7 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ /*global self, importScripts, require */ importScripts("thirdparty/requirejs/require.js"); @@ -36,7 +35,7 @@ var config = {}; require(["./MessageIds", "./HintUtils2"], function (messageIds, hintUtils2) { MessageIds = messageIds; HintUtils2 = hintUtils2; - var ternRequire = require.config({baseUrl: "./thirdparty"}); + var ternRequire = require.config({baseUrl: "./node_modules"}); ternRequire(["tern/lib/tern", "tern/lib/infer", "tern/plugin/requirejs", "tern/plugin/doc_comment", "tern/plugin/angular"], function (tern, infer, requirejs, docComment) { Tern = tern; Infer = infer; @@ -111,7 +110,7 @@ var config = {}; * Create a new tern server. * * @param {Object} env - an Object with the environment, as read in from - * the json files in thirdparty/tern/defs + * the json files in node_modules/tern/defs * @param {Array.} files - a list of filenames tern should be aware of */ function initTernServer(env, files) { @@ -123,6 +122,14 @@ var config = {}; }; ternServer = new Tern.Server(ternOptions); + // Since we don't specify projectDir, Tern will "normalize" file names by + // removing any leading "/" (the default projectDir, which cannot be changed to ""). + // This is not a problem on Windows, but on Mac and Linux, it will break + // absolute paths ("/home/" to "home/", for example) + ternServer.normalizeFilename = function (name) { + return name; + }; + files.forEach(function (file) { ternServer.addFile(file); }); diff --git a/src/extensions/default/JavaScriptCodeHints/thirdparty/acorn b/src/extensions/default/JavaScriptCodeHints/thirdparty/acorn deleted file mode 160000 index 78e1d7ada68..00000000000 --- a/src/extensions/default/JavaScriptCodeHints/thirdparty/acorn +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 78e1d7ada684868d92d09555408ae2df1812b5ae diff --git a/src/extensions/default/JavaScriptCodeHints/thirdparty/tern b/src/extensions/default/JavaScriptCodeHints/thirdparty/tern deleted file mode 160000 index 7606a6448a8..00000000000 --- a/src/extensions/default/JavaScriptCodeHints/thirdparty/tern +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7606a6448a8f7a2aacd50d10d9752440689803e8 diff --git a/src/extensions/default/JavaScriptCodeHints/unittests.js b/src/extensions/default/JavaScriptCodeHints/unittests.js index 032742e06bf..9c93ac879e9 100644 --- a/src/extensions/default/JavaScriptCodeHints/unittests.js +++ b/src/extensions/default/JavaScriptCodeHints/unittests.js @@ -21,8 +21,8 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, describe, it, xit, expect, beforeEach, afterEach, waitsFor, runs, brackets, waitsForDone, beforeFirst, afterLast */ +/*jslint regexp: true */ +/*global describe, it, xit, expect, beforeEach, afterEach, waitsFor, runs, waitsForDone, beforeFirst, afterLast */ define(function (require, exports, module) { "use strict"; @@ -1152,8 +1152,8 @@ define(function (require, exports, module) { testDoc.replaceRange("help.", start, start); testEditor.setCursorPos(end); var hintObj = expectHints(JSCodeHints.jsHintProvider); - // check we have a properties from "Function", "Array", and "Date" - hintsPresentOrdered(hintObj, ["apply", "concat", "getSeconds"]); + // check we have a properties from "Function", "String", and "Array" + hintsPresentOrdered(hintObj, ["apply", "charCodeAt", "concat"]); }); it("should switch to guesses after typing a query that does not match any hints", function () { diff --git a/src/extensions/default/JavaScriptQuickEdit/main.js b/src/extensions/default/JavaScriptQuickEdit/main.js index 3a8171b2688..72d95ad8aea 100644 --- a/src/extensions/default/JavaScriptQuickEdit/main.js +++ b/src/extensions/default/JavaScriptQuickEdit/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/JavaScriptQuickEdit/unittests.js b/src/extensions/default/JavaScriptQuickEdit/unittests.js index 6c5fd317775..77380ba2376 100644 --- a/src/extensions/default/JavaScriptQuickEdit/unittests.js +++ b/src/extensions/default/JavaScriptQuickEdit/unittests.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, xit, expect, beforeEach, afterEach, waitsFor, runs, $, brackets, waitsForDone */ +/*global describe, it, xit, expect, beforeEach, afterEach, waitsFor, runs, waitsForDone */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/LESSSupport/main.js b/src/extensions/default/LESSSupport/main.js index 63ed22c5c0f..30891bf5b40 100644 --- a/src/extensions/default/LESSSupport/main.js +++ b/src/extensions/default/LESSSupport/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, nomen: true, regexp: true, maxerr: 50 */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/NavigationAndHistory/main.js b/src/extensions/default/NavigationAndHistory/main.js index 356fe4d4a20..ebe702f0bdc 100644 --- a/src/extensions/default/NavigationAndHistory/main.js +++ b/src/extensions/default/NavigationAndHistory/main.js @@ -21,11 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, regexp: true, nomen: true, indent: 4, maxerr: 50 */ -/*global $, define, brackets */ - - - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/NoDistractions/main.js b/src/extensions/default/NoDistractions/main.js index f610771cfea..c472d8c4e01 100644 --- a/src/extensions/default/NoDistractions/main.js +++ b/src/extensions/default/NoDistractions/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, indent: 4, maxerr: 50 */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/PrefsCodeHints/main.js b/src/extensions/default/PrefsCodeHints/main.js index 3c7a9cdc66d..c22b6903248 100644 --- a/src/extensions/default/PrefsCodeHints/main.js +++ b/src/extensions/default/PrefsCodeHints/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $*/ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/PrefsCodeHints/unittests.js b/src/extensions/default/PrefsCodeHints/unittests.js index 6e29799de01..80e72729613 100644 --- a/src/extensions/default/PrefsCodeHints/unittests.js +++ b/src/extensions/default/PrefsCodeHints/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $, describe, beforeEach, afterEach, it, expect*/ +/*global describe, beforeEach, afterEach, it, expect*/ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/QuickOpenCSS/main.js b/src/extensions/default/QuickOpenCSS/main.js index 4c1892269d5..cc56c09250f 100644 --- a/src/extensions/default/QuickOpenCSS/main.js +++ b/src/extensions/default/QuickOpenCSS/main.js @@ -21,11 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets */ - - - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/QuickOpenHTML/main.js b/src/extensions/default/QuickOpenHTML/main.js index ec2e38cc2eb..2ff2a40cfa7 100644 --- a/src/extensions/default/QuickOpenHTML/main.js +++ b/src/extensions/default/QuickOpenHTML/main.js @@ -21,10 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, regexp: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets */ - - +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/QuickOpenJavaScript/main.js b/src/extensions/default/QuickOpenJavaScript/main.js index 1d009c7e915..bcd0909a3c8 100644 --- a/src/extensions/default/QuickOpenJavaScript/main.js +++ b/src/extensions/default/QuickOpenJavaScript/main.js @@ -21,11 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets */ - - - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/QuickView/main.js b/src/extensions/default/QuickView/main.js index e04f1e6a210..55486e615a2 100644 --- a/src/extensions/default/QuickView/main.js +++ b/src/extensions/default/QuickView/main.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $, window */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/QuickView/unittests.js b/src/extensions/default/QuickView/unittests.js index bbe72ca1b30..3917a96817b 100644 --- a/src/extensions/default/QuickView/unittests.js +++ b/src/extensions/default/QuickView/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, runs, brackets, waitsForDone */ +/*global describe, it, expect, beforeEach, runs, waitsForDone */ define(function (require, exports, module) { "use strict"; @@ -475,7 +474,7 @@ define(function (require, exports, module) { checkImageDataAtPos("data:image/svg+xml;utf8, ", 185, 26); // data url("") containing ' }); - it("Should show image preview for URLs with known image extensions", function() { + it("Should show image preview for URLs with known image extensions", function () { checkImageDataAtPos("http://example.com/image.gif", 194, 20); checkImageDataAtPos("http://example.com/image.png", 195, 20); checkImageDataAtPos("http://example.com/image.jpe", 196, 20); @@ -486,7 +485,7 @@ define(function (require, exports, module) { checkImageDataAtPos("http://example.com/image.svg", 201, 20); }); - it("Should show image preview for extensionless URLs (with protocol) with pref set", function() { + it("Should show image preview for extensionless URLs (with protocol) with pref set", function () { // Flip the pref on and restore when done var original = prefs.get("extensionlessImagePreview"); prefs.set("extensionlessImagePreview", true); @@ -498,7 +497,7 @@ define(function (require, exports, module) { prefs.set("extensionlessImagePreview", original); }); - it("Should not show image preview for extensionless URLs (with protocol) without pref set", function() { + it("Should not show image preview for extensionless URLs (with protocol) without pref set", function () { // Flip the pref off and restore when done var original = prefs.get("extensionlessImagePreview"); prefs.set("extensionlessImagePreview", false); @@ -510,7 +509,7 @@ define(function (require, exports, module) { prefs.set("extensionlessImagePreview", original); }); - it("Should ignore URLs for common non-image extensions", function() { + it("Should ignore URLs for common non-image extensions", function () { expectNoPreviewAtPos(209, 20); // .html expectNoPreviewAtPos(210, 20); // .css expectNoPreviewAtPos(211, 20); // .js diff --git a/src/extensions/default/RecentProjects/main.js b/src/extensions/default/RecentProjects/main.js index 6762ce86277..041e23ac727 100644 --- a/src/extensions/default/RecentProjects/main.js +++ b/src/extensions/default/RecentProjects/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets, window, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/RecentProjects/unittests.js b/src/extensions/default/RecentProjects/unittests.js index 1f9fd0bcd3a..135d3c55d6f 100644 --- a/src/extensions/default/RecentProjects/unittests.js +++ b/src/extensions/default/RecentProjects/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeFirst, afterLast, runs, brackets, waitsFor, spyOn */ +/*global describe, it, expect, beforeFirst, afterLast, runs, waitsFor, spyOn */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/SVGCodeHints/main.js b/src/extensions/default/SVGCodeHints/main.js index 76bc21c42ac..ef430eb442a 100644 --- a/src/extensions/default/SVGCodeHints/main.js +++ b/src/extensions/default/SVGCodeHints/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/SVGCodeHints/unittests.js b/src/extensions/default/SVGCodeHints/unittests.js index ff952a0b977..d95e21faca9 100644 --- a/src/extensions/default/SVGCodeHints/unittests.js +++ b/src/extensions/default/SVGCodeHints/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $, describe, beforeEach, afterEach, it, expect */ +/*global describe, beforeEach, afterEach, it, expect */ define(function (require, exports, module) { "use strict"; @@ -460,7 +459,9 @@ define(function (require, exports, module) { var hints = expectHints(SVGCodeHints.hintProvider); verifyHints(hints, "aliceblue"); // first hint should be aliceblue expect(hints[0].find(".color-swatch").length).toBe(1); - expect(hints[0].find(".color-swatch").css("backgroundColor")).toBe("rgb(240, 248, 255)"); + // CEF 2623 will output "aliceblue" whereas earlier versions give "rgb(240, 248, 255)", + // so we need this ugly hack to make sure this test passes on both + expect(hints[0].find(".color-swatch").css("backgroundColor")).toMatch(/^rgb\(240, 248, 255\)$|aliceblue/); }); it("should always include transparent and currentColor and they should not have a swatch, but class no-swatch-margin", function () { diff --git a/src/extensions/default/StaticServer/StaticServer.js b/src/extensions/default/StaticServer/StaticServer.js index 2f2b2e5d378..adc7ecbb242 100644 --- a/src/extensions/default/StaticServer/StaticServer.js +++ b/src/extensions/default/StaticServer/StaticServer.js @@ -21,11 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, -maxerr: 50, browser: true */ -/*global $, define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/StaticServer/main.js b/src/extensions/default/StaticServer/main.js index f2b17e25e9a..66bbf17b2df 100644 --- a/src/extensions/default/StaticServer/main.js +++ b/src/extensions/default/StaticServer/main.js @@ -21,11 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, -maxerr: 50, browser: true */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/StaticServer/node/StaticServerDomain.js b/src/extensions/default/StaticServer/node/StaticServerDomain.js index 09d1e8a86b3..ec12edaabd3 100644 --- a/src/extensions/default/StaticServer/node/StaticServerDomain.js +++ b/src/extensions/default/StaticServer/node/StaticServerDomain.js @@ -21,460 +21,457 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, node: true */ - -(function () { - "use strict"; - - var http = require("http"), - pathJoin = require("path").join, - connect = require("connect"), - utils = require("connect/lib/utils"), - mime = require("connect/node_modules/send/node_modules/mime"), - parse = utils.parseUrl; - - var _domainManager; - - var FILTER_REQUEST_TIMEOUT = 5000; - - /** - * @private - * @type {number} - * Used to assign unique identifiers to each filter request - */ - var _filterRequestCounter = 0; - - /** - * @private - * @type {number} - * Duration to wait before passing a filtered request to the static file server. - */ - var _filterRequestTimeout = FILTER_REQUEST_TIMEOUT; - - /** - * When Chrome has a css stylesheet replaced over live development, - * it re-checks any image urls in the new css stylesheet. If it has - * to hit the server to check them, this is asynchronous, so it causes - * two re-layouts of the webpage, which causes flickering. By setting - * a max age of five seconds, Chrome won't bother to hit the server - * on each keystroke. So, flickers will happen at most once every five - * seconds. - * - * @const - * @type {number} - */ - var STATIC_CACHE_MAX_AGE = 5000; // 5 seconds - - /** - * @private - * @type {Object.} - * A map from root paths to server instances. - */ - var _servers = {}; - - /** - * @private - * @type {Object.}} - * A map from a request identifier to its request/response mapping. - */ - var _requests = {}; - - /** - * @private - * @type {Object.}} - * A map from root paths to relative paths to rewrite - */ - var _rewritePaths = {}; - - var PATH_KEY_PREFIX = "LiveDev_"; - - /** - * @private - * Removes trailing forward slash for the project root absolute path - * @param {string} path Absolute path for a server - * @returns {string} - */ - function normalizeRootPath(path) { - return (path && path[path.length - 1] === "/") ? path.slice(0, -1) : path; - } +/*eslint-env node */ +/*jslint node: true */ +"use strict"; - /** - * @private - * Generates a key based on a server's absolute path - * @param {string} path Absolute path for a server - * @returns {string} - */ - function getPathKey(path) { - return PATH_KEY_PREFIX + normalizeRootPath(path); - } +var http = require("http"), + pathJoin = require("path").join, + connect = require("connect"), + utils = require("connect/lib/utils"), + mime = require("connect/node_modules/send/node_modules/mime"), + parse = utils.parseUrl; - /** - * @private - * Helper function to create a new server. - * @param {string} path The absolute path that should be the document root - * @param {function(?string, ?httpServer)} cb Callback function that receives - * an error (or null if there was no error) and the server (or null if there - * was an error). - */ - function _createServer(path, port, createCompleteCallback) { - var server, - app, - address, - pathKey = getPathKey(path); - - // create a new map for this server's requests - _requests[pathKey] = {}; - - function requestRoot(server, cb) { - address = server.address(); - - // Request the root file from the project in order to ensure that the - // server is actually initialized. If we don't do this, it seems like - // connect takes time to warm up the server. - var req = http.get( - {host: address.address, port: address.port}, - function (res) { - cb(null, res); - } - ); - req.on("error", function (err) { - cb(err, null); - }); - } +var _domainManager; - function rewrite(req, res, next) { - var location = {pathname: parse(req).pathname}, - hasListener = _rewritePaths[pathKey] && _rewritePaths[pathKey][location.pathname], - requestId = _filterRequestCounter++, - timeoutId; +var FILTER_REQUEST_TIMEOUT = 5000; - // ignore most HTTP methods and files that we're not watching - if (("GET" !== req.method && "HEAD" !== req.method) || !hasListener) { - next(); - return; - } +/** + * @private + * @type {number} + * Used to assign unique identifiers to each filter request + */ +var _filterRequestCounter = 0; - // pause the request and wait for listeners to possibly respond - var pause = utils.pause(req); +/** + * @private + * @type {number} + * Duration to wait before passing a filtered request to the static file server. + */ +var _filterRequestTimeout = FILTER_REQUEST_TIMEOUT; + +/** + * When Chrome has a css stylesheet replaced over live development, + * it re-checks any image urls in the new css stylesheet. If it has + * to hit the server to check them, this is asynchronous, so it causes + * two re-layouts of the webpage, which causes flickering. By setting + * a max age of five seconds, Chrome won't bother to hit the server + * on each keystroke. So, flickers will happen at most once every five + * seconds. + * + * @const + * @type {number} + */ +var STATIC_CACHE_MAX_AGE = 5000; // 5 seconds - function resume(doNext) { - // delete the callback after it's used or we hit the timeout. - // if this path is requested again, a new callback is generated. - delete _requests[pathKey][requestId]; +/** + * @private + * @type {Object.} + * A map from root paths to server instances. + */ +var _servers = {}; - // pass request to next middleware - if (doNext) { - next(); - } +/** + * @private + * @type {Object.}} + * A map from a request identifier to its request/response mapping. + */ +var _requests = {}; - pause.resume(); - } +/** + * @private + * @type {Object.}} + * A map from root paths to relative paths to rewrite + */ +var _rewritePaths = {}; - // map request pathname to response callback - _requests[pathKey][requestId] = function (resData) { - // clear timeout immediately when this callback is called - clearTimeout(timeoutId); +var PATH_KEY_PREFIX = "LiveDev_"; - // response data is optional - if (resData.body) { - // HTTP headers - var type = mime.lookup(location.pathname), - charset = mime.charsets.lookup(type); +/** + * @private + * Removes trailing forward slash for the project root absolute path + * @param {string} path Absolute path for a server + * @returns {string} + */ +function normalizeRootPath(path) { + return (path && path[path.length - 1] === "/") ? path.slice(0, -1) : path; +} + +/** + * @private + * Generates a key based on a server's absolute path + * @param {string} path Absolute path for a server + * @returns {string} + */ +function getPathKey(path) { + return PATH_KEY_PREFIX + normalizeRootPath(path); +} + +/** + * @private + * Helper function to create a new server. + * @param {string} path The absolute path that should be the document root + * @param {function(?string, ?httpServer)} cb Callback function that receives + * an error (or null if there was no error) and the server (or null if there + * was an error). + */ +function _createServer(path, port, createCompleteCallback) { + var server, + app, + address, + pathKey = getPathKey(path); + + // create a new map for this server's requests + _requests[pathKey] = {}; + + function requestRoot(server, cb) { + address = server.address(); + + // Request the root file from the project in order to ensure that the + // server is actually initialized. If we don't do this, it seems like + // connect takes time to warm up the server. + var req = http.get( + {host: address.address, port: address.port}, + function (res) { + cb(null, res); + } + ); + req.on("error", function (err) { + cb(err, null); + }); + } - res.setHeader("Content-Type", type + (charset ? "; charset=" + charset : "")); + function rewrite(req, res, next) { + var location = {pathname: parse(req).pathname}, + hasListener = _rewritePaths[pathKey] && _rewritePaths[pathKey][location.pathname], + requestId = _filterRequestCounter++, + timeoutId; - // TODO (jasonsanjose): off-by-1 error here, why? - // Chrome seems to handle the request without issues when Content-Length is not specified - //res.setHeader("Content-Length", Buffer.byteLength(resData.body /* TODO encoding? */)); + // ignore most HTTP methods and files that we're not watching + if (("GET" !== req.method && "HEAD" !== req.method) || !hasListener) { + next(); + return; + } - // response body - res.end(resData.body); - } + // pause the request and wait for listeners to possibly respond + var pause = utils.pause(req); - // resume the HTTP ServerResponse, pass to next middleware if - // no response data was passed - resume(!resData.body); - }; + function resume(doNext) { + // delete the callback after it's used or we hit the timeout. + // if this path is requested again, a new callback is generated. + delete _requests[pathKey][requestId]; - location.hostname = address.address; - location.port = address.port; - location.root = path; + // pass request to next middleware + if (doNext) { + next(); + } - var request = { - headers: req.headers, - location: location, - id: requestId - }; + pause.resume(); + } - // dispatch request event - _domainManager.emitEvent("staticServer", "requestFilter", [request]); + // map request pathname to response callback + _requests[pathKey][requestId] = function (resData) { + // clear timeout immediately when this callback is called + clearTimeout(timeoutId); - // set a timeout if custom responses are not returned - timeoutId = setTimeout(function () { resume(true); }, _filterRequestTimeout); - } + // response data is optional + if (resData.body) { + // HTTP headers + var type = mime.lookup(location.pathname), + charset = mime.charsets.lookup(type); - app = connect(); - app.use(rewrite); - // JSLint complains if we use `connect.static` because static is a - // reserved word. - app.use(connect["static"](path, { maxAge: STATIC_CACHE_MAX_AGE })); - app.use(connect.directory(path)); - - server = http.createServer(app); - - // Once the server is listening then verify we can handle requests - // before calling the callback - server.on("listening", function () { - requestRoot( - server, - function (err, res) { - if (err) { - createCompleteCallback("Could not GET root after launching server", null); - } else { - createCompleteCallback(null, server); - } - } - ); - }); + res.setHeader("Content-Type", type + (charset ? "; charset=" + charset : "")); - // If the given port/address is in use then use a random port - server.on("error", function (e) { - if (e.code === "EADDRINUSE") { - server.listen(0, "127.0.0.1"); - } else { - throw e; + // TODO (jasonsanjose): off-by-1 error here, why? + // Chrome seems to handle the request without issues when Content-Length is not specified + //res.setHeader("Content-Length", Buffer.byteLength(resData.body /* TODO encoding? */)); + + // response body + res.end(resData.body); } - }); - server.listen(port, "127.0.0.1"); + // resume the HTTP ServerResponse, pass to next middleware if + // no response data was passed + resume(!resData.body); + }; + + location.hostname = address.address; + location.port = address.port; + location.root = path; + + var request = { + headers: req.headers, + location: location, + id: requestId + }; + + // dispatch request event + _domainManager.emitEvent("staticServer", "requestFilter", [request]); + + // set a timeout if custom responses are not returned + timeoutId = setTimeout(function () { resume(true); }, _filterRequestTimeout); } - /** - * @private - * Handler function for the staticServer.getServer command. If a server - * already exists for the given path, returns that, otherwise starts a new - * one. - * @param {string} path The absolute path that should be the document root - * @param {function(?string, ?{address: string, family: string, - * port: number})} cb Callback that should receive the address information - * for the server. First argument is the error string (or null if no error), - * second argument is the address object (or null if there was an error). - * The "family" property of the address indicates whether the address is, - * for example, IPv4, IPv6, or a UNIX socket. - */ - function _cmdGetServer(path, port, cb) { - // Make sure the key doesn't conflict with some built-in property of Object. - var pathKey = getPathKey(path); - if (_servers[pathKey]) { - cb(null, _servers[pathKey].address()); - } else { - _createServer(path, port, function (err, server) { + app = connect(); + app.use(rewrite); + // JSLint complains if we use `connect.static` because static is a + // reserved word. + app.use(connect["static"](path, { maxAge: STATIC_CACHE_MAX_AGE })); + app.use(connect.directory(path)); + + server = http.createServer(app); + + // Once the server is listening then verify we can handle requests + // before calling the callback + server.on("listening", function () { + requestRoot( + server, + function (err, res) { if (err) { - cb(err, null); + createCompleteCallback("Could not GET root after launching server", null); } else { - _servers[pathKey] = server; - _rewritePaths[pathKey] = {}; - cb(null, server.address()); + createCompleteCallback(null, server); } - }); - } - } + } + ); + }); - /** - * @private - * Handler function for the staticServer.closeServer command. If a server - * exists for the given path, closes it, otherwise does nothing. Note that - * this function doesn't wait for the actual socket to close, since the - * server will actually wait for all client connections to close (which can - * be awhile); but once it returns, you're guaranteed to get a different - * server the next time you call getServer() on the same path. - * - * @param {string} path The absolute path whose server we should close. - * @return {boolean} true if there was a server for that path, false otherwise - */ - function _cmdCloseServer(path, cba) { - var pathKey = getPathKey(path); - if (_servers[pathKey]) { - var serverToClose = _servers[pathKey]; - delete _servers[pathKey]; - serverToClose.close(); - return true; + // If the given port/address is in use then use a random port + server.on("error", function (e) { + if (e.code === "EADDRINUSE") { + server.listen(0, "127.0.0.1"); + } else { + throw e; } - return false; - } - - /** - * @private - * Defines a set of paths from a server's root path to watch and fire "request" events for. - * - * @param {string} path The absolute path whose server we should watch - * @param {Array.} paths An array of root-relative paths to watch. - * Each path should begin with a forward slash "/". - */ - function _cmdSetRequestFilterPaths(root, paths) { - var pathKey = getPathKey(root), - rewritePaths = {}; - - // reset list of filtered paths for each call to setRequestFilterPaths - _rewritePaths[pathKey] = rewritePaths; - - paths.forEach(function (path) { - rewritePaths[path] = pathJoin(root, path); + }); + + server.listen(port, "127.0.0.1"); +} + +/** + * @private + * Handler function for the staticServer.getServer command. If a server + * already exists for the given path, returns that, otherwise starts a new + * one. + * @param {string} path The absolute path that should be the document root + * @param {function(?string, ?{address: string, family: string, + * port: number})} cb Callback that should receive the address information + * for the server. First argument is the error string (or null if no error), + * second argument is the address object (or null if there was an error). + * The "family" property of the address indicates whether the address is, + * for example, IPv4, IPv6, or a UNIX socket. + */ +function _cmdGetServer(path, port, cb) { + // Make sure the key doesn't conflict with some built-in property of Object. + var pathKey = getPathKey(path); + if (_servers[pathKey]) { + cb(null, _servers[pathKey].address()); + } else { + _createServer(path, port, function (err, server) { + if (err) { + cb(err, null); + } else { + _servers[pathKey] = server; + _rewritePaths[pathKey] = {}; + cb(null, server.address()); + } }); } - - /** - * @private - * Overrides the server response from static middleware with the provided - * response data. This should be called only in response to a filtered request. - * - * @param {string} path The absolute path of the server - * @param {string} root The relative path of the file beginning with a forward slash "/" - * @param {!Object} resData Response data to use - */ - function _cmdWriteFilteredResponse(root, path, resData) { - var pathKey = getPathKey(root), - callback = _requests[pathKey][resData.id]; - - if (callback) { - callback(resData); - } else { - console.warn("writeFilteredResponse: Missing callback for %s. This command must only be called after a requestFilter event has fired for a path.", pathJoin(root, path)); - } +} + +/** + * @private + * Handler function for the staticServer.closeServer command. If a server + * exists for the given path, closes it, otherwise does nothing. Note that + * this function doesn't wait for the actual socket to close, since the + * server will actually wait for all client connections to close (which can + * be awhile); but once it returns, you're guaranteed to get a different + * server the next time you call getServer() on the same path. + * + * @param {string} path The absolute path whose server we should close. + * @return {boolean} true if there was a server for that path, false otherwise + */ +function _cmdCloseServer(path, cba) { + var pathKey = getPathKey(path); + if (_servers[pathKey]) { + var serverToClose = _servers[pathKey]; + delete _servers[pathKey]; + serverToClose.close(); + return true; } + return false; +} - /** - * @private - * Unit tests only. Set, or reset, timeout value for filtered requests. - * - * @param {number=} timeout Duration to wait before passing a filtered request to the static file server. - * If omitted, timeout is reset to FILTER_REQUEST_TIMEOUT (5s). - */ - function _cmdSetRequestFilterTimeout(timeout) { - timeout = (timeout === undefined) ? FILTER_REQUEST_TIMEOUT : timeout; - _filterRequestTimeout = timeout; +/** + * @private + * Defines a set of paths from a server's root path to watch and fire "request" events for. + * + * @param {string} path The absolute path whose server we should watch + * @param {Array.} paths An array of root-relative paths to watch. + * Each path should begin with a forward slash "/". + */ +function _cmdSetRequestFilterPaths(root, paths) { + var pathKey = getPathKey(root), + rewritePaths = {}; + + // reset list of filtered paths for each call to setRequestFilterPaths + _rewritePaths[pathKey] = rewritePaths; + + paths.forEach(function (path) { + rewritePaths[path] = pathJoin(root, path); + }); +} + +/** + * @private + * Overrides the server response from static middleware with the provided + * response data. This should be called only in response to a filtered request. + * + * @param {string} path The absolute path of the server + * @param {string} root The relative path of the file beginning with a forward slash "/" + * @param {!Object} resData Response data to use + */ +function _cmdWriteFilteredResponse(root, path, resData) { + var pathKey = getPathKey(root), + callback = _requests[pathKey][resData.id]; + + if (callback) { + callback(resData); + } else { + console.warn("writeFilteredResponse: Missing callback for %s. This command must only be called after a requestFilter event has fired for a path.", pathJoin(root, path)); } +} - /** - * Initializes the StaticServer domain with its commands. - * @param {DomainManager} domainManager The DomainManager for the server - */ - function init(domainManager) { - _domainManager = domainManager; +/** + * @private + * Unit tests only. Set, or reset, timeout value for filtered requests. + * + * @param {number=} timeout Duration to wait before passing a filtered request to the static file server. + * If omitted, timeout is reset to FILTER_REQUEST_TIMEOUT (5s). + */ +function _cmdSetRequestFilterTimeout(timeout) { + timeout = (timeout === undefined) ? FILTER_REQUEST_TIMEOUT : timeout; + _filterRequestTimeout = timeout; +} + +/** + * Initializes the StaticServer domain with its commands. + * @param {DomainManager} domainManager The DomainManager for the server + */ +function init(domainManager) { + _domainManager = domainManager; - if (!domainManager.hasDomain("staticServer")) { - domainManager.registerDomain("staticServer", {major: 0, minor: 1}); - } - _domainManager.registerCommand( - "staticServer", - "_setRequestFilterTimeout", - _cmdSetRequestFilterTimeout, - false, - "Unit tests only. Set timeout value for filtered requests.", - [{ - name: "timeout", - type: "number", - description: "Duration to wait before passing a filtered request to the static file server." - }], - [] - ); - _domainManager.registerCommand( - "staticServer", - "getServer", - _cmdGetServer, - true, - "Starts or returns an existing server for the given path.", - [ - { - name: "path", - type: "string", - description: "Absolute filesystem path for root of server." - }, - { - name: "port", - type: "number", - description: "Port number to use for HTTP server. Pass zero to assign a random port." - } - ], - [{ - name: "address", - type: "{address: string, family: string, port: number}", - description: "hostname (stored in 'address' parameter), port, and socket type (stored in 'family' parameter) for the server. Currently, 'family' will always be 'IPv4'." - }] - ); - _domainManager.registerCommand( - "staticServer", - "closeServer", - _cmdCloseServer, - false, - "Closes the server for the given path.", - [{ + if (!domainManager.hasDomain("staticServer")) { + domainManager.registerDomain("staticServer", {major: 0, minor: 1}); + } + _domainManager.registerCommand( + "staticServer", + "_setRequestFilterTimeout", + _cmdSetRequestFilterTimeout, + false, + "Unit tests only. Set timeout value for filtered requests.", + [{ + name: "timeout", + type: "number", + description: "Duration to wait before passing a filtered request to the static file server." + }], + [] + ); + _domainManager.registerCommand( + "staticServer", + "getServer", + _cmdGetServer, + true, + "Starts or returns an existing server for the given path.", + [ + { name: "path", type: "string", + description: "Absolute filesystem path for root of server." + }, + { + name: "port", + type: "number", + description: "Port number to use for HTTP server. Pass zero to assign a random port." + } + ], + [{ + name: "address", + type: "{address: string, family: string, port: number}", + description: "hostname (stored in 'address' parameter), port, and socket type (stored in 'family' parameter) for the server. Currently, 'family' will always be 'IPv4'." + }] + ); + _domainManager.registerCommand( + "staticServer", + "closeServer", + _cmdCloseServer, + false, + "Closes the server for the given path.", + [{ + name: "path", + type: "string", + description: "absolute filesystem path for root of server" + }], + [{ + name: "result", + type: "boolean", + description: "indicates whether a server was found for the specific path then closed" + }] + ); + _domainManager.registerCommand( + "staticServer", + "setRequestFilterPaths", + _cmdSetRequestFilterPaths, + false, + "Defines a set of paths from a server's root path to watch and fire 'requestFilter' events for.", + [ + { + name: "root", + type: "string", description: "absolute filesystem path for root of server" - }], - [{ - name: "result", - type: "boolean", - description: "indicates whether a server was found for the specific path then closed" - }] - ); - _domainManager.registerCommand( - "staticServer", - "setRequestFilterPaths", - _cmdSetRequestFilterPaths, - false, - "Defines a set of paths from a server's root path to watch and fire 'requestFilter' events for.", - [ - { - name: "root", - type: "string", - description: "absolute filesystem path for root of server" - }, - { - name: "paths", - type: "Array", - description: "path to notify" - } - ], - [] - ); - _domainManager.registerCommand( - "staticServer", - "writeFilteredResponse", - _cmdWriteFilteredResponse, - false, - "Overrides the server response from static middleware with the provided response data. This should be called only in response to a filtered request.", - [ - { - name: "root", - type: "string", - description: "absolute filesystem path for root of server" - }, - { - name: "path", - type: "string", - description: "path to rewrite" - }, - { - name: "resData", - type: "{body: string, headers: Array}", - description: "TODO" - } - ], - [] - ); - _domainManager.registerEvent( - "staticServer", - "requestFilter", - [{ - name: "location", - type: "{hostname: string, pathname: string, port: number, root: string: id: number}", - description: "request path" - }] - ); - } - - exports.init = init; - -}()); + }, + { + name: "paths", + type: "Array", + description: "path to notify" + } + ], + [] + ); + _domainManager.registerCommand( + "staticServer", + "writeFilteredResponse", + _cmdWriteFilteredResponse, + false, + "Overrides the server response from static middleware with the provided response data. This should be called only in response to a filtered request.", + [ + { + name: "root", + type: "string", + description: "absolute filesystem path for root of server" + }, + { + name: "path", + type: "string", + description: "path to rewrite" + }, + { + name: "resData", + type: "{body: string, headers: Array}", + description: "TODO" + } + ], + [] + ); + _domainManager.registerEvent( + "staticServer", + "requestFilter", + [{ + name: "location", + type: "{hostname: string, pathname: string, port: number, root: string: id: number}", + description: "request path" + }] + ); +} + +exports.init = init; diff --git a/src/extensions/default/StaticServer/unittests.js b/src/extensions/default/StaticServer/unittests.js index e574c5fa4f8..fd9f839bee0 100644 --- a/src/extensions/default/StaticServer/unittests.js +++ b/src/extensions/default/StaticServer/unittests.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, afterEach, waits, waitsFor, waitsForDone, runs, $, brackets, waitsForDone, spyOn */ +/*global describe, it, expect, beforeEach, afterEach, waits, waitsFor, waitsForDone, runs, waitsForDone, spyOn */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/UrlCodeHints/main.js b/src/extensions/default/UrlCodeHints/main.js index aa076a8a22c..cb72d5771d0 100644 --- a/src/extensions/default/UrlCodeHints/main.js +++ b/src/extensions/default/UrlCodeHints/main.js @@ -20,10 +20,6 @@ * DEALINGS IN THE SOFTWARE. */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $, window */ - - define(function (require, exports, module) { "use strict"; @@ -752,8 +748,6 @@ define(function (require, exports, module) { } else if (tagInfo.position.offset === 0) { completion = "\"" + completion + "\""; } - } else if (completion === tagInfo.attr.value) { - shouldReplace = false; } if (shouldReplace) { diff --git a/src/extensions/default/UrlCodeHints/testfiles/test.html b/src/extensions/default/UrlCodeHints/testfiles/test.html index 74a4b59067b..96e5b1f848d 100644 --- a/src/extensions/default/UrlCodeHints/testfiles/test.html +++ b/src/extensions/default/UrlCodeHints/testfiles/test.html @@ -23,5 +23,6 @@ Site-root relative: root folder Results + diff --git a/src/extensions/default/UrlCodeHints/unittests.js b/src/extensions/default/UrlCodeHints/unittests.js index 9ed0d13381c..f7569657e54 100644 --- a/src/extensions/default/UrlCodeHints/unittests.js +++ b/src/extensions/default/UrlCodeHints/unittests.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, afterEach, beforeFirst, afterLast, waitsFor, runs, brackets, waitsForDone */ +/*global describe, it, expect, beforeEach, afterEach, beforeFirst, afterLast, waitsFor, runs, waitsForDone */ define(function (require, exports, module) { "use strict"; @@ -620,6 +618,34 @@ define(function (require, exports, module) { }); }); + it("should completely replace file in HTML", function () { + var pos1 = { line: 25, ch: 11 }, + pos2 = { line: 25, ch: 27 }, + pos3 = { line: 25, ch: 34 }; + + runs(function () { + testEditor.setCursorPos(pos2); + hintsObj = null; + expectAsyncHints(UrlCodeHints.hintProvider); + }); + + runs(function () { + expect(hintsObj).toBeTruthy(); + expect(hintsObj.hints).toBeTruthy(); + expect(hintsObj.hints.length).toBe(1); + expect(hintsObj.hints[0]).toBe("subfolder/chevron.png"); + + // False indicates hints were closed after insertion + expect(UrlCodeHints.hintProvider.insertHint(hintsObj.hints[0])).toBe(false); + + // File name was completely replaced, not just appended to + expect(testDocument.getRange(pos1, pos3)).toEqual("'subfolder/chevron.png'"); + + // Cursor was moved past closing single-quote + expect(testEditor.getCursorPos()).toEqual(pos3); + }); + }); + it("should insert filtered folder in HTML", function () { var pos1 = { line: 23, ch: 11 }, pos2 = { line: 23, ch: 14 }, diff --git a/src/extensions/default/WebPlatformDocs/InlineDocsViewer.js b/src/extensions/default/WebPlatformDocs/InlineDocsViewer.js index 70f7b002040..b615151e2a8 100644 --- a/src/extensions/default/WebPlatformDocs/InlineDocsViewer.js +++ b/src/extensions/default/WebPlatformDocs/InlineDocsViewer.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $, window */ - /** * Inline widget to display WebPlatformDocs JSON data nicely formatted */ diff --git a/src/extensions/default/WebPlatformDocs/main.js b/src/extensions/default/WebPlatformDocs/main.js index 1ff9f1bc349..28e6fc8ba2a 100644 --- a/src/extensions/default/WebPlatformDocs/main.js +++ b/src/extensions/default/WebPlatformDocs/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global $, define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/default/WebPlatformDocs/unittests.js b/src/extensions/default/WebPlatformDocs/unittests.js index 883d24d67c4..01c535fc492 100644 --- a/src/extensions/default/WebPlatformDocs/unittests.js +++ b/src/extensions/default/WebPlatformDocs/unittests.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, describe, it, expect, beforeEach, afterEach, waitsFor, runs, $, brackets, waitsForDone, waitsForFail */ +/*global describe, it, expect, beforeEach, afterEach, waitsFor, runs, waitsForDone, waitsForFail */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/samples/BracketsConfigCentral/htmlContent/logo-sm.png b/src/extensions/samples/BracketsConfigCentral/htmlContent/logo-sm.png index 5891c3c2da5..7fe5a8a3cc7 100644 Binary files a/src/extensions/samples/BracketsConfigCentral/htmlContent/logo-sm.png and b/src/extensions/samples/BracketsConfigCentral/htmlContent/logo-sm.png differ diff --git a/src/extensions/samples/BracketsConfigCentral/main.js b/src/extensions/samples/BracketsConfigCentral/main.js index 7199b6a58d0..74c686bd9e0 100644 --- a/src/extensions/samples/BracketsConfigCentral/main.js +++ b/src/extensions/samples/BracketsConfigCentral/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/samples/ContextMenuTest/main.js b/src/extensions/samples/ContextMenuTest/main.js index ff18cd6208f..19ebaa4bf0b 100644 --- a/src/extensions/samples/ContextMenuTest/main.js +++ b/src/extensions/samples/ContextMenuTest/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets */ - define(function (require, exports, module) { "use strict"; @@ -46,21 +42,21 @@ define(function (require, exports, module) { var checked = command1.getChecked(); if (checked) { - alert("Unchecking self. Disabling next."); + window.alert("Unchecking self. Disabling next."); command2.setEnabled(false); } else { - alert("Checking self. Enabling next."); + window.alert("Checking self. Enabling next."); command2.setEnabled(true); } command1.setChecked(!checked); } function TestCommand2() { - alert("Executing command 2"); + window.alert("Executing command 2"); } function TestCommand3() { - alert("Executing command 3"); + window.alert("Executing command 3"); } // Register the functions as commands diff --git a/src/extensions/samples/InlineImageViewer/InlineImageViewer.js b/src/extensions/samples/InlineImageViewer/InlineImageViewer.js index 23c41ef0a5c..283578d4f5b 100644 --- a/src/extensions/samples/InlineImageViewer/InlineImageViewer.js +++ b/src/extensions/samples/InlineImageViewer/InlineImageViewer.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $, window */ - define(function (require, exports, module) { 'use strict'; diff --git a/src/extensions/samples/InlineImageViewer/main.js b/src/extensions/samples/InlineImageViewer/main.js index 9e617d6212a..5201c479321 100644 --- a/src/extensions/samples/InlineImageViewer/main.js +++ b/src/extensions/samples/InlineImageViewer/main.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ +/*jslint regexp: true */ define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/samples/LocalizationExample/main.js b/src/extensions/samples/LocalizationExample/main.js index 74a802dafc3..8c25c5fa358 100644 --- a/src/extensions/samples/LocalizationExample/main.js +++ b/src/extensions/samples/LocalizationExample/main.js @@ -21,11 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, require */ - - require.config({ paths: { "text" : "lib/text", @@ -56,7 +51,7 @@ define(function (require, exports, module) { // This sample command first shows an alert passing in a localized // string in JavaScript then it shows a localized HTML dialog. function testCommand() { - alert(Strings.ALERT_MESSAGE); + window.alert(Strings.ALERT_MESSAGE); // Localize the dialog using Strings as the datasource and use it as the dialog template var localizedTemplate = Mustache.render(browserWrapperHtml, Strings); diff --git a/src/extensions/samples/LocalizationExample/nls/fr/strings.js b/src/extensions/samples/LocalizationExample/nls/fr/strings.js index 4b72c3884c1..9ec142ff179 100644 --- a/src/extensions/samples/LocalizationExample/nls/fr/strings.js +++ b/src/extensions/samples/LocalizationExample/nls/fr/strings.js @@ -23,10 +23,6 @@ // French Translation -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - - define({ "COMMAND_NAME" : "Ma nouvelle commande", "ALERT_MESSAGE" : "Ceci est un exemple d'alerte", diff --git a/src/extensions/samples/LocalizationExample/nls/root/strings.js b/src/extensions/samples/LocalizationExample/nls/root/strings.js index ce75521660b..b8ab078a04a 100644 --- a/src/extensions/samples/LocalizationExample/nls/root/strings.js +++ b/src/extensions/samples/LocalizationExample/nls/root/strings.js @@ -23,9 +23,6 @@ // English - root strings -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ "COMMAND_NAME" : "My New Command", "ALERT_MESSAGE" : "This is a sample alert message", diff --git a/src/extensions/samples/LocalizationExample/nls/strings.js b/src/extensions/samples/LocalizationExample/nls/strings.js index 1119fa97cb9..9c12a14c9ef 100644 --- a/src/extensions/samples/LocalizationExample/nls/strings.js +++ b/src/extensions/samples/LocalizationExample/nls/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { 'use strict'; diff --git a/src/extensions/samples/LocalizationExample/strings.js b/src/extensions/samples/LocalizationExample/strings.js index 2ae2877984f..f604fcfa2a4 100644 --- a/src/extensions/samples/LocalizationExample/strings.js +++ b/src/extensions/samples/LocalizationExample/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * This file provides the interface to user visible strings in Brackets. Code that needs * to display strings should should load this module by calling var Strings = require("strings"). diff --git a/src/extensions/samples/TypingSpeedLogger/main.js b/src/extensions/samples/TypingSpeedLogger/main.js index 3d74a9cee0f..447be90bf21 100644 --- a/src/extensions/samples/TypingSpeedLogger/main.js +++ b/src/extensions/samples/TypingSpeedLogger/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/samples/circular_dependency_test/main.js b/src/extensions/samples/circular_dependency_test/main.js index 85c948a5bf4..2d003564ac8 100644 --- a/src/extensions/samples/circular_dependency_test/main.js +++ b/src/extensions/samples/circular_dependency_test/main.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/extensions/samples/circular_dependency_test/secondary.js b/src/extensions/samples/circular_dependency_test/secondary.js index ac037bae9e5..f1fb488ea98 100644 --- a/src/extensions/samples/circular_dependency_test/secondary.js +++ b/src/extensions/samples/circular_dependency_test/secondary.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/file/FileUtils.js b/src/file/FileUtils.js index 784794591b9..f1088b20945 100644 --- a/src/file/FileUtils.js +++ b/src/file/FileUtils.js @@ -21,9 +21,8 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, unescape, window */ +/*jslint regexp: true */ +/*global unescape */ /** * Set of utilities for working with files and text content. diff --git a/src/filesystem/Directory.js b/src/filesystem/Directory.js index b0080b74b08..ff2b207487b 100644 --- a/src/filesystem/Directory.js +++ b/src/filesystem/Directory.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/filesystem/File.js b/src/filesystem/File.js index ff41057f598..fc3b38e79e9 100644 --- a/src/filesystem/File.js +++ b/src/filesystem/File.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/filesystem/FileIndex.js b/src/filesystem/FileIndex.js index 1951b73d55c..6097908bc2e 100644 --- a/src/filesystem/FileIndex.js +++ b/src/filesystem/FileIndex.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * FileIndex is an internal module used by FileSystem to maintain an index of all files and directories. * diff --git a/src/filesystem/FileSystem.js b/src/filesystem/FileSystem.js index 807f7391fff..8a3227dec5f 100644 --- a/src/filesystem/FileSystem.js +++ b/src/filesystem/FileSystem.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * FileSystem is a model object representing a complete file system. This object creates * and manages File and Directory instances, dispatches events when the file system changes, @@ -264,7 +261,8 @@ define(function (require, exports, module) { FileSystem.prototype._watchOrUnwatchEntry = function (entry, watchedRoot, callback, shouldWatch) { var impl = this._impl, recursiveWatch = impl.recursiveWatch, - commandName = shouldWatch ? "watchPath" : "unwatchPath"; + commandName = shouldWatch ? "watchPath" : "unwatchPath", + filterGlobs = watchedRoot.filterGlobs; if (recursiveWatch) { // The impl can watch the entire subtree with one call on the root (we also fall into this case for @@ -276,7 +274,7 @@ define(function (require, exports, module) { } else { // The impl will handle finding all subdirectories to watch. this._enqueueWatchRequest(function (requestCb) { - impl[commandName].call(impl, entry.fullPath, requestCb); + impl[commandName].call(impl, entry.fullPath, filterGlobs, requestCb); }.bind(this), callback); } } else if (shouldWatch) { @@ -317,7 +315,7 @@ define(function (require, exports, module) { }; entriesToWatch.forEach(function (entry) { - impl.watchPath(entry.fullPath, watchCallback); + impl.watchPath(entry.fullPath, filterGlobs, watchCallback); }); }); }, callback); @@ -854,11 +852,19 @@ define(function (require, exports, module) { * @param {function(string): boolean} filter - Returns true if a particular item should * be watched, given its name (not full path). Items that are ignored are also * filtered from Directory.getContents() results within this subtree. + * @param {Array} filterGlobs - glob compatible string definitions for + * filtering out events on the node side. * @param {function(?string)=} callback - A function that is called when the watch has * completed. If the watch fails, the function will have a non-null FileSystemError * string parametr. */ - FileSystem.prototype.watch = function (entry, filter, callback) { + FileSystem.prototype.watch = function (entry, filter, filterGlobs, callback) { + // make filterGlobs an optional argument to stay backwards compatible + if (typeof callback === "undefined" && typeof filterGlobs === "function") { + callback = filterGlobs; + filterGlobs = null; + } + var fullPath = entry.fullPath; callback = callback || function () {}; @@ -885,7 +891,7 @@ define(function (require, exports, module) { return; } - var watchedRoot = new WatchedRoot(entry, filter); + var watchedRoot = new WatchedRoot(entry, filter, filterGlobs); this._watchedRoots[fullPath] = watchedRoot; diff --git a/src/filesystem/FileSystemEntry.js b/src/filesystem/FileSystemEntry.js index d2973297b91..ea6f718048c 100644 --- a/src/filesystem/FileSystemEntry.js +++ b/src/filesystem/FileSystemEntry.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - /* * To ensure cache coherence, current and future asynchronous state-changing * operations of FileSystemEntry and its subclasses should implement the diff --git a/src/filesystem/FileSystemError.js b/src/filesystem/FileSystemError.js index 104e1d74998..bb37bc33437 100644 --- a/src/filesystem/FileSystemError.js +++ b/src/filesystem/FileSystemError.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * FileSystemError describes the errors that can occur when using the FileSystem, File, * and Directory modules. diff --git a/src/filesystem/FileSystemStats.js b/src/filesystem/FileSystemStats.js index 69349a2458d..801b51b8de0 100644 --- a/src/filesystem/FileSystemStats.js +++ b/src/filesystem/FileSystemStats.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * The FileSystemStats represents a particular FileSystemEntry's stats. */ @@ -40,9 +36,13 @@ define(function (require, exports, module) { this._isFile = isFile; this._isDirectory = !isFile; - this._mtime = options.mtime; + // in case of stats transferred over a node-domain, + // mtime will have JSON-ified value which needs to be restored + this._mtime = options.mtime instanceof Date ? options.mtime : new Date(options.mtime); this._size = options.size; - this._hash = options.hash; + // hash is a property introduced by brackets and it's calculated + // as a valueOf modification time -> calculate here if it's not present + this._hash = options.hash || this._mtime.valueOf(); var realPath = options.realPath; if (realPath) { diff --git a/src/filesystem/WatchedRoot.js b/src/filesystem/WatchedRoot.js index 897faa19a79..f8bd78fcb35 100644 --- a/src/filesystem/WatchedRoot.js +++ b/src/filesystem/WatchedRoot.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; @@ -41,10 +37,12 @@ define(function (require, exports, module) { * @constructor * @param {File|Directory} entry * @param {function(string, string):boolean} filter + * @param {Array} filterGlobs */ - function WatchedRoot(entry, filter) { + function WatchedRoot(entry, filter, filterGlobs) { this.entry = entry; this.filter = filter; + this.filterGlobs = filterGlobs; } // Status constants @@ -62,6 +60,11 @@ define(function (require, exports, module) { */ WatchedRoot.prototype.filter = null; + /** + * @type {Array} + */ + WatchedRoot.prototype.filterGlobs = null; + /** * @type {number} */ diff --git a/src/filesystem/impls/appshell/AppshellFileSystem.js b/src/filesystem/impls/appshell/AppshellFileSystem.js index 317ba6b17bf..a594b98a596 100644 --- a/src/filesystem/impls/appshell/AppshellFileSystem.js +++ b/src/filesystem/impls/appshell/AppshellFileSystem.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, appshell, window */ +/*global appshell */ define(function (require, exports, module) { "use strict"; @@ -80,29 +78,16 @@ define(function (require, exports, module) { * Enqueue a file change event for eventual reporting back to the FileSystem. * * @param {string} changedPath The path that was changed - * @param {boolean} needsStats Whether or not the eventual change event should include stats + * @param {object} stats Stats coming from the underlying watcher, if available * @private */ - function _enqueueChange(changedPath, needsStats) { - _pendingChanges[changedPath] = _pendingChanges[changedPath] || needsStats; - + function _enqueueChange(changedPath, stats) { + _pendingChanges[changedPath] = stats; if (!_changeTimeout) { _changeTimeout = window.setTimeout(function () { if (_changeCallback) { Object.keys(_pendingChanges).forEach(function (path) { - var needsStats = _pendingChanges[path]; - if (needsStats) { - exports.stat(path, function (err, stats) { - if (err) { - // warning has been removed due to spamming the console - see #7332 - // console.warn("Unable to stat changed path: ", path, err); - return; - } - _changeCallback(path, stats); - }); - } else { - _changeCallback(path); - } + _changeCallback(path, _pendingChanges[path]); }); } @@ -116,25 +101,32 @@ define(function (require, exports, module) { * Event handler for the Node fileWatcher domain's change event. * * @param {jQuery.Event} The underlying change event - * @param {string} path The path that is reported to have changed - * @param {string} event The type of the event: either "change" or "rename" - * @param {string=} filename The name of the file that changed. + * @param {string} event The type of the event: "changed", "created" or "deleted" + * @param {string} parentDirPath The path to the directory holding entry that has changed + * @param {string=} entryName The name of the file/directory that has changed + * @param {object} statsObj Object that can be used to construct FileSystemStats * @private */ - function _fileWatcherChange(evt, path, event, filename) { + function _fileWatcherChange(evt, event, parentDirPath, entryName, statsObj) { var change; - - if (event === "change") { - // Only register change events if filename is passed - if (filename) { - // an existing file was modified; stats are needed - change = path + filename; - _enqueueChange(change, true); + switch (event) { + case "changed": + // an existing file/directory was modified; stats are passed if available + var fsStats; + if (statsObj) { + fsStats = new FileSystemStats(statsObj); + } else { + console.warn("FileWatcherDomain was expected to deliver stats for changed event!"); } - } else if (event === "rename") { - // a new file was created; no stats are needed - change = path; - _enqueueChange(change, false); + _enqueueChange(parentDirPath + entryName, fsStats); + break; + case "created": + case "deleted": + // file/directory was created/deleted; fire change on parent to reload contents + _enqueueChange(parentDirPath, null); + break; + default: + console.error("Unexpected 'change' event:", event); } } @@ -522,9 +514,10 @@ define(function (require, exports, module) { * when the recursiveWatch property of this module is true. * * @param {string} path + * @param {Array} ignored * @param {function(?string)=} callback */ - function watchPath(path, callback) { + function watchPath(path, ignored, callback) { if (_isRunningOnWindowsXP) { callback(FileSystemError.NOT_SUPPORTED); return; @@ -538,7 +531,7 @@ define(function (require, exports, module) { } return; } - _nodeDomain.exec("watchPath", path) + _nodeDomain.exec("watchPath", path, ignored) .then(callback, callback); }); } @@ -546,11 +539,14 @@ define(function (require, exports, module) { * Stop providing change notifications for the file or directory at the * given path, calling back asynchronously with a possibly null FileSystemError * string when the operation is complete. + * This function needs to mirror the signature of watchPath + * because of FileSystem.prototype._watchOrUnwatchEntry implementation. * * @param {string} path + * @param {Array} ignored * @param {function(?string)=} callback */ - function unwatchPath(path, callback) { + function unwatchPath(path, ignored, callback) { _nodeDomain.exec("unwatchPath", path) .then(callback, callback); } @@ -587,11 +583,11 @@ define(function (require, exports, module) { /** * Indicates whether or not recursive watching notifications are supported - * by the watchPath call. Currently, only Darwin supports recursive watching. + * by the watchPath call. * * @type {boolean} */ - exports.recursiveWatch = (appshell.platform === "mac" || appshell.platform === "win"); + exports.recursiveWatch = true; /** * Indicates whether or not the filesystem should expect and normalize UNC diff --git a/src/filesystem/impls/appshell/node/CSharpWatcher.js b/src/filesystem/impls/appshell/node/CSharpWatcher.js new file mode 100644 index 00000000000..45f4f356c03 --- /dev/null +++ b/src/filesystem/impls/appshell/node/CSharpWatcher.js @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013 - present Adobe Systems Incorporated. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/* + * Code for working with CodeHelper.exe was inspired by: + * https://github.com/Microsoft/vscode/blob/314e122b16c5c1ca0288c8006e9c9c3039a51cd7/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts + */ + +/*eslint-env node */ +/*jslint node: true */ + +"use strict"; + +var fs = require("fs"); +var fspath = require("path"); +var cp = require("child_process"); +var anymatch = require('anymatch'); +var FileWatcherManager = require("./FileWatcherManager"); + +function buildMatcher(ignored) { + // in case of a glob like **/.git we want also to ignore its contents **/.git/** + return anymatch(ignored.concat(ignored.map(function (glob) { + return glob + "/**"; + }))); +} + +function watchPath(path, ignored, _watcherMap) { + + var ignoreMatcher = buildMatcher(ignored); + var closing = false; + + function processLine(line) { + if (line === "") { + return; + } + + var parts = line.split("|"); + if (parts.length !== 2) { + console.warn("CSharpWatcher unexpected line: '" + line + "'"); + return; + } + + var type = parseInt(parts[0], 10); + // convert it back to unix path and clear trailing whitespace + var absolutePath = parts[1].replace(/\\/g, "/").replace(/\s+$/g, ""); + + // convert type to an event + var event; + switch (type) { + case 0: + event = "changed"; + break; + case 1: + event = "created"; + break; + case 2: + event = "deleted"; + break; + default: + console.warn("CSharpWatcher event type: " + type); + return; + } + + // make sure ignored events are not emitted + if (ignoreMatcher(absolutePath)) { + return; + } + + var parentDirPath = fspath.dirname(absolutePath) + "/"; + var entryName = fspath.basename(absolutePath); + + // we need stats object for changed event + if (event === "changed") { + fs.stat(absolutePath, function (err, nodeFsStats) { + if (err) { + console.warn("CSharpWatcher err getting stats: " + err.toString()); + } + FileWatcherManager.emitChange(event, parentDirPath, entryName, nodeFsStats); + }); + } else { + FileWatcherManager.emitChange(event, parentDirPath, entryName, null); + } + } + + function onError(err) { + console.warn("CSharpWatcher process error: " + err.toString()); + FileWatcherManager.unwatchPath(path); + } + + function onExit(code, signal) { + if (!closing || signal !== "SIGTERM") { + console.warn("CSharpWatcher terminated unexpectedly with code: " + code + ", signal: " + signal); + } + FileWatcherManager.unwatchPath(path); + } + + try { + + var args = [ + // fspath.resolve will normalize slashes to windows format + fspath.resolve(path) + ]; + var handle = cp.spawn(fspath.resolve(__dirname, "win32", "CodeHelper.exe"), args); + + // Events over stdout + handle.stdout.on("data", function (buffer) { + var lines = buffer.toString("utf8").split("\n"); + while (lines.length > 0) { + processLine(lines.shift()); + } + }); + + // Errors + handle.on("error", onError); + handle.stderr.on("data", onError); + + // Exit + handle.on("exit", onExit); + + // Add handler for closing to the _watcherMap + _watcherMap[path] = { + close: function () { + closing = true; + handle.kill(); + } + }; + + } catch (err) { + console.warn("Failed to watch file " + path + ": " + (err && err.message)); + } +} + +exports.watchPath = watchPath; diff --git a/src/filesystem/impls/appshell/node/ChokidarWatcher.js b/src/filesystem/impls/appshell/node/ChokidarWatcher.js new file mode 100644 index 00000000000..79a38ae7602 --- /dev/null +++ b/src/filesystem/impls/appshell/node/ChokidarWatcher.js @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 - present Adobe Systems Incorporated. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/*eslint-env node */ +/*jslint node: true */ + +"use strict"; + +var fspath = require("path"); +var chokidar = require("chokidar"); +var FileWatcherManager = require("./FileWatcherManager"); + +function watchPath(path, ignored, _watcherMap) { + try { + var watcher = chokidar.watch(path, { + persistent: true, + ignoreInitial: true, + ignorePermissionErrors: true, + followSymlinks: true, + ignored: ignored, + interval: 1000, // while not used in normal cases, if any error causes chokidar to fallback to polling, increase its intervals + binaryInterval: 1000 + }); + + watcher.on("all", function (type, filename, nodeFsStats) { + var event; + switch (type) { + case "change": + event = "changed"; + break; + case "add": + case "addDir": + event = "created"; + break; + case "unlink": + case "unlinkDir": + event = "deleted"; + break; + default: + event = null; + } + if (!event || !filename) { + return; + } + // make sure it's normalized + filename = filename.replace(/\\/g, "/"); + var parentDirPath = fspath.dirname(filename) + "/"; + var entryName = fspath.basename(filename); + FileWatcherManager.emitChange(event, parentDirPath, entryName, nodeFsStats); + }); + + _watcherMap[path] = watcher; + + watcher.on("error", function (err) { + console.error("Error watching file " + path + ": " + (err && err.message)); + FileWatcherManager.unwatchPath(path); + }); + } catch (err) { + console.warn("Failed to watch file " + path + ": " + (err && err.message)); + } +} + +exports.watchPath = watchPath; diff --git a/src/filesystem/impls/appshell/node/FileWatcherDomain.js b/src/filesystem/impls/appshell/node/FileWatcherDomain.js index 22ea1fc7622..dbdcaf0b618 100644 --- a/src/filesystem/impls/appshell/node/FileWatcherDomain.js +++ b/src/filesystem/impls/appshell/node/FileWatcherDomain.js @@ -21,148 +21,18 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, node: true, nomen: true, indent: 4, maxerr: 50 */ +/*eslint-env node */ +/*jslint node: true */ "use strict"; -var fspath = require("path"), - fs = require("fs"), - os = require("os"), - fsevents; - -/* - * NOTE: The fsevents package is a temporary solution for file-watching on darwin. - * Node's native fs.watch call would be preferable, but currently has a hard limit - * of 451 watched directories and fails silently after that! In the next stable - * version of Node (0.12), fs.watch on darwin will support a new "recursive" option - * that will allow us to only request a single watched path per directory structure. - * When that is stable, we should switch back to fs.watch for all platforms, and - * we should use the recursive option where available. As of January 2014, the - * current experimental Node branch (0.11) only supports the recursive option for - * darwin. - * - * In the meantime, the fsevents package makes direct use of the Mac OS fsevents - * API to provide file watching capabilities. Its behavior is also recursive - * (like fs.watch with the recursive option), but the events it emits are not - * exactly the same as those emitted by Node watchers. Consequently, we require, - * for now, dual implementations of the FileWatcher domain. - * - * ALSO NOTE: the fsevents package as installed by NPM is not suitable for - * distribution with Brackets! The problem is that the native code embedded in - * the fsevents module is compiled by default for x86-64, but the Brackets-node - * process is compiled for x86-32. Consequently, the fsevents module must be - * compiled manually, which is why it is checked into Brackets source control - * and not managed by NPM. Changing compilation from 64- to 32-bit just requires - * changing a couple of definitions in the .gyp file used to build fsevents. - */ -if (process.platform === "darwin") { - fsevents = require("fsevents"); -} else if (process.platform === "win32") { - var version = os.release(); - // XP will use node's built in file watcher module. - if (version && version.length > 0 && version[0] !== "5") { - fsevents = require("fsevents_win/fsevents_win"); - } -} - -var _domainManager, - _watcherMap = {}; - -/** - * @private - * Un-watch a file or directory. - * @param {string} path File or directory to unwatch. - */ -function _unwatchPath(path) { - var watcher = _watcherMap[path]; - - if (watcher) { - try { - if (fsevents) { - watcher.stop(); - } else { - watcher.close(); - } - } catch (err) { - console.warn("Failed to unwatch file " + path + ": " + (err && err.message)); - } finally { - delete _watcherMap[path]; - } - } -} - -/** - * Un-watch a file or directory. For directories, unwatch all descendants. - * @param {string} path File or directory to unwatch. - */ -function unwatchPath(path) { - Object.keys(_watcherMap).forEach(function (keyPath) { - if (keyPath.indexOf(path) === 0) { - _unwatchPath(keyPath); - } - }); -} - -/** - * Watch a file or directory. - * @param {string} path File or directory to watch. - */ -function watchPath(path) { - if (_watcherMap.hasOwnProperty(path)) { - return; - } - - try { - var watcher; - - if (fsevents) { - watcher = fsevents(path); - watcher.on("change", function (filename, info) { - var parent = filename && (fspath.dirname(filename) + "/"), - name = filename && fspath.basename(filename), - type; - - switch (info.event) { - case "modified": // triggered by file content changes - case "unknown": // triggered by metatdata-only changes - type = "change"; - break; - default: - type = "rename"; - } - - _domainManager.emitEvent("fileWatcher", "change", [parent, type, name]); - }); - } else { - watcher = fs.watch(path, {persistent: false}, function (event, filename) { - // File/directory changes are emitted as "change" events on the fileWatcher domain. - _domainManager.emitEvent("fileWatcher", "change", [path, event, filename]); - }); - } - - _watcherMap[path] = watcher; - - watcher.on("error", function (err) { - console.error("Error watching file " + path + ": " + (err && err.message)); - unwatchPath(path); - }); - } catch (err) { - console.warn("Failed to watch file " + path + ": " + (err && err.message)); - } -} - -/** - * Un-watch all files and directories. - */ -function unwatchAll() { - var path; - - for (path in _watcherMap) { - if (_watcherMap.hasOwnProperty(path)) { - unwatchPath(path); - } - } +var os = require("os"); +var watcherManager = require("./FileWatcherManager"); +var watcherImpl; +if (process.platform === "win32") { + watcherImpl = require("./CSharpWatcher"); +} else { + watcherImpl = require("./ChokidarWatcher"); } /** @@ -177,19 +47,23 @@ function init(domainManager) { domainManager.registerCommand( "fileWatcher", "watchPath", - watchPath, + watcherManager.watchPath, false, "Start watching a file or directory", [{ name: "path", type: "string", description: "absolute filesystem path of the file or directory to watch" + }, { + name: "ignored", + type: "array", + description: "list of path to ignore" }] ); domainManager.registerCommand( "fileWatcher", "unwatchPath", - unwatchPath, + watcherManager.unwatchPath, false, "Stop watching a single file or a directory and it's descendants", [{ @@ -201,7 +75,7 @@ function init(domainManager) { domainManager.registerCommand( "fileWatcher", "unwatchAll", - unwatchAll, + watcherManager.unwatchAll, false, "Stop watching all files and directories" ); @@ -209,13 +83,16 @@ function init(domainManager) { "fileWatcher", "change", [ - {name: "path", type: "string"}, {name: "event", type: "string"}, - {name: "filename", type: "string"} + {name: "parentDirPath", type: "string"}, + {name: "entryName", type: "string"}, + {name: "statsObj", type: "object"} ] ); - _domainManager = domainManager; + watcherManager.setDomainManager(domainManager); + watcherManager.setWatcherImpl(watcherImpl); + } exports.init = init; diff --git a/src/filesystem/impls/appshell/node/FileWatcherManager.js b/src/filesystem/impls/appshell/node/FileWatcherManager.js new file mode 100644 index 00000000000..77eac41f25c --- /dev/null +++ b/src/filesystem/impls/appshell/node/FileWatcherManager.js @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013 - present Adobe Systems Incorporated. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/*eslint-env node */ +/*jslint node: true */ + +"use strict"; + +var _watcherMap = {}; +var _domainManager = null; +var _watcherImpl = null; + +function setDomainManager(dm) { + _domainManager = dm; +} + +function setWatcherImpl(impl) { + _watcherImpl = impl; +} + +/** + * Transform Node's native fs.stats to a format that can be sent through domain + * @param {stats} nodeFsStats Node's fs.stats result + * @return {object} Can be consumed by new FileSystemStats(object); in Brackets + */ +function normalizeStats(nodeFsStats) { + // current shell's stat method floors the mtime to the nearest thousand + // which causes problems when comparing timestamps + // so we have to round mtime to the nearest thousand too + var mtime = Math.floor(nodeFsStats.mtime.getTime() / 1000) * 1000; + + // from shell: If "filename" is a symlink, + // realPath should be the actual path to the linked object + // not implemented in shell yet + return { + isFile: nodeFsStats.isFile(), + isDirectory: nodeFsStats.isDirectory(), + mtime: mtime, + size: nodeFsStats.size, + realPath: null, + hash: mtime + }; +} + +/** + * Un-watch a file or directory. + * @private + * @param {string} path File or directory to unwatch. + */ +function _unwatchPath(path) { + var watcher = _watcherMap[path]; + + if (watcher) { + try { + watcher.close(); + } catch (err) { + console.warn("Failed to unwatch file " + path + ": " + (err && err.message)); + } finally { + delete _watcherMap[path]; + } + } +} + +/** + * Un-watch a file or directory. For directories, unwatch all descendants. + * @param {string} path File or directory to unwatch. + */ +function unwatchPath(path) { + Object.keys(_watcherMap).forEach(function (keyPath) { + if (keyPath.indexOf(path) === 0) { + _unwatchPath(keyPath); + } + }); +} + +/** + * Watch a file or directory. + * @param {string} path File or directory to watch. + * @param {Array} ignored List of entries to ignore during watching. + */ +function watchPath(path, ignored) { + if (_watcherMap.hasOwnProperty(path)) { + return; + } + return _watcherImpl.watchPath(path, ignored, _watcherMap, _domainManager); +} + +/** + * Un-watch all files and directories. + */ +function unwatchAll() { + var path; + + for (path in _watcherMap) { + if (_watcherMap.hasOwnProperty(path)) { + unwatchPath(path); + } + } +} + +function emitChange(event, parentDirPath, entryName, nodeFsStats) { + // make sure stats are normalized for domain transfer + var statsObj = nodeFsStats ? normalizeStats(nodeFsStats) : null; + _domainManager.emitEvent("fileWatcher", "change", [event, parentDirPath, entryName, statsObj]); +} + +exports.setDomainManager = setDomainManager; +exports.setWatcherImpl = setWatcherImpl; +exports.unwatchPath = unwatchPath; +exports.watchPath = watchPath; +exports.unwatchAll = unwatchAll; +exports.emitChange = emitChange; diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/CHANGELOG.md b/src/filesystem/impls/appshell/node/node_modules/fsevents/CHANGELOG.md deleted file mode 100644 index 6c4d8e4e09b..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/CHANGELOG.md +++ /dev/null @@ -1,10 +0,0 @@ -# Native Access to Mac OS-X FSEvents - Change-Log - -## Version 0.0.1 - - * Basic functionality - -## Version 0.1.2 - - * Finally made the Jump to node 0.8+ with this module. - * Much more Event-Details diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/Readme.md b/src/filesystem/impls/appshell/node/node_modules/fsevents/Readme.md deleted file mode 100644 index fefaa55792e..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/Readme.md +++ /dev/null @@ -1,72 +0,0 @@ -# FSEvents [![NPM](https://nodei.co/npm/fsevents.png)](https://nodei.co/npm/fsevents/) -## Native Access to Mac OS-X FSEvents - - * [Node.js](http://nodejs.org/) - * [Github repo](https://github.com/phidelta/NodeJS-FSEvents.git) - * [Module Site](https://github.com/phidelta/NodeJS-FSEvents) - * [NPM Page](https://npmjs.org/package/fsevents) - -## Installation - - $ npm install -g node-gyp - $ git clone https://github.com/phidelta/NodeJS-FSEvents.git fsevents - $ cd fsevents - $ node-gyp configure build - -OR SIMPLY - - $ npm install fsevents - -## Usage - - var fsevents = require('fsevents'); - var watcher = fsevents(__dirname); - watcher.on('fsevent', function(path, flags, id) { }); // RAW Event as emitted by OS-X - watcher.on('change', function(path, info) {}); // Common Event for all changes - -### Events - - * *fsevent* - RAW Event as emitted by OS-X - * *change* - Common Event for all changes - * *created* - A File-System-Item has been created - * *deleted* - A File-System-Item has been deleted - * *modified* - A File-System-Item has been modified - * *moved-out* - A File-System-Item has been moved away from this location - * *moved-in* - A File-System-Item has been moved into this location - -All events except *fsevent* take an *info* object as the second parameter of the callback. The structure of this object is: - - { - "event": "", - "id": , - "path": "", - "type": "", - "changes": { - "inode": true, // Has the iNode Meta-Information changed - "finder": false, // Has the Finder Meta-Data changed - "access": false, // Have the access permissions changed - "xattrs": false // Have the xAttributes changed - } - } - -## MIT License - -Copyright (C) 2010-2013 Philipp Dunkel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/binding.gyp b/src/filesystem/impls/appshell/node/node_modules/fsevents/binding.gyp deleted file mode 100644 index d0349fa8e3f..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'fswatch', - 'sources': [ 'nodefsevents.cc' ], - } - ] -} \ No newline at end of file diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Makefile b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Makefile deleted file mode 100644 index 250273e5ebf..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Makefile +++ /dev/null @@ -1,350 +0,0 @@ -# We borrow heavily from the kernel build setup, though we are simpler since -# we don't have Kconfig tweaking settings on us. - -# The implicit make rules have it looking for RCS files, among other things. -# We instead explicitly write all the rules we care about. -# It's even quicker (saves ~200ms) to pass -r on the command line. -MAKEFLAGS=-r - -# The source directory tree. -srcdir := .. -abs_srcdir := $(abspath $(srcdir)) - -# The name of the builddir. -builddir_name ?= . - -# The V=1 flag on command line makes us verbosely print command lines. -ifdef V - quiet= -else - quiet=quiet_ -endif - -# Specify BUILDTYPE=Release on the command line for a release build. -BUILDTYPE ?= Release - -# Directory all our build output goes into. -# Note that this must be two directories beneath src/ for unit tests to pass, -# as they reach into the src/ directory for data with relative paths. -builddir ?= $(builddir_name)/$(BUILDTYPE) -abs_builddir := $(abspath $(builddir)) -depsdir := $(builddir)/.deps - -# Object output directory. -obj := $(builddir)/obj -abs_obj := $(abspath $(obj)) - -# We build up a list of every single one of the targets so we can slurp in the -# generated dependency rule Makefiles in one pass. -all_deps := - - - -CC.target ?= $(CC) -CFLAGS.target ?= $(CFLAGS) -CXX.target ?= $(CXX) -CXXFLAGS.target ?= $(CXXFLAGS) -LINK.target ?= $(LINK) -LDFLAGS.target ?= $(LDFLAGS) -AR.target ?= $(AR) - -# C++ apps need to be linked with g++. -# -# Note: flock is used to seralize linking. Linking is a memory-intensive -# process so running parallel links can often lead to thrashing. To disable -# the serialization, override LINK via an envrionment variable as follows: -# -# export LINK=g++ -# -# This will allow make to invoke N linker processes as specified in -jN. -LINK ?= ./gyp-mac-tool flock $(builddir)/linker.lock $(CXX.target) - -# TODO(evan): move all cross-compilation logic to gyp-time so we don't need -# to replicate this environment fallback in make as well. -CC.host ?= gcc -CFLAGS.host ?= -CXX.host ?= g++ -CXXFLAGS.host ?= -LINK.host ?= $(CXX.host) -LDFLAGS.host ?= -AR.host ?= ar - -# Define a dir function that can handle spaces. -# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions -# "leading spaces cannot appear in the text of the first argument as written. -# These characters can be put into the argument value by variable substitution." -empty := -space := $(empty) $(empty) - -# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces -replace_spaces = $(subst $(space),?,$1) -unreplace_spaces = $(subst ?,$(space),$1) -dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) - -# Flags to make gcc output dependency info. Note that you need to be -# careful here to use the flags that ccache and distcc can understand. -# We write to a dep file on the side first and then rename at the end -# so we can't end up with a broken dep file. -depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw - -# We have to fixup the deps output in a few ways. -# (1) the file output should mention the proper .o file. -# ccache or distcc lose the path to the target, so we convert a rule of -# the form: -# foobar.o: DEP1 DEP2 -# into -# path/to/foobar.o: DEP1 DEP2 -# (2) we want missing files not to cause us to fail to build. -# We want to rewrite -# foobar.o: DEP1 DEP2 \ -# DEP3 -# to -# DEP1: -# DEP2: -# DEP3: -# so if the files are missing, they're just considered phony rules. -# We have to do some pretty insane escaping to get those backslashes -# and dollar signs past make, the shell, and sed at the same time. -# Doesn't work with spaces, but that's fine: .d files have spaces in -# their names replaced with other characters. -define fixup_dep -# The depfile may not exist if the input file didn't have any #includes. -touch $(depfile).raw -# Fixup path as in (1). -sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) -# Add extra rules as in (2). -# We remove slashes and replace spaces with new lines; -# remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ - grep -v '^$$' |\ - sed -e 1d -e 's|$$|:|' \ - >> $(depfile) -rm $(depfile).raw -endef - -# Command definitions: -# - cmd_foo is the actual command to run; -# - quiet_cmd_foo is the brief-output summary of the command. - -quiet_cmd_cc = CC($(TOOLSET)) $@ -cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_cxx = CXX($(TOOLSET)) $@ -cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_objc = CXX($(TOOLSET)) $@ -cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< - -quiet_cmd_objcxx = CXX($(TOOLSET)) $@ -cmd_objcxx = $(CXX.$(TOOLSET)) $(GYP_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< - -# Commands for precompiled header files. -quiet_cmd_pch_c = CXX($(TOOLSET)) $@ -cmd_pch_c = $(CC.$(TOOLSET)) $(GYP_PCH_CFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< -quiet_cmd_pch_cc = CXX($(TOOLSET)) $@ -cmd_pch_cc = $(CC.$(TOOLSET)) $(GYP_PCH_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< -quiet_cmd_pch_m = CXX($(TOOLSET)) $@ -cmd_pch_m = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< -quiet_cmd_pch_mm = CXX($(TOOLSET)) $@ -cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< - -# gyp-mac-tool is written next to the root Makefile by gyp. -# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd -# already. -quiet_cmd_mac_tool = MACTOOL $(4) $< -cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@" - -quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@ -cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4) - -quiet_cmd_infoplist = INFOPLIST $@ -cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@" - -quiet_cmd_touch = TOUCH $@ -cmd_touch = touch $@ - -quiet_cmd_copy = COPY $@ -# send stderr to /dev/null to ignore messages when linking directories. -cmd_copy = rm -rf "$@" && cp -af "$<" "$@" - -quiet_cmd_alink = LIBTOOL-STATIC $@ -cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^) - -quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) - -quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) - -quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) -bundle $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) - - -# Define an escape_quotes function to escape single quotes. -# This allows us to handle quotes properly as long as we always use -# use single quotes and escape_quotes. -escape_quotes = $(subst ','\'',$(1)) -# This comment is here just to include a ' to unconfuse syntax highlighting. -# Define an escape_vars function to escape '$' variable syntax. -# This allows us to read/write command lines with shell variables (e.g. -# $LD_LIBRARY_PATH), without triggering make substitution. -escape_vars = $(subst $$,$$$$,$(1)) -# Helper that expands to a shell command to echo a string exactly as it is in -# make. This uses printf instead of echo because printf's behaviour with respect -# to escape sequences is more portable than echo's across different shells -# (e.g., dash, bash). -exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' - -# Helper to compare the command we're about to run against the command -# we logged the last time we ran the command. Produces an empty -# string (false) when the commands match. -# Tricky point: Make has no string-equality test function. -# The kernel uses the following, but it seems like it would have false -# positives, where one string reordered its arguments. -# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ -# $(filter-out $(cmd_$@), $(cmd_$(1)))) -# We instead substitute each for the empty string into the other, and -# say they're equal if both substitutions produce the empty string. -# .d files contain ? instead of spaces, take that into account. -command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ - $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) - -# Helper that is non-empty when a prerequisite changes. -# Normally make does this implicitly, but we force rules to always run -# so we can check their command lines. -# $? -- new prerequisites -# $| -- order-only dependencies -prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) - -# Helper that executes all postbuilds until one fails. -define do_postbuilds - @E=0;\ - for p in $(POSTBUILDS); do\ - eval $$p;\ - E=$$?;\ - if [ $$E -ne 0 ]; then\ - break;\ - fi;\ - done;\ - if [ $$E -ne 0 ]; then\ - rm -rf "$@";\ - exit $$E;\ - fi -endef - -# do_cmd: run a command via the above cmd_foo names, if necessary. -# Should always run for a given target to handle command-line changes. -# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. -# Third argument, if non-zero, makes it do POSTBUILDS processing. -# Note: We intentionally do NOT call dirx for depfile, since it contains ? for -# spaces already and dirx strips the ? characters. -define do_cmd -$(if $(or $(command_changed),$(prereq_changed)), - @$(call exact_echo, $($(quiet)cmd_$(1))) - @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" - $(if $(findstring flock,$(word 2,$(cmd_$1))), - @$(cmd_$(1)) - @echo " $(quiet_cmd_$(1)): Finished", - @$(cmd_$(1)) - ) - @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) - @$(if $(2),$(fixup_dep)) - $(if $(and $(3), $(POSTBUILDS)), - $(call do_postbuilds) - ) -) -endef - -# Declare the "all" target first so it is the default, -# even though we don't have the deps yet. -.PHONY: all -all: - -# make looks for ways to re-generate included makefiles, but in our case, we -# don't have a direct way. Explicitly telling make that it has nothing to do -# for them makes it go faster. -%.d: ; - -# Use FORCE_DO_CMD to force a target to run. Should be coupled with -# do_cmd. -.PHONY: FORCE_DO_CMD -FORCE_DO_CMD: - -TOOLSET := target -# Suffix rules, putting all outputs into $(obj). -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.m FORCE_DO_CMD - @$(call do_cmd,objc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.mm FORCE_DO_CMD - @$(call do_cmd,objcxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -# Try building from generated source, too. -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.m FORCE_DO_CMD - @$(call do_cmd,objc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.mm FORCE_DO_CMD - @$(call do_cmd,objcxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.m FORCE_DO_CMD - @$(call do_cmd,objc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.mm FORCE_DO_CMD - @$(call do_cmd,objcxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - - -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,fswatch.target.mk)))),) - include fswatch.target.mk -endif - -quiet_cmd_regen_makefile = ACTION Regenerating $@ -cmd_regen_makefile = cd $(srcdir); /usr/local/lib/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/Users/wehrman/Source/edge-code/src/filesystem/impls/appshell/node/node_modules/fsevents/build/config.gypi -I/usr/local/lib/node_modules/node-gyp/addon.gypi -I/Users/wehrman/.node-gyp/0.10.22/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/wehrman/.node-gyp/0.10.22" "-Dmodule_root_dir=/Users/wehrman/Source/edge-code/src/filesystem/impls/appshell/node/node_modules/fsevents" binding.gyp -Makefile: $(srcdir)/../../../../../../../../../../../usr/local/lib/node_modules/node-gyp/addon.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../.node-gyp/0.10.22/common.gypi - $(call do_cmd,regen_makefile) - -# "all" is a concatenation of the "all" targets from all the included -# sub-makefiles. This is just here to clarify. -all: - -# Add in dependency-tracking rules. $(all_deps) is the list of every single -# target in our tree. Only consider the ones with .d (dependency) info: -d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) -ifneq ($(d_files),) - include $(d_files) -endif diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Makefile.d b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Makefile.d deleted file mode 100644 index 362a9358a2f..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Makefile.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Makefile := cd ..; /usr/local/lib/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/Users/wehrman/Source/edge-code/src/filesystem/impls/appshell/node/node_modules/fsevents/build/config.gypi -I/usr/local/lib/node_modules/node-gyp/addon.gypi -I/Users/wehrman/.node-gyp/0.10.22/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/wehrman/.node-gyp/0.10.22" "-Dmodule_root_dir=/Users/wehrman/Source/edge-code/src/filesystem/impls/appshell/node/node_modules/fsevents" binding.gyp diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Release/fswatch.node.d b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Release/fswatch.node.d deleted file mode 100644 index cae48227a94..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Release/fswatch.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/fswatch.node := ./gyp-mac-tool flock ./Release/linker.lock c++ -bundle -Wl,-search_paths_first -mmacosx-version-min=10.5 -arch i386 -L./Release -o Release/fswatch.node Release/obj.target/fswatch/nodefsevents.o -undefined dynamic_lookup diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Release/obj.target/fswatch/nodefsevents.o.d b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Release/obj.target/fswatch/nodefsevents.o.d deleted file mode 100644 index 8621681fbc2..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/.deps/Release/obj.target/fswatch/nodefsevents.o.d +++ /dev/null @@ -1,19 +0,0 @@ -cmd_Release/obj.target/fswatch/nodefsevents.o := c++ '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/wehrman/.node-gyp/0.10.22/src -I/Users/wehrman/.node-gyp/0.10.22/deps/uv/include -I/Users/wehrman/.node-gyp/0.10.22/deps/v8/include -Os -gdwarf-2 -mmacosx-version-min=10.5 -arch i386 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/fswatch/nodefsevents.o.d.raw -c -o Release/obj.target/fswatch/nodefsevents.o ../nodefsevents.cc -Release/obj.target/fswatch/nodefsevents.o: ../nodefsevents.cc \ - /Users/wehrman/.node-gyp/0.10.22/src/node.h \ - /Users/wehrman/.node-gyp/0.10.22/deps/uv/include/uv.h \ - /Users/wehrman/.node-gyp/0.10.22/deps/uv/include/uv-private/uv-unix.h \ - /Users/wehrman/.node-gyp/0.10.22/deps/uv/include/uv-private/ngx-queue.h \ - /Users/wehrman/.node-gyp/0.10.22/deps/uv/include/uv-private/uv-darwin.h \ - /Users/wehrman/.node-gyp/0.10.22/deps/v8/include/v8.h \ - /Users/wehrman/.node-gyp/0.10.22/deps/v8/include/v8stdint.h \ - /Users/wehrman/.node-gyp/0.10.22/src/node_object_wrap.h -../nodefsevents.cc: -/Users/wehrman/.node-gyp/0.10.22/src/node.h: -/Users/wehrman/.node-gyp/0.10.22/deps/uv/include/uv.h: -/Users/wehrman/.node-gyp/0.10.22/deps/uv/include/uv-private/uv-unix.h: -/Users/wehrman/.node-gyp/0.10.22/deps/uv/include/uv-private/ngx-queue.h: -/Users/wehrman/.node-gyp/0.10.22/deps/uv/include/uv-private/uv-darwin.h: -/Users/wehrman/.node-gyp/0.10.22/deps/v8/include/v8.h: -/Users/wehrman/.node-gyp/0.10.22/deps/v8/include/v8stdint.h: -/Users/wehrman/.node-gyp/0.10.22/src/node_object_wrap.h: diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/fswatch.node b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/fswatch.node deleted file mode 100755 index 5655c86170b..00000000000 Binary files a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/fswatch.node and /dev/null differ diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/linker.lock b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/linker.lock deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/obj.target/fswatch/nodefsevents.o b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/obj.target/fswatch/nodefsevents.o deleted file mode 100644 index 7594ba71428..00000000000 Binary files a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/Release/obj.target/fswatch/nodefsevents.o and /dev/null differ diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/binding.Makefile b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/binding.Makefile deleted file mode 100644 index c5c25f0ce89..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/binding.Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated by gyp; do not edit. - -export builddir_name ?= build/./. -.PHONY: all -all: - $(MAKE) fswatch diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/config.gypi b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/config.gypi deleted file mode 100644 index 248fe2841d6..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/config.gypi +++ /dev/null @@ -1,36 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 1, - "host_arch": "ia32", - "node_install_npm": "true", - "node_prefix": "/", - "node_shared_cares": "false", - "node_shared_http_parser": "false", - "node_shared_libuv": "false", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_tag": "", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "true", - "node_use_etw": "false", - "node_use_openssl": "true", - "node_use_perfctr": "false", - "python": "/usr/bin/python", - "target_arch": "ia32", - "v8_enable_gdbjit": 0, - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "false", - "nodedir": "/Users/wehrman/.node-gyp/0.10.22", - "copy_dev_lib": "true", - "standalone_static_library": 1 - } -} diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/fswatch.target.mk b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/fswatch.target.mk deleted file mode 100644 index c82d9376a02..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/fswatch.target.mk +++ /dev/null @@ -1,154 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := fswatch -DEFS_Debug := \ - '-D_DARWIN_USE_64_BIT_INODE=1' \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' \ - '-DDEBUG' \ - '-D_DEBUG' - -# Flags passed to all source files. -CFLAGS_Debug := \ - -O0 \ - -gdwarf-2 \ - -mmacosx-version-min=10.5 \ - -arch i386 \ - -Wall \ - -Wendif-labels \ - -W \ - -Wno-unused-parameter - -# Flags passed to only C files. -CFLAGS_C_Debug := \ - -fno-strict-aliasing - -# Flags passed to only C++ files. -CFLAGS_CC_Debug := \ - -fno-rtti \ - -fno-exceptions \ - -fno-threadsafe-statics \ - -fno-strict-aliasing - -# Flags passed to only ObjC files. -CFLAGS_OBJC_Debug := - -# Flags passed to only ObjC++ files. -CFLAGS_OBJCC_Debug := - -INCS_Debug := \ - -I/Users/wehrman/.node-gyp/0.10.22/src \ - -I/Users/wehrman/.node-gyp/0.10.22/deps/uv/include \ - -I/Users/wehrman/.node-gyp/0.10.22/deps/v8/include - -DEFS_Release := \ - '-D_DARWIN_USE_64_BIT_INODE=1' \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' - -# Flags passed to all source files. -CFLAGS_Release := \ - -Os \ - -gdwarf-2 \ - -mmacosx-version-min=10.5 \ - -arch i386 \ - -Wall \ - -Wendif-labels \ - -W \ - -Wno-unused-parameter - -# Flags passed to only C files. -CFLAGS_C_Release := \ - -fno-strict-aliasing - -# Flags passed to only C++ files. -CFLAGS_CC_Release := \ - -fno-rtti \ - -fno-exceptions \ - -fno-threadsafe-statics \ - -fno-strict-aliasing - -# Flags passed to only ObjC files. -CFLAGS_OBJC_Release := - -# Flags passed to only ObjC++ files. -CFLAGS_OBJCC_Release := - -INCS_Release := \ - -I/Users/wehrman/.node-gyp/0.10.22/src \ - -I/Users/wehrman/.node-gyp/0.10.22/deps/uv/include \ - -I/Users/wehrman/.node-gyp/0.10.22/deps/v8/include - -OBJS := \ - $(obj).target/$(TARGET)/nodefsevents.o - -# Add to the list of files we specially track dependencies for. -all_deps += $(OBJS) - -# CFLAGS et al overrides must be target-local. -# See "Target-specific Variable Values" in the GNU Make manual. -$(OBJS): TOOLSET := $(TOOLSET) -$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) -$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) -$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE)) -$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE)) - -# Suffix rules, putting all outputs into $(obj). - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# Try building from generated source, too. - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# End of this set of suffix rules -### Rules for final target. -LDFLAGS_Debug := \ - -Wl,-search_paths_first \ - -mmacosx-version-min=10.5 \ - -arch i386 \ - -L$(builddir) - -LIBTOOLFLAGS_Debug := \ - -Wl,-search_paths_first - -LDFLAGS_Release := \ - -Wl,-search_paths_first \ - -mmacosx-version-min=10.5 \ - -arch i386 \ - -L$(builddir) - -LIBTOOLFLAGS_Release := \ - -Wl,-search_paths_first - -LIBS := \ - -undefined dynamic_lookup - -$(builddir)/fswatch.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(builddir)/fswatch.node: LIBS := $(LIBS) -$(builddir)/fswatch.node: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE)) -$(builddir)/fswatch.node: TOOLSET := $(TOOLSET) -$(builddir)/fswatch.node: $(OBJS) FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(builddir)/fswatch.node -# Add target alias -.PHONY: fswatch -fswatch: $(builddir)/fswatch.node - -# Short alias for building this executable. -.PHONY: fswatch.node -fswatch.node: $(builddir)/fswatch.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/fswatch.node - diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/gyp-mac-tool b/src/filesystem/impls/appshell/node/node_modules/fsevents/build/gyp-mac-tool deleted file mode 100755 index 12edee94424..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/build/gyp-mac-tool +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env python -# Generated by gyp. Do not edit. -# Copyright (c) 2012 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Utility functions to perform Xcode-style build steps. - -These functions are executed via gyp-mac-tool when using the Makefile generator. -""" - -import fcntl -import json -import os -import plistlib -import re -import shutil -import string -import subprocess -import sys - - -def main(args): - executor = MacTool() - exit_code = executor.Dispatch(args) - if exit_code is not None: - sys.exit(exit_code) - - -class MacTool(object): - """This class performs all the Mac tooling steps. The methods can either be - executed directly, or dispatched from an argument list.""" - - def Dispatch(self, args): - """Dispatches a string command to a method.""" - if len(args) < 1: - raise Exception("Not enough arguments") - - method = "Exec%s" % self._CommandifyName(args[0]) - return getattr(self, method)(*args[1:]) - - def _CommandifyName(self, name_string): - """Transforms a tool name like copy-info-plist to CopyInfoPlist""" - return name_string.title().replace('-', '') - - def ExecCopyBundleResource(self, source, dest): - """Copies a resource file to the bundle/Resources directory, performing any - necessary compilation on each resource.""" - extension = os.path.splitext(source)[1].lower() - if os.path.isdir(source): - # Copy tree. - # TODO(thakis): This copies file attributes like mtime, while the - # single-file branch below doesn't. This should probably be changed to - # be consistent with the single-file branch. - if os.path.exists(dest): - shutil.rmtree(dest) - shutil.copytree(source, dest) - elif extension == '.xib': - return self._CopyXIBFile(source, dest) - elif extension == '.storyboard': - return self._CopyXIBFile(source, dest) - elif extension == '.strings': - self._CopyStringsFile(source, dest) - else: - shutil.copy(source, dest) - - def _CopyXIBFile(self, source, dest): - """Compiles a XIB file with ibtool into a binary plist in the bundle.""" - - # ibtool sometimes crashes with relative paths. See crbug.com/314728. - base = os.path.dirname(os.path.realpath(__file__)) - if os.path.relpath(source): - source = os.path.join(base, source) - if os.path.relpath(dest): - dest = os.path.join(base, dest) - - args = ['xcrun', 'ibtool', '--errors', '--warnings', '--notices', - '--output-format', 'human-readable-text', '--compile', dest, source] - ibtool_section_re = re.compile(r'/\*.*\*/') - ibtool_re = re.compile(r'.*note:.*is clipping its content') - ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE) - current_section_header = None - for line in ibtoolout.stdout: - if ibtool_section_re.match(line): - current_section_header = line - elif not ibtool_re.match(line): - if current_section_header: - sys.stdout.write(current_section_header) - current_section_header = None - sys.stdout.write(line) - return ibtoolout.returncode - - def _CopyStringsFile(self, source, dest): - """Copies a .strings file using iconv to reconvert the input into UTF-16.""" - input_code = self._DetectInputEncoding(source) or "UTF-8" - - # Xcode's CpyCopyStringsFile / builtin-copyStrings seems to call - # CFPropertyListCreateFromXMLData() behind the scenes; at least it prints - # CFPropertyListCreateFromXMLData(): Old-style plist parser: missing - # semicolon in dictionary. - # on invalid files. Do the same kind of validation. - import CoreFoundation - s = open(source, 'rb').read() - d = CoreFoundation.CFDataCreate(None, s, len(s)) - _, error = CoreFoundation.CFPropertyListCreateFromXMLData(None, d, 0, None) - if error: - return - - fp = open(dest, 'wb') - fp.write(s.decode(input_code).encode('UTF-16')) - fp.close() - - def _DetectInputEncoding(self, file_name): - """Reads the first few bytes from file_name and tries to guess the text - encoding. Returns None as a guess if it can't detect it.""" - fp = open(file_name, 'rb') - try: - header = fp.read(3) - except e: - fp.close() - return None - fp.close() - if header.startswith("\xFE\xFF"): - return "UTF-16" - elif header.startswith("\xFF\xFE"): - return "UTF-16" - elif header.startswith("\xEF\xBB\xBF"): - return "UTF-8" - else: - return None - - def ExecCopyInfoPlist(self, source, dest, *keys): - """Copies the |source| Info.plist to the destination directory |dest|.""" - # Read the source Info.plist into memory. - fd = open(source, 'r') - lines = fd.read() - fd.close() - - # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild). - plist = plistlib.readPlistFromString(lines) - if keys: - plist = dict(plist.items() + json.loads(keys[0]).items()) - lines = plistlib.writePlistToString(plist) - - # Go through all the environment variables and replace them as variables in - # the file. - IDENT_RE = re.compile('[/\s]') - for key in os.environ: - if key.startswith('_'): - continue - evar = '${%s}' % key - evalue = os.environ[key] - lines = string.replace(lines, evar, evalue) - - # Xcode supports various suffices on environment variables, which are - # all undocumented. :rfc1034identifier is used in the standard project - # template these days, and :identifier was used earlier. They are used to - # convert non-url characters into things that look like valid urls -- - # except that the replacement character for :identifier, '_' isn't valid - # in a URL either -- oops, hence :rfc1034identifier was born. - evar = '${%s:identifier}' % key - evalue = IDENT_RE.sub('_', os.environ[key]) - lines = string.replace(lines, evar, evalue) - - evar = '${%s:rfc1034identifier}' % key - evalue = IDENT_RE.sub('-', os.environ[key]) - lines = string.replace(lines, evar, evalue) - - # Remove any keys with values that haven't been replaced. - lines = lines.split('\n') - for i in range(len(lines)): - if lines[i].strip().startswith("${"): - lines[i] = None - lines[i - 1] = None - lines = '\n'.join(filter(lambda x: x is not None, lines)) - - # Write out the file with variables replaced. - fd = open(dest, 'w') - fd.write(lines) - fd.close() - - # Now write out PkgInfo file now that the Info.plist file has been - # "compiled". - self._WritePkgInfo(dest) - - def _WritePkgInfo(self, info_plist): - """This writes the PkgInfo file from the data stored in Info.plist.""" - plist = plistlib.readPlist(info_plist) - if not plist: - return - - # Only create PkgInfo for executable types. - package_type = plist['CFBundlePackageType'] - if package_type != 'APPL': - return - - # The format of PkgInfo is eight characters, representing the bundle type - # and bundle signature, each four characters. If that is missing, four - # '?' characters are used instead. - signature_code = plist.get('CFBundleSignature', '????') - if len(signature_code) != 4: # Wrong length resets everything, too. - signature_code = '?' * 4 - - dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo') - fp = open(dest, 'w') - fp.write('%s%s' % (package_type, signature_code)) - fp.close() - - def ExecFlock(self, lockfile, *cmd_list): - """Emulates the most basic behavior of Linux's flock(1).""" - # Rely on exception handling to report errors. - fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666) - fcntl.flock(fd, fcntl.LOCK_EX) - return subprocess.call(cmd_list) - - def ExecFilterLibtool(self, *cmd_list): - """Calls libtool and filters out '/path/to/libtool: file: foo.o has no - symbols'.""" - libtool_re = re.compile(r'^.*libtool: file: .* has no symbols$') - libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE) - _, err = libtoolout.communicate() - for line in err.splitlines(): - if not libtool_re.match(line): - print >>sys.stderr, line - return libtoolout.returncode - - def ExecPackageFramework(self, framework, version): - """Takes a path to Something.framework and the Current version of that and - sets up all the symlinks.""" - # Find the name of the binary based on the part before the ".framework". - binary = os.path.basename(framework).split('.')[0] - - CURRENT = 'Current' - RESOURCES = 'Resources' - VERSIONS = 'Versions' - - if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)): - # Binary-less frameworks don't seem to contain symlinks (see e.g. - # chromium's out/Debug/org.chromium.Chromium.manifest/ bundle). - return - - # Move into the framework directory to set the symlinks correctly. - pwd = os.getcwd() - os.chdir(framework) - - # Set up the Current version. - self._Relink(version, os.path.join(VERSIONS, CURRENT)) - - # Set up the root symlinks. - self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary) - self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES) - - # Back to where we were before! - os.chdir(pwd) - - def _Relink(self, dest, link): - """Creates a symlink to |dest| named |link|. If |link| already exists, - it is overwritten.""" - if os.path.lexists(link): - os.remove(link) - os.symlink(dest, link) - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/fsevents.js b/src/filesystem/impls/appshell/node/node_modules/fsevents/fsevents.js deleted file mode 100644 index 67dc5939901..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/fsevents.js +++ /dev/null @@ -1,69 +0,0 @@ -/* -** © 2013 by Philipp Dunkel . Licensed under MIT License. -*/ - -var util = require('util'); -var events = require('events'); -var binding; -//try { - binding = require('./build/Release/fswatch'); -//} catch(ex) { -// binding = require('./build/Debug/fswatch'); -//} - -var Fs = require('fs'); - -module.exports = function(path) { - var fsevents = new FSEvents(path); - fsevents.on('fsevent', function(path, flags, id) { - var info = { - event:'unknown', - id:id, - path: path, - type: fileType(flags), - changes: fileChanges(flags), - }; - if (FSEvents.kFSEventStreamEventFlagItemCreated & flags) { - info.event = 'created'; - } else if (FSEvents.kFSEventStreamEventFlagItemRemoved & flags) { - info.event = 'deleted'; - } else if (FSEvents.kFSEventStreamEventFlagItemRenamed & flags) { - info.event = 'moved'; - } else if (FSEvents.kFSEventStreamEventFlagItemModified & flags) { - info.event = 'modified'; - } - - if (info.event == 'moved') { - Fs.stat(info.path, function(err, stat) { - if (err || !stat) { - info.event = 'moved-out'; - } else { - info.event = 'moved-in'; - } - fsevents.emit('change', path, info); - fsevents.emit(info.event, path, info); - }); - } else { - fsevents.emit('change', path, info); - if (info.event !== 'unknown') fsevents.emit(info.event, path, info); - } - }); - return fsevents; -}; -var FSEvents = binding.FSEvents; -util.inherits(FSEvents, events.EventEmitter); - -function fileType(flags) { - if (FSEvents.kFSEventStreamEventFlagItemIsFile & flags) return 'file'; - if (FSEvents.kFSEventStreamEventFlagItemIsDir & flags) return 'directory'; - if (FSEvents.kFSEventStreamEventFlagItemIsSymlink & flags) return 'symlink'; -} - -function fileChanges(flags) { - var res = {}; - res.inode = !!(FSEvents.kFSEventStreamEventFlagItemInodeMetaMod & flags); - res.finder = !!(FSEvents.kFSEventStreamEventFlagItemFinderInfoMod & flags); - res.access = !!(FSEvents.kFSEventStreamEventFlagItemChangeOwner & flags); - res.xattrs = !!(FSEvents.kFSEventStreamEventFlagItemXattrMod & flags); - return res; -} diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/nodefsevents.cc b/src/filesystem/impls/appshell/node/node_modules/fsevents/nodefsevents.cc deleted file mode 100644 index cb167482125..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/nodefsevents.cc +++ /dev/null @@ -1,196 +0,0 @@ -/* -** © 2013 by Philipp Dunkel . Licensed under MIT License. -*/ - -#include -#include -#include - -#include -#include -#include - -#include - -#define MAXPATH 1024 - -typedef struct s_evt *p_evt; -struct s_evt { - FSEventStreamEventFlags flags; - FSEventStreamEventId evtid; - char path[MAXPATH + 1]; - p_evt next; -}; -static v8::Persistent constructor_template; -namespace node_fsevents { - using namespace v8; - using namespace node; - - static Persistent emit_sym; - static Persistent change_sym; - class NodeFSEvents : node::ObjectWrap { - public: - static void Initialize(v8::Handle target) { - HandleScope scope; - emit_sym = NODE_PSYMBOL("emit"); - change_sym = NODE_PSYMBOL("fsevent"); - Local t = FunctionTemplate::New(NodeFSEvents::New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("FSEvents")); - Local constructor = constructor_template->GetFunction(); - - constructor->Set(String::New("kFSEventStreamEventFlagNone"), Integer::New(0x00000000)); - constructor->Set(String::New("kFSEventStreamEventFlagMustScanSubDirs"), Integer::New(0x00000001)); - constructor->Set(String::New("kFSEventStreamEventFlagUserDropped"), Integer::New(0x00000002)); - constructor->Set(String::New("kFSEventStreamEventFlagKernelDropped"), Integer::New(0x00000004)); - constructor->Set(String::New("kFSEventStreamEventFlagEventIdsWrapped"), Integer::New(0x00000008)); - constructor->Set(String::New("kFSEventStreamEventFlagHistoryDone"), Integer::New(0x00000010)); - constructor->Set(String::New("kFSEventStreamEventFlagRootChanged"), Integer::New(0x00000020)); - constructor->Set(String::New("kFSEventStreamEventFlagMount"), Integer::New(0x00000040)); - constructor->Set(String::New("kFSEventStreamEventFlagUnmount"), Integer::New(0x00000080)); - constructor->Set(String::New("kFSEventStreamEventFlagItemCreated"), Integer::New(0x00000100)); - constructor->Set(String::New("kFSEventStreamEventFlagItemRemoved"), Integer::New(0x00000200)); - constructor->Set(String::New("kFSEventStreamEventFlagItemInodeMetaMod"), Integer::New(0x00000400)); - constructor->Set(String::New("kFSEventStreamEventFlagItemRenamed"), Integer::New(0x00000800)); - constructor->Set(String::New("kFSEventStreamEventFlagItemModified"), Integer::New(0x00001000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemFinderInfoMod"), Integer::New(0x00002000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemChangeOwner"), Integer::New(0x00004000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemXattrMod"), Integer::New(0x00008000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemIsFile"), Integer::New(0x00010000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemIsDir"), Integer::New(0x00020000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemIsSymlink"), Integer::New(0x00040000)); - - target->Set(String::NewSymbol("FSEvents"), constructor); - } - static v8::Handle Shutdown(const v8::Arguments& args) { - HandleScope scope; - NodeFSEvents *native = node::ObjectWrap::Unwrap(args.This()); - native->Shutdown(); - return Undefined(); - } - static v8::Handle New(const v8::Arguments& args) { - HandleScope scope; - - if (args.Length() != 1 || !args[0]->IsString()) { - return ThrowException(String::New("Bad arguments")); - } - - String::Utf8Value pathname(args[0]->ToString()); - - NodeFSEvents *nativeobj = new NodeFSEvents(*pathname); - nativeobj->Wrap(args.Holder()); - NODE_SET_METHOD(args.Holder(), "stop", NodeFSEvents::Shutdown); - return args.This(); - } - - - NodeFSEvents(const char *path) : ObjectWrap() { - running=1; - first = NULL; - last = NULL; - strncpy(pathname, path ? path : "/", MAXPATH); - pthread_mutex_init(&mutex, NULL); - uv_async_init(uv_default_loop(), &watcher, NodeFSEvents::Callback); - watcher.data = this; - pthread_create(&thread, NULL, &NodeFSEvents::Run, this); - } - - ~NodeFSEvents() { - this->Shutdown(); - } - void Shutdown() { - if (running) { - CFRunLoopStop(runLoop); - pthread_join(thread, NULL); - pthread_mutex_destroy(&mutex); - uv_close((uv_handle_t*) &watcher, NULL); - } - running = 0; - } - static void *Run(void *data) { - NodeFSEvents *This = (NodeFSEvents *)data; - CFStringRef dir_names[1]; - dir_names[0] = CFStringCreateWithCString(NULL, This->pathname, kCFStringEncodingUTF8); - CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&dir_names, 1, NULL); - FSEventStreamContext context = { 0, data, NULL, NULL, NULL }; - FSEventStreamRef stream = FSEventStreamCreate(NULL, &NodeFSEvents::Event, &context, pathsToWatch, kFSEventStreamEventIdSinceNow, (CFAbsoluteTime) 0.1, kFSEventStreamCreateFlagNone | kFSEventStreamCreateFlagWatchRoot | kFSEventStreamCreateFlagFileEvents); - This->runLoop = CFRunLoopGetCurrent(); - FSEventStreamScheduleWithRunLoop(stream, This->runLoop, kCFRunLoopDefaultMode); - FSEventStreamStart(stream); - CFRunLoopRun(); - FSEventStreamStop(stream); - FSEventStreamUnscheduleFromRunLoop(stream, This->runLoop, kCFRunLoopDefaultMode); - FSEventStreamInvalidate(stream); - FSEventStreamRelease(stream); - pthread_exit(NULL); - } - static void Event(ConstFSEventStreamRef streamRef, void *userData, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { - NodeFSEvents *This = static_cast(userData); - char **paths = static_cast(eventPaths); - size_t idx; - p_evt item; - pthread_mutex_lock(&(This->mutex)); - for (idx=0; idx < numEvents; idx++) { - item = (p_evt)malloc(sizeof(struct s_evt)); - if (!This->first) { - This->first = item; - This->last = item; - } else { - This->last->next = item; - This->last = item; - } - item->next = NULL; - strncpy(item->path, paths[idx],MAXPATH); - item->flags = eventFlags[idx]; - item->evtid = eventIds[idx]; - } - pthread_mutex_unlock(&(This->mutex)); - uv_async_send(&(This->watcher)); - } - static void Callback(uv_async_t *handle, int status) { - NodeFSEvents *This = static_cast(handle->data); - HandleScope scope; - TryCatch try_catch; - Local callback_v = This->handle_->Get(emit_sym); - Local callback = Local::Cast(callback_v); - p_evt item; - pthread_mutex_lock(&(This->mutex)); - - v8::Handle args[4]; - args[0] = change_sym; - This->Ref(); - item = This->first; - while (item) { - This->first = item->next; - if (!try_catch.HasCaught()) { - args[1] = v8::String::New(item->path ? item->path : ""); - args[2] = v8::Integer::New(item->flags); - args[3] = v8::Integer::New(item->evtid); - callback->Call(This->handle_, 4, args); - } - free(item); - item = This->first; - } - This->first = NULL; - This->last = NULL; - This->Ref(); - pthread_mutex_unlock(&(This->mutex)); - if (try_catch.HasCaught()) try_catch.ReThrow(); - } - - int running; - char pathname[MAXPATH + 1]; - CFRunLoopRef runLoop; - p_evt first; - p_evt last; - uv_async_t watcher; - pthread_t thread; - pthread_mutex_t mutex; - }; - extern "C" void init(v8::Handle target) { - node_fsevents::NodeFSEvents::Initialize(target); - } -} - -NODE_MODULE(fswatch, node_fsevents::init) diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents/package.json b/src/filesystem/impls/appshell/node/node_modules/fsevents/package.json deleted file mode 100644 index 1f7e4666a7e..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "fsevents", - "description": "Native Access to Mac OS-X FSEvents", - "homepage": "https://github.com/phidelta/NodeJS-FSEvents", - "version": "0.1.5", - "maintainers": [ - "Philipp Dunkel " - ], - "contributors": [ - "Philipp Dunkel " - ], - "bugs": { - "url": "https://github.com/phidelta/fsevents" - }, - "licenses": [ - { - "type": "MIT" - } - ], - "repository": { - "type": "git", - "url": "https://github.com/phidelta/fsevents.git" - }, - "main": "./fsevents.js", - "engines": {"node": ">=0.8"} -} diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/binding.gyp b/src/filesystem/impls/appshell/node/node_modules/fsevents_win/binding.gyp deleted file mode 100644 index 0e32c560323..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'fswatch_win', - 'sources': [ 'fsevents_win.cpp' ], - } - ] -} \ No newline at end of file diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/build/Release/fswatch_win.node b/src/filesystem/impls/appshell/node/node_modules/fsevents_win/build/Release/fswatch_win.node deleted file mode 100644 index 50f64f95c07..00000000000 Binary files a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/build/Release/fswatch_win.node and /dev/null differ diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.cpp b/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.cpp deleted file mode 100644 index a9e574e7de8..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.cpp +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2014 - present Adobe Systems Incorporated. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -/* This implementation based on code originally written by - * (c) 2013 by Philipp Dunkel . Licensed under MIT License - * https://github.com/phidelta/fsevents.git - */ - -#include "fsevents_win.h" -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#include - -#include - -#pragma comment(lib, "node") // link to node - -static Persistent constructor_template; -static Persistent emit_sym; -static Persistent change_sym; - -//***************************************************************************** - -// node addon required function -extern "C" void init(Handle target) { - NodeFSEvents::Initialize(target); -} - -NODE_MODULE(fswatch_win, init) - -//***************************************************************************** - -// wraps gaining access to a given mutex -class CMutexAccess -{ -public: - CMutexAccess(HANDLE hMutex) : m_hMutex(hMutex) - { - if (m_hMutex != NULL) - ::WaitForSingleObject(m_hMutex, INFINITE); - } - - ~CMutexAccess() - { - if (m_hMutex != NULL) - ::ReleaseMutex(m_hMutex); - } - -private: - HANDLE m_hMutex; -}; - -//***************************************************************************** - -// constructor -CFileNotifyChangeInfo::Entry::Entry(LPWSTR lpFilename, int iFilenameLen, DWORD dwAction) : - m_wstrFilename(lpFilename, iFilenameLen), - m_dwAction(dwAction) -{ -} - -// constructor -CFileNotifyChangeInfo::CFileNotifyChangeInfo() -{ - // mutex to synchronize access to the queue - m_hMutex = ::CreateMutexA(NULL, FALSE, NULL); -} - -// destructor -CFileNotifyChangeInfo::~CFileNotifyChangeInfo() -{ - // cleanup queue - { - CMutexAccess access(m_hMutex); - while (!m_Entries.empty()) - { - LPEntry lpEntry = m_Entries.front(); - m_Entries.pop(); - delete lpEntry; - } - } - - // cleanup - ::CloseHandle(m_hMutex); -} - -// pushes a new entry to the tail of the queue -void CFileNotifyChangeInfo::Push(LPEntry lpEntry) -{ - if (lpEntry != NULL) - { - CMutexAccess access(m_hMutex); - m_Entries.push(lpEntry); - } -} - -// retrieves the entry at the head of the queue -CFileNotifyChangeInfo::LPEntry CFileNotifyChangeInfo::Peek() -{ - LPEntry lpEntry = NULL; - - CMutexAccess access(m_hMutex); - if (!m_Entries.empty()) - lpEntry = m_Entries.front(); - - return lpEntry; -} - -// pops the entry off the head of the queue -void CFileNotifyChangeInfo::Pop() -{ - CMutexAccess access(m_hMutex); - if (!m_Entries.empty()) - m_Entries.pop(); -} - - -//***************************************************************************** - -// constructor -NodeFSEvents::NodeFSEvents(const char *lpszPath) : ObjectWrap(), - m_pChangeInfo(NULL), - m_lpBuffer(NULL), - m_hAsyncDir(NULL), - m_hIoCPort(NULL), - m_hThread(NULL), - m_lpThreadInfo(NULL) -{ - Startup(lpszPath); -} - -// destructor -NodeFSEvents::~NodeFSEvents() -{ - Shutdown(); -} - -// initialize a JS wrapper around this object -void NodeFSEvents::Initialize(Handle target) -{ - HandleScope scope; - emit_sym = NODE_PSYMBOL("emit"); - change_sym = NODE_PSYMBOL("fsevent"); - Local t = FunctionTemplate::New(NodeFSEvents::New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("FSEvents")); - Local constructor = constructor_template->GetFunction(); - - constructor->Set(String::New("kFSEventStreamEventFlagNone"), Integer::New(0x00000000)); - constructor->Set(String::New("kFSEventStreamEventFlagMustScanSubDirs"), Integer::New(0x00000001)); - constructor->Set(String::New("kFSEventStreamEventFlagUserDropped"), Integer::New(0x00000002)); - constructor->Set(String::New("kFSEventStreamEventFlagKernelDropped"), Integer::New(0x00000004)); - constructor->Set(String::New("kFSEventStreamEventFlagEventIdsWrapped"), Integer::New(0x00000008)); - constructor->Set(String::New("kFSEventStreamEventFlagHistoryDone"), Integer::New(0x00000010)); - constructor->Set(String::New("kFSEventStreamEventFlagRootChanged"), Integer::New(0x00000020)); - constructor->Set(String::New("kFSEventStreamEventFlagMount"), Integer::New(0x00000040)); - constructor->Set(String::New("kFSEventStreamEventFlagUnmount"), Integer::New(0x00000080)); - constructor->Set(String::New("kFSEventStreamEventFlagItemCreated"), Integer::New(0x00000100)); - constructor->Set(String::New("kFSEventStreamEventFlagItemRemoved"), Integer::New(0x00000200)); - constructor->Set(String::New("kFSEventStreamEventFlagItemInodeMetaMod"), Integer::New(0x00000400)); - constructor->Set(String::New("kFSEventStreamEventFlagItemRenamed"), Integer::New(0x00000800)); - constructor->Set(String::New("kFSEventStreamEventFlagItemModified"), Integer::New(0x00001000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemFinderInfoMod"), Integer::New(0x00002000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemChangeOwner"), Integer::New(0x00004000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemXattrMod"), Integer::New(0x00008000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemIsFile"), Integer::New(0x00010000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemIsDir"), Integer::New(0x00020000)); - constructor->Set(String::New("kFSEventStreamEventFlagItemIsSymlink"), Integer::New(0x00040000)); - - target->Set(String::NewSymbol("FSEvents"), constructor); -} - -// unwrap the JS wrapper -Handle NodeFSEvents::Shutdown(const Arguments& args) -{ - HandleScope scope; - NodeFSEvents *native = node::ObjectWrap::Unwrap(args.This()); - native->Shutdown(); - return Undefined(); -} - -// API to allocate a new object from JS -Handle NodeFSEvents::New(const Arguments& args) -{ - HandleScope scope; - - if (args.Length() != 1 || !args[0]->IsString()) { - return ThrowException(String::New("Bad arguments")); - } - - String::Utf8Value szPathName(args[0]->ToString()); - - NodeFSEvents *nativeobj = new NodeFSEvents(*szPathName); - nativeobj->Wrap(args.Holder()); - NODE_SET_METHOD(args.Holder(), "stop", NodeFSEvents::Shutdown); - return args.This(); -} - -// starts up the file watching thread -void NodeFSEvents::Startup(const char *lpszPath) -{ - if (m_hThread != NULL) // check if already started - return; - - BOOL bResult = FALSE; - - // validate path input - int iLen = ::MultiByteToWideChar(CP_UTF8, 0, lpszPath, -1, NULL, 0); - m_wstrRootPath.resize(iLen + 1); - ::MultiByteToWideChar(CP_UTF8, 0, lpszPath, -1, &m_wstrRootPath[0], iLen + 1); - - // allocate buffer to hold asynchronous watch info - m_pChangeInfo = new CFileNotifyChangeInfo(); - if (m_pChangeInfo != NULL) - { - // allocate buffer to hold directory change information - m_lpBuffer = (PFILE_NOTIFY_INFORMATION)malloc(READ_DIRECTORY_CHANGES_BUFSIZE); - if (m_lpBuffer != NULL) - { - // open the directory to watch - m_hAsyncDir = CreateFileW( - m_wstrRootPath.c_str(), - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, - NULL); - if (m_hAsyncDir != INVALID_HANDLE_VALUE) - { - // set up communication channels between watcher and our thread - m_hIoCPort = ::CreateIoCompletionPort( - m_hAsyncDir, - m_hIoCPort, - (ULONG_PTR)m_pChangeInfo, - 0); - if (m_hIoCPort != NULL) - { - memset(&m_Overlapped, 0, sizeof(m_Overlapped)); - - // set up communication between our file watching thread and a callback to post changes back to JS - uv_async_init(uv_default_loop(), &m_uvaWatcher, NodeFSEvents::Callback); - m_uvaWatcher.data = (LPVOID)this; - - // collect info to be shared with the worker thread - m_lpThreadInfo = (LPTHREADINFO)malloc(sizeof(THREADINFO)); - if (m_lpThreadInfo != NULL) - { - m_lpThreadInfo->m_pChangeInfo = m_pChangeInfo; - m_lpThreadInfo->m_hAsyncDir = m_hAsyncDir; - m_lpThreadInfo->m_hIoCPort = m_hIoCPort; - m_lpThreadInfo->m_lpBuffer = m_lpBuffer; - m_lpThreadInfo->m_lpOverlapped = &m_Overlapped; - m_lpThreadInfo->m_lpuvaWatcher = &m_uvaWatcher; - m_lpThreadInfo->m_bShouldExit = FALSE; - - // start the thread - DWORD dwThreadId = 0; - m_hThread = ::CreateThread(NULL, 0, &NodeFSEvents::Run, (LPVOID)m_lpThreadInfo, 0, &dwThreadId); - - bResult = m_hThread != NULL; - } - } - } - } - } - - // if something failed, then shutdown and cleanup - if (!bResult) - Shutdown(); -} - -// cleanly shuts down the file watching thread -void NodeFSEvents::Shutdown() -{ - // shutdown the thread, if it's running - if (m_hThread != NULL) - { - m_lpThreadInfo->m_bShouldExit = TRUE; // tell the thread to quit - ::PostQueuedCompletionStatus(m_hIoCPort, 0, 0, NULL); // wake up threat - ::WaitForSingleObject(m_hThread, INFINITE); // wait for the thread to quit - uv_close((uv_handle_t*) &m_uvaWatcher, NULL); - m_hThread = NULL; - } - - // cleanup - if (m_lpThreadInfo != NULL) - { - free(m_lpThreadInfo); - m_lpThreadInfo = NULL; - } - if (m_hIoCPort != NULL) - { - ::CloseHandle(m_hIoCPort); - m_hIoCPort = NULL; - } - if (m_hAsyncDir != NULL) - { - ::CloseHandle(m_hAsyncDir); - m_hAsyncDir = NULL; - } - if (m_lpBuffer != NULL) - { - ::free(m_lpBuffer); - m_lpBuffer = NULL; - } - if (m_pChangeInfo != NULL) - { - delete m_pChangeInfo; - m_pChangeInfo = NULL; - } -} - -// threadproc used to maintain the file watcher and any file changes it finds -DWORD WINAPI NodeFSEvents::Run(LPVOID lpData) -{ - LPTHREADINFO lpThreadInfo = (LPTHREADINFO)lpData; - if (lpThreadInfo != NULL) - { - // iterate watching for directory changes until we're signalled to stop - while (lpThreadInfo->m_bShouldExit == FALSE) - { - // set the watcher - DWORD dwBytesReturned = (DWORD)0; - if (!::ReadDirectoryChangesW(lpThreadInfo->m_hAsyncDir, lpThreadInfo->m_lpBuffer, READ_DIRECTORY_CHANGES_BUFSIZE, TRUE, - FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE - | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SECURITY, - &dwBytesReturned, lpThreadInfo->m_lpOverlapped, NULL)) - { - break; - } - // wait for a signal - DWORD dwNumBytes; - LPOVERLAPPED lpOverlapped = NULL; - ULONG_PTR lpCompletionKey = NULL; - ::GetQueuedCompletionStatus(lpThreadInfo->m_hIoCPort, &dwNumBytes, &lpCompletionKey, &lpOverlapped, INFINITE); - if (dwNumBytes > 0) - { - if (lpOverlapped == NULL) - { - // in case an unknown error occurred in the completion port, skip to the next change notification - continue; - } - else - { - // process the watched directory change - PFILE_NOTIFY_INFORMATION pfni = lpThreadInfo->m_lpBuffer; - while (pfni != NULL) - { - CFileNotifyChangeInfo::LPEntry lpEntry = new CFileNotifyChangeInfo::Entry( - pfni->FileName, - pfni->FileNameLength / sizeof(WCHAR), - pfni->Action); - if (lpEntry != NULL && (lpThreadInfo->m_pChangeInfo != NULL)) - { - lpThreadInfo->m_pChangeInfo->Push(lpEntry); - - // post a signal to send this back to JS - uv_async_send(lpThreadInfo->m_lpuvaWatcher); - } - - // process the next change - pfni = (pfni->NextEntryOffset > 0) ? (PFILE_NOTIFY_INFORMATION)(((BYTE*)pfni) + pfni->NextEntryOffset) : NULL; - } - } - } - } - } - - return TRUE; -} - -// callback signaled from file watching threadproc that allows us to asynchronously post changes back to JS -void NodeFSEvents::Callback(uv_async_t *handle, int status) -{ - NodeFSEvents *This = static_cast(handle->data); - if (This->m_pChangeInfo != NULL) - { - HandleScope scope; - - // initialize wrapper to call back into JS - Local callback_v = This->handle_->Get(emit_sym); - Local callback = Local::Cast(callback_v); - Handle args[3]; - args[0] = change_sym; - - // iterate thru each queued file watching entry - CFileNotifyChangeInfo::LPEntry lpEntry = NULL; - while ((lpEntry = This->m_pChangeInfo->Peek()) != NULL) - { - // concatenate the root search path and the file notification path - std::wstring wstrFullPath = This->m_wstrRootPath.c_str(); - wstrFullPath += lpEntry->m_wstrFilename; - - // normalize path separators from '\' to '/' - std::replace(wstrFullPath.begin(), wstrFullPath.end(), '\\', '/'); - - // convert the full pathname to utf8 - int iLen = ::WideCharToMultiByte(CP_UTF8, 0, wstrFullPath.c_str(), -1, NULL, 0, NULL, NULL); - std::string strFullPath(iLen + 1, 0x00); - ::WideCharToMultiByte(CP_UTF8, 0, wstrFullPath.c_str(), -1, &strFullPath[0], iLen + 1, NULL, NULL); - - // map the FILE_NOTIFY_INFORMATION 'Action' to a node fs-event.c 'enum uv_fs_event' type - int iAction; - switch(lpEntry->m_dwAction) - { - case FILE_ACTION_ADDED: - case FILE_ACTION_REMOVED: - case FILE_ACTION_RENAMED_OLD_NAME: - case FILE_ACTION_RENAMED_NEW_NAME: - iAction = UV_RENAME; - break; - case FILE_ACTION_MODIFIED: - default: - iAction = UV_CHANGE; - } - - // call back into JS with each change. - args[1] = String::New(strFullPath.c_str()); - args[2] = Integer::New(iAction); - callback->Call(This->handle_, 3, args); - - // discard the now-processed entry - This->m_pChangeInfo->Pop(); - delete lpEntry; - } - } -} \ No newline at end of file diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.h b/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.h deleted file mode 100644 index bc19e031a05..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2014 - present Adobe Systems Incorporated. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include -#include -#include - -#include -#include - -#define READ_DIRECTORY_CHANGES_BUFSIZE 8192 - -using namespace v8; - -// encapsulates changes reported by ReadDirectoryChangesW() -class CFileNotifyChangeInfo -{ -public: - // records a single change as reported by ReadDirectoryChanges() - struct Entry { - std::wstring m_wstrFilename; - DWORD m_dwAction; - - Entry(LPWSTR lpwszFilename, int iFilenameLen, DWORD dwAction); - }; - typedef Entry* LPEntry; - -public: - CFileNotifyChangeInfo(); - ~CFileNotifyChangeInfo(); - - // mutex-synchronized accessor methods - void Push(LPEntry lpEntry); // pushes a new entry to the tail of the queue - LPEntry Peek(); // retrieves the entry at the head of the queue - void Pop(); // pops the entry off the head of the queue - -protected: - std::queue m_Entries; // queue of ReadDirectoryChangesW() entries - HANDLE m_hMutex; // mutex synchronizing access to queue -}; - -// encapsulates data to be shared with the worker thread -struct THREADINFO -{ - CFileNotifyChangeInfo *m_pChangeInfo; // queue of file notification changes - PFILE_NOTIFY_INFORMATION m_lpBuffer; // buffer for watched file notification changes - HANDLE m_hAsyncDir; // handle to watched parent folder - HANDLE m_hIoCPort; // handle to I/O completion port - LPOVERLAPPED m_lpOverlapped; // handle to overlapped I/O - uv_async_t *m_lpuvaWatcher; // handle to uv watch - BOOL m_bShouldExit; // flag to control thread state -}; -typedef THREADINFO *LPTHREADINFO; - -// main node object -class NodeFSEvents : public node::ObjectWrap -{ -public: - NodeFSEvents(const char *lpszPath); - ~NodeFSEvents(); - - // JS wrapper methods - static void Initialize(Handle target); - static Handle Shutdown(const Arguments& args); - static Handle New(const Arguments& args); - -protected: - // file watching methods - void Startup(const char *lpszPath); - void Shutdown(); -public: - static DWORD WINAPI Run(LPVOID lpData); - static void Callback(uv_async_t *handle, int status); - -protected: - std::wstring m_wstrRootPath; // root path to watch - CFileNotifyChangeInfo *m_pChangeInfo; // queue of file notification changes - PFILE_NOTIFY_INFORMATION m_lpBuffer; // buffer for watched file notification changes - HANDLE m_hAsyncDir; // handle to watched parent folder - HANDLE m_hIoCPort; // handle to I/O completion port - OVERLAPPED m_Overlapped; // handle to overlapped I/O - uv_async_t m_uvaWatcher; // handle to uv watch - HANDLE m_hThread; // handle to watcher thread - LPTHREADINFO m_lpThreadInfo; // info to be shared with the worker thread -}; diff --git a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.js b/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.js deleted file mode 100644 index d6e010773f6..00000000000 --- a/src/filesystem/impls/appshell/node/node_modules/fsevents_win/fsevents_win.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2014 - present Adobe Systems Incorporated. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -/* This implementation based on code originally written by - * (c) 2013 by Philipp Dunkel . Licensed under MIT License - * https://github.com/phidelta/fsevents.git - */ - -var util = require('util'); -var events = require('events'); - -// link to native (C++) node_modules addon -var binding = require('./build/Release/fswatch_win'); - -module.exports = function(path) { - // create node object and kick-off file watcher thread on this path - var fsevents = new FSEvents(path); - - // process file change events emitted by node object - fsevents.on('fsevent', function(path, action) { - var info = { - event:'unknown', - path: path, - }; - - if (action === 1) { - info.event = 'rename'; - } else { - info.event = 'modified'; - } - - fsevents.emit('change', path, info); - }); - - return fsevents; -}; - -var FSEvents = binding.FSEvents; -util.inherits(FSEvents, events.EventEmitter); \ No newline at end of file diff --git a/src/filesystem/impls/appshell/node/win32/CodeHelper.exe b/src/filesystem/impls/appshell/node/win32/CodeHelper.exe new file mode 100644 index 00000000000..4d4b6737825 Binary files /dev/null and b/src/filesystem/impls/appshell/node/win32/CodeHelper.exe differ diff --git a/src/filesystem/impls/appshell/node/win32/CodeHelper.md b/src/filesystem/impls/appshell/node/win32/CodeHelper.md new file mode 100644 index 00000000000..81e43c0951d --- /dev/null +++ b/src/filesystem/impls/appshell/node/win32/CodeHelper.md @@ -0,0 +1,8 @@ +# Native File Watching for Windows using C# FileSystemWatcher + +- Repository: https://github.com/Microsoft/vscode-filewatcher-windows + +# Build + +- Build in "Release" config +- Copy CodeHelper.exe over into this folder \ No newline at end of file diff --git a/src/filesystem/impls/appshell/node/win32/LICENSE b/src/filesystem/impls/appshell/node/win32/LICENSE new file mode 100644 index 00000000000..2be9200f4d6 --- /dev/null +++ b/src/filesystem/impls/appshell/node/win32/LICENSE @@ -0,0 +1,18 @@ + +Copyright (c) Microsoft Corporation + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/help/HelpCommandHandlers.js b/src/help/HelpCommandHandlers.js index d8636548ddf..41302d76988 100644 --- a/src/help/HelpCommandHandlers.js +++ b/src/help/HelpCommandHandlers.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/language/CSSUtils.js b/src/language/CSSUtils.js index 3db26d62881..f2b842106c0 100644 --- a/src/language/CSSUtils.js +++ b/src/language/CSSUtils.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */ -/*global define, $ */ +/*jslint regexp: true */ /** * Set of utilities for simple parsing of CSS text. @@ -92,7 +90,7 @@ define(function (require, exports, module) { return null; } var state = ctx.token.state.localState || ctx.token.state; - if (!state.context && ctx.token.state.html.localState) { + if (!state.context && ctx.token.state.html && ctx.token.state.html.localState) { state = ctx.token.state.html.localState; } return state; diff --git a/src/language/CodeInspection.js b/src/language/CodeInspection.js index 53e8ccc7696..986d0230a4f 100644 --- a/src/language/CodeInspection.js +++ b/src/language/CodeInspection.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4 */ -/*global define, $, brackets */ - /** * Manages linters and other code inspections on a per-language basis. Provides a UI and status indicator for * the resulting errors/warnings. diff --git a/src/language/HTMLDOMDiff.js b/src/language/HTMLDOMDiff.js index fda196269a0..665c4920238 100644 --- a/src/language/HTMLDOMDiff.js +++ b/src/language/HTMLDOMDiff.js @@ -21,9 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ /*unittests: HTML Instrumentation*/ define(function (require, exports, module) { diff --git a/src/language/HTMLInstrumentation.js b/src/language/HTMLInstrumentation.js index cb20fe17dc3..f763ec83e63 100644 --- a/src/language/HTMLInstrumentation.js +++ b/src/language/HTMLInstrumentation.js @@ -21,9 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ /*unittests: HTML Instrumentation*/ /** @@ -145,21 +142,16 @@ define(function (require, exports, module) { } // The mark with the latest start is the innermost one. - match = marks[marks.length - 1]; + match = marks.pop(); if (preferParent) { // If the match is exactly at the edge of the range and preferParent is set, - // we want to pop upwards. - if (_posEq(match.range.from, pos) || _posEq(match.range.to, pos)) { - if (marks.length > 1) { - match = marks[marks.length - 2]; - } else { - // We must be outside the root, so there's no containing tag. - match = null; - } + // we want to pop upwards. If pos is exactly between two marks, we need to pop upwards twice. + while (match && (_posEq(match.range.from, pos) || _posEq(match.range.to, pos))) { + match = marks.pop(); } } - return match.mark; + return match && match.mark; } /** diff --git a/src/language/HTMLSimpleDOM.js b/src/language/HTMLSimpleDOM.js index a45916cafd3..304182a9b40 100644 --- a/src/language/HTMLSimpleDOM.js +++ b/src/language/HTMLSimpleDOM.js @@ -21,9 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ /*unittests: HTML Instrumentation*/ define(function (require, exports, module) { @@ -51,10 +48,14 @@ define(function (require, exports, module) { article : { p: true }, aside : { p: true }, blockquote : { p: true }, + colgroup: { caption: true }, + details : { p: true }, dir : { p: true }, div : { p: true }, dl : { p: true }, fieldset: { p: true }, + figcaption: { p: true }, + figure : { p: true }, footer : { p: true }, form : { p: true }, h1 : { p: true }, @@ -75,18 +76,49 @@ define(function (require, exports, module) { section : { p: true }, table : { p: true }, ul : { p: true }, - rt : { rp: true, rt: true }, - rp : { rp: true, rt: true }, + rb : { rb: true, rt: true, rtc: true, rp: true }, + rp : { rb: true, rt: true, rp: true }, + rt : { rb: true, rt: true, rp: true }, + rtc : { rb: true, rt: true, rtc: true, rp: true }, optgroup: { optgroup: true, option: true }, option : { option: true }, - tbody : { thead: true, tbody: true, tfoot: true }, - tfoot : { tbody: true }, - tr : { tr: true, th: true, td: true }, + tbody : { caption: true, colgroup: true, thead: true, tbody: true, tfoot: true, }, + tfoot : { caption: true, colgroup: true, thead: true, tbody: true }, + thead : { caption: true, colgroup: true }, + tr : { tr: true, th: true, td: true, caption: true }, th : { th: true, td: true }, - td : { thead: true, th: true, td: true }, - body : { head: true, link: true, script: true } + td : { th: true, td: true }, + body : { head: true } + }; + + /** + * A list of elements which are automatically closed when their parent is closed: + * http://www.w3.org/html/wg/drafts/html/master/syntax.html#optional-tags + */ + var optionalClose = { + html: true, + body: true, + li: true, + dd: true, + dt: true, // This is not actually correct, but showing a syntax error is not helpful + p: true, + rb: true, + rt: true, + rtc: true, + rp: true, + optgroup: true, + option: true, + colgroup: true, + caption: true, + tbody: true, + tfoot: true, + tr: true, + td: true, + th: true }; + // TODO: handle optional start tags + /** * A list of tags that are self-closing (do not contain other elements). * Mostly taken from http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements @@ -385,13 +417,6 @@ define(function (require, exports, module) { break; } } - if (strict && i !== stack.length - 1) { - // If we're in strict mode, treat unbalanced tags as invalid. - PerfUtils.finalizeMeasurement(timerBuildFull); - PerfUtils.addMeasurement(timerBuildPart); - this._logError(token); - return null; - } if (i >= 0) { do { // For all tags we're implicitly closing (before we hit the matching tag), we want the @@ -402,6 +427,13 @@ define(function (require, exports, module) { if (stack.length === i + 1) { closeTag(token.end + 1, _offsetPos(token.endPos, 1)); } else { + if (strict && !optionalClose.hasOwnProperty(stack[stack.length - 1].tag)) { + // If we're in strict mode, treat unbalanced tags as invalid. + PerfUtils.finalizeMeasurement(timerBuildFull); + PerfUtils.addMeasurement(timerBuildPart); + this._logError(token); + return null; + } closeTag(token.start - 2, _offsetPos(token.startPos, -2)); } } while (stack.length > i); @@ -450,24 +482,16 @@ define(function (require, exports, module) { lastIndex = token.end; } - // If we have any tags hanging open (e.g. html or body), fail the parse if we're in strict mode, + // If we have any tags hanging open, fail the parse if we're in strict mode, // otherwise close them at the end of the document. - if (stack.length) { - if (strict) { + while (stack.length) { + if (strict && !optionalClose.hasOwnProperty(stack[stack.length - 1].tag)) { PerfUtils.finalizeMeasurement(timerBuildFull); PerfUtils.addMeasurement(timerBuildPart); this._logError(token); return null; - } else { - // Manually compute the position of the end of the text (we can't rely on the - // tokenizer for this since it may not get to the very end) - // TODO: should probably make the tokenizer get to the end... - var lines = this.text.split("\n"), - lastPos = {line: lines.length - 1, ch: lines[lines.length - 1].length}; - while (stack.length) { - closeTag(this.text.length, lastPos); - } } + closeTag(this.text.length, this.t._indexPos); } var dom = lastClosedTag; diff --git a/src/language/HTMLTokenizer.js b/src/language/HTMLTokenizer.js index 017267d4e2e..51af03c05d4 100644 --- a/src/language/HTMLTokenizer.js +++ b/src/language/HTMLTokenizer.js @@ -24,8 +24,8 @@ // A simple HTML tokenizer, originally adapted from https://github.com/fb55/htmlparser2 // (MIT-licensed), but with significant customizations for use in HTML live development. -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, continue: true */ -/*global define */ +/*jslint continue: true */ + /*unittests: HTML Tokenizer*/ define(function (require, exports, module) { @@ -678,9 +678,14 @@ define(function (require, exports, module) { this._index++; } - if (this._index === this._buffer.length && this._state !== TEXT) { - // We hit EOF in the middle of processing something else. - this._emitSpecialToken("error"); + if (!this._token) { + if (this._state !== TEXT) { + // We hit EOF in the middle of processing something else. + this._emitSpecialToken("error"); + } else { + this._emitTokenIfNonempty("text"); + this._startSection(); + } } return this._token; }; diff --git a/src/language/HTMLUtils.js b/src/language/HTMLUtils.js index 14303433825..f189837b7cb 100644 --- a/src/language/HTMLUtils.js +++ b/src/language/HTMLUtils.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/language/JSONUtils.js b/src/language/JSONUtils.js index fbecbeeeffc..17f2aab7f49 100644 --- a/src/language/JSONUtils.js +++ b/src/language/JSONUtils.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $*/ - define(function (require, exports, module) { "use strict"; diff --git a/src/language/JSUtils.js b/src/language/JSUtils.js index 2ddd6f05e2d..e0a172be377 100644 --- a/src/language/JSUtils.js +++ b/src/language/JSUtils.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ +/*jslint regexp: true */ /** * Set of utilities for simple parsing of JS text. diff --git a/src/language/LanguageManager.js b/src/language/LanguageManager.js index fbf7bc3a465..1b714c5ee9c 100644 --- a/src/language/LanguageManager.js +++ b/src/language/LanguageManager.js @@ -21,9 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ /*unittests: LanguageManager*/ /** diff --git a/src/language/XMLUtils.js b/src/language/XMLUtils.js index 6966eb879d9..7d6e7875572 100644 --- a/src/language/XMLUtils.js +++ b/src/language/XMLUtils.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/main.js b/src/main.js index 5b1d224d14c..5405651f971 100644 --- a/src/main.js +++ b/src/main.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global require, define, window, brackets, navigator */ - /** * The bootstrapping module for brackets. This module sets up the require * configuration and loads the brackets module. @@ -63,7 +60,7 @@ if (window.location.search.indexOf("testEnvironment") > -1) { * extension). */ require.config({ - locale: window.localStorage.getItem("locale") || (typeof (brackets) !== "undefined" ? brackets.app.language : navigator.language) + locale: window.localStorage.getItem("locale") || (typeof (brackets) !== "undefined" ? brackets.app.language : window.navigator.language) }); } diff --git a/src/nls/bg/strings.js b/src/nls/bg/strings.js index 6c904663984..5b5eb3b4d39 100644 --- a/src/nls/bg/strings.js +++ b/src/nls/bg/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -131,7 +128,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Искате ли да запазите промените, които направихте в документа {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Искате ли да запазите промените си в следните файлове?", "EXT_MODIFIED_TITLE" : "Външни промени", - "CONFIRM_FOLDER_DELETE_TITLE" : "Потвърждаване на изтриването", + "CONFIRM_DELETE_TITLE" : "Потвърждаване на изтриването", "CONFIRM_FOLDER_DELETE" : "Наистина ли искате да изтриете папката {0}?", "FILE_DELETED_TITLE" : "Изтрит файл", "EXT_MODIFIED_WARNING" : "Файлът {0} беше променен извън {APP_NAME}.

    Искате ли да запазите файла и да презапишете промените му?", diff --git a/src/nls/bg/urls.js b/src/nls/bg/urls.js index 416b2beb651..7eae69cbf24 100644 --- a/src/nls/bg/urls.js +++ b/src/nls/bg/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "bg/Getting Started", diff --git a/src/nls/cs/strings.js b/src/nls/cs/strings.js index acf59be625e..82293a26993 100644 --- a/src/nls/cs/strings.js +++ b/src/nls/cs/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Chcete uložit změny v souboru {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Chcete uložit změny v následujících souborech?", "EXT_MODIFIED_TITLE" : "Externí změny", - "CONFIRM_FOLDER_DELETE_TITLE" : "Potvrdit smazání", + "CONFIRM_DELETE_TITLE" : "Potvrdit smazání", "CONFIRM_FOLDER_DELETE" : "Opravdu chcete smazat složku {0}?", "FILE_DELETED_TITLE" : "Soubor smazán", "EXT_MODIFIED_WARNING" : "{0} byl změněn mimo {APP_NAME}.

    Chcete uložit soubor a přepsat tyto změny?", diff --git a/src/nls/cs/urls.js b/src/nls/cs/urls.js index 53ea0387a4c..fcfc5a30af2 100644 --- a/src/nls/cs/urls.js +++ b/src/nls/cs/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "cs/Getting Started", diff --git a/src/nls/da/strings.js b/src/nls/da/strings.js index 401f66cc922..175b940cc00 100644 --- a/src/nls/da/strings.js +++ b/src/nls/da/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -115,7 +112,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Ønsker du at gemme ændringerne i dokumentet {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Ønsker du at gemme ændringerne i følgende filer?", "EXT_MODIFIED_TITLE" : "Eksterne ændringer", - "CONFIRM_FOLDER_DELETE_TITLE" : "Bekræft sletning", + "CONFIRM_DELETE_TITLE" : "Bekræft sletning", "CONFIRM_FOLDER_DELETE" : "Er du sikker på at du vil slette mappen {0}?", "FILE_DELETED_TITLE" : "Fil slettet", "EXT_MODIFIED_WARNING" : "{0} er blevet ændret på disken.

    Ønsker du at gemme filen og overskrive disse ændringer?", diff --git a/src/nls/da/urls.js b/src/nls/da/urls.js index dbe397115e5..1ccc584c26d 100644 --- a/src/nls/da/urls.js +++ b/src/nls/da/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "da/Kom godt i gang" diff --git a/src/nls/de/strings.js b/src/nls/de/strings.js index e7c9e93882a..6da7b8398c5 100644 --- a/src/nls/de/strings.js +++ b/src/nls/de/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -131,7 +128,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Wollen Sie die Änderungen in dem Dokument {0} speichern?", "SAVE_CLOSE_MULTI_MESSAGE" : "Wollen Sie Ihre Änderungen in den folgenden Dateien speichern?", "EXT_MODIFIED_TITLE" : "Externe Änderungen", - "CONFIRM_FOLDER_DELETE_TITLE" : "Löschen bestätigen", + "CONFIRM_DELETE_TITLE" : "Löschen bestätigen", "CONFIRM_FOLDER_DELETE" : "Sind Sie sich sicher, dass Sie den Ordner {0} löschen wollen?", "FILE_DELETED_TITLE" : "Datei gelöscht", "EXT_MODIFIED_WARNING" : "{0} wurde außerhalb von {APP_NAME} geändert.

    Wollen Sie die Datei speichern und die externen Änderungen ersetzen?", diff --git a/src/nls/de/urls.js b/src/nls/de/urls.js index a7d1d25299c..ebbd78ff50d 100644 --- a/src/nls/de/urls.js +++ b/src/nls/de/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "de/Erste Schritte", diff --git a/src/nls/el/strings.js b/src/nls/el/strings.js index 60030341c24..686ed0016ad 100644 --- a/src/nls/el/strings.js +++ b/src/nls/el/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -103,7 +100,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Θέλετε να αποθηκεύσετε τις αλλαγές που κάνατε στο έγγραφο {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Θέλετε να αποθηκεύσετε τις αλλαγές σας στα παρακάτω αρχεία;", "EXT_MODIFIED_TITLE" : "Εξωτερικές Αλλαγές", - "CONFIRM_FOLDER_DELETE_TITLE" : "Επιβεβαίωση Διαγραφής", + "CONFIRM_DELETE_TITLE" : "Επιβεβαίωση Διαγραφής", "CONFIRM_FOLDER_DELETE" : "Είστε σίγουρος ότι θέλετε να διαγράψετε τον φάκελο {0}?", "FILE_DELETED_TITLE" : "Το Αρχείο Διαγράφηκε", "EXT_MODIFIED_MESSAGE" : "Το {0} έχει τροποποιηθεί στο δίσκο, αλλά υπάρχουν και μη αποθηκευμένες αλλαγές στο {APP_NAME}.

    Ποια έκδοση θέλετε να κρατήσετε;", diff --git a/src/nls/el/urls.js b/src/nls/el/urls.js index 038e8188e5d..723262ca401 100644 --- a/src/nls/el/urls.js +++ b/src/nls/el/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "el/Ξεκινώντας", diff --git a/src/nls/en-gb/strings.js b/src/nls/en-gb/strings.js index cf7cd8f3dbd..6d9463e1ab1 100644 --- a/src/nls/en-gb/strings.js +++ b/src/nls/en-gb/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ }); diff --git a/src/nls/es/strings.js b/src/nls/es/strings.js index 85c9235ba44..e4c1a3962a0 100644 --- a/src/nls/es/strings.js +++ b/src/nls/es/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "¿Quieres guardar los cambios existentes en el documento {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "¿Quieres guardar tus cambios en los siguientes documentos?", "EXT_MODIFIED_TITLE" : "Cambios externos", - "CONFIRM_FOLDER_DELETE_TITLE" : "Confirmar eliminación", + "CONFIRM_DELETE_TITLE" : "Confirmar eliminación", "CONFIRM_FOLDER_DELETE" : "¿Estás seguro que deseas eliminar el directorio {0}?", "FILE_DELETED_TITLE" : "Archivo eliminado", "EXT_MODIFIED_WARNING" : "{0} ha sido modificado en el disco fuera de {APP_NAME}.

    ¿Deseas guardar el archivo y sobrescribir esos cambios?", diff --git a/src/nls/es/urls.js b/src/nls/es/urls.js index 40f424dd623..ea9380d7c44 100644 --- a/src/nls/es/urls.js +++ b/src/nls/es/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "es/Primeros Pasos", diff --git a/src/nls/fa-ir/strings.js b/src/nls/fa-ir/strings.js index 4757b8fe315..cc4598af7d7 100644 --- a/src/nls/fa-ir/strings.js +++ b/src/nls/fa-ir/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -129,7 +126,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "آیا مایلید تغییرات داده شده در سند ذخیره گردند {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "آیا مایلید تغییرات داده شده در پرونده های زیر، ذخیره گردند? ", "EXT_MODIFIED_TITLE" : "تغییرات خارجی", - "CONFIRM_FOLDER_DELETE_TITLE" : "تایید حذف", + "CONFIRM_DELETE_TITLE" : "تایید حذف", "CONFIRM_FOLDER_DELETE" : "آیا مطمئنید می خواهید این پوشه حذف گردد {0}?", "FILE_DELETED_TITLE" : "پرونده حذف گردید", "EXT_MODIFIED_WARNING" : "{0} خارج از براکتس ویرایش شده.

    آیا می خواهید پرونده را ذخیره و تغییراتی را که داده اید دوباره بر روی پرونده ویرایش شده اعمال نمایید؟", @@ -596,7 +593,7 @@ define({ "INLINE_TIMING_EDITOR_PROGRESSION" : "پیشرفت", "BEZIER_EDITOR_INFO" : " انتخاب حرکت نشانگر
    شیفتحرکت با ده واحد
    تب نقاط تغییر", "STEPS_EDITOR_INFO" : "افزایش و یا کاهش گام
    'شروع' or 'پایان'", - "INLINE_TIMING_EDITOR_INVALID" :"مقدار سابق {0} دیگر معتبر نمی باشد, زیرا تابع نمایش به مقدار {1} تغییر یافته. سند در اولین ویرایش بروزرسانی خواهد شد.", + "INLINE_TIMING_EDITOR_INVALID" : "مقدار سابق {0} دیگر معتبر نمی باشد, زیرا تابع نمایش به مقدار {1} تغییر یافته. سند در اولین ویرایش بروزرسانی خواهد شد.", // extensions/default/InlineColorEditor "COLOR_EDITOR_CURRENT_COLOR_SWATCH_TIP" : "رنگ فعلی", diff --git a/src/nls/fa-ir/urls.js b/src/nls/fa-ir/urls.js index d7aa668ea20..6ab6259efa2 100644 --- a/src/nls/fa-ir/urls.js +++ b/src/nls/fa-ir/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "fa-ir/Getting Started", diff --git a/src/nls/fi/strings.js b/src/nls/fi/strings.js index a1cff0d6ce7..c520f1ab086 100644 --- a/src/nls/fi/strings.js +++ b/src/nls/fi/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Haluatko tallentaa tekemäsi muutokset dokumenttiin {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Haluatko tallentaa muutokset seuraaviin tiedostoihin?", "EXT_MODIFIED_TITLE" : "Ulkoiset muutokset", - "CONFIRM_FOLDER_DELETE_TITLE" : "Vahvista poisto", + "CONFIRM_DELETE_TITLE" : "Vahvista poisto", "CONFIRM_FOLDER_DELETE" : "Haluatko varmasti poistaa kansion {0}?", "FILE_DELETED_TITLE" : "Tiedosto poistettu", "EXT_MODIFIED_WARNING" : "{0} on muuttunut levyllä {APP_NAME}in ulkopuolella.

    Haluatko tallentaa tiedoston ja korvata kyseiset muutokset?", diff --git a/src/nls/fi/urls.js b/src/nls/fi/urls.js index d71dc88a5c4..d81777cbb76 100644 --- a/src/nls/fi/urls.js +++ b/src/nls/fi/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "fi/Aloitus", diff --git a/src/nls/fr/strings.js b/src/nls/fr/strings.js index 04f8f597bc3..4a5bbd6ddd7 100644 --- a/src/nls/fr/strings.js +++ b/src/nls/fr/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -131,7 +128,7 @@ define({ "SAVE_CLOSE_MESSAGE": "Souhaitez-vous enregistrer les modifications apportées au document {0} ?", "SAVE_CLOSE_MULTI_MESSAGE": "Souhaitez-vous enregistrer les modifications apportées aux fichiers suivants ?", "EXT_MODIFIED_TITLE": "Modifications externes", - "CONFIRM_FOLDER_DELETE_TITLE": "Confirmer la suppression", + "CONFIRM_DELETE_TITLE": "Confirmer la suppression", "CONFIRM_FOLDER_DELETE": "Voulez-vous vraiment supprimer le dossier {0} ?", "FILE_DELETED_TITLE": "Fichier supprimé", "EXT_MODIFIED_WARNING": "{0} a été modifié sur le disque, dans une application autre que {APP_NAME}.

    Voulez-vous enregistrer le fichier et remplacer ces modifications ?", diff --git a/src/nls/fr/urls.js b/src/nls/fr/urls.js index c14693637c5..88cbd432780 100644 --- a/src/nls/fr/urls.js +++ b/src/nls/fr/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "fr/Premiers pas", diff --git a/src/nls/gl/strings.js b/src/nls/gl/strings.js index 3d3417a57e4..9cddb0f54a2 100644 --- a/src/nls/gl/strings.js +++ b/src/nls/gl/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -118,7 +115,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "¿Queres gardar os cambios existentes no documento {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "¿Queres gardar os teus cambios nos seguintes documentos?", "EXT_MODIFIED_TITLE" : "Cambios externos", - "CONFIRM_FOLDER_DELETE_TITLE" : "Confirmar eliminación", + "CONFIRM_DELETE_TITLE" : "Confirmar eliminación", "CONFIRM_FOLDER_DELETE" : "¿Está seguro de que desexa eliminar o directorio {0}?", "FILE_DELETED_TITLE" : "Arquivo eliminado", "EXT_MODIFIED_WARNING" : "{0} foi modificado no disco.

    ¿Desexa gardar o arquivo e sobrescribir eses cambios?", diff --git a/src/nls/hr/strings.js b/src/nls/hr/strings.js index d64d82a88ec..4efe3348a68 100644 --- a/src/nls/hr/strings.js +++ b/src/nls/hr/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -108,7 +105,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Želite li sačuvati izmjene koje ste napravili u dokumentu {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Želite li sačuvati izmjene sljedećih datoteka?", "EXT_MODIFIED_TITLE" : "Vanjske izmjene", - "CONFIRM_FOLDER_DELETE_TITLE" : "Potvrdi brisanje", + "CONFIRM_DELETE_TITLE" : "Potvrdi brisanje", "CONFIRM_FOLDER_DELETE" : "Da li ste sigurni da želite obrisati mapu {0}?", "FILE_DELETED_TITLE" : "Datoteka Obrisana", "EXT_MODIFIED_WARNING" : "{0} je bio izmjenjen na disku.

    Da li želite sačuvati datoteku i spremiti preko tih izmjena?", @@ -350,6 +347,8 @@ define({ "CMD_CSS_QUICK_EDIT_NEW_RULE" : "Novo pravilo", "CMD_NEXT_DOC" : "Sljedeći dokument", "CMD_PREV_DOC" : "Prethodni dokument", + "CMD_NEXT_DOC_LIST_ORDER" : "Sljedeći dokument u listi", + "CMD_PREV_DOC_LIST_ORDER" : "Prethodni dokument u listi", "CMD_SHOW_IN_TREE" : "Prikaži u stablu datoteka", "CMD_SHOW_IN_EXPLORER" : "Prikaži u Exploreru", "CMD_SHOW_IN_FINDER" : "Prikaži u Finderu", @@ -454,7 +453,7 @@ define({ "EXTENSION_MANAGER_TITLE" : "Manager extenzija", "EXTENSION_MANAGER_ERROR_LOAD" : "Pristupanje registru extenzije nije moguće. Pokušajte kasnije.", "INSTALL_EXTENSION_DRAG" : "Dovuci .zip ovdje ili", - "INSTALL_EXTENSION_DROP" : "Ispusti .zip da instaliraš", + "INSTALL_EXTENSION_DROP" : "ispusti .zip da instaliraš", "INSTALL_FROM_URL" : "Instaliraj sa URL linka\u2026", "EXTENSION_AUTHOR" : "Autor", "EXTENSION_DATE" : "Datum", @@ -480,7 +479,7 @@ define({ "MARKED_FOR_UPDATE" : "Označeno za ažuriranje", "UNDO_UPDATE" : "Poništi", "CHANGE_AND_RELOAD_TITLE" : "Promjeni extenzije", - "CHANGE_AND_RELOAD_MESSAGE" : "Da biste obnovili ili uklonili označene extenzije, {APP_NAME} će se trebati ponovo učitati. Bit ćete zatraženi da sačuvate nesačuvane promjene.", + "CHANGE_AND_RELOAD_MESSAGE" : "Da biste obnovili ili uklonili označene extenzije, {APP_NAME} se treba ponovo učitati. Bit ćete zatraženi da sačuvate nesačuvane promjene.", "REMOVE_AND_RELOAD" : "Ukloni extenzije i ponovno učitaj", "CHANGE_AND_RELOAD" : "Promjeni extenzije i ponovo učitaj", "UPDATE_AND_RELOAD" : "Obnovi extenzije i ponovo učitaj", diff --git a/src/nls/hr/urls.js b/src/nls/hr/urls.js index b40aaa5cc38..badaf9f2791 100644 --- a/src/nls/hr/urls.js +++ b/src/nls/hr/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "ADOBE_THIRD_PARTY" : "http://www.adobe.com/go/thirdparty/", diff --git a/src/nls/hu/strings.js b/src/nls/hu/strings.js index 42058989fa6..7516c40ffb3 100644 --- a/src/nls/hu/strings.js +++ b/src/nls/hu/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** diff --git a/src/nls/id/strings.js b/src/nls/id/strings.js index a3c25886c1f..bc878f5a768 100644 --- a/src/nls/id/strings.js +++ b/src/nls/id/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -129,7 +126,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Apakah Anda ingin menyimpan perubahan yang Anda buat di dokumen {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Apakah Anda ingin menyimpan perubahan pada file berikut?", "EXT_MODIFIED_TITLE" : "Perubahan Eksternal", - "CONFIRM_FOLDER_DELETE_TITLE" : "Konfirmasi Hapus", + "CONFIRM_DELETE_TITLE" : "Konfirmasi Hapus", "CONFIRM_FOLDER_DELETE" : "Apakah Anda yakin ingin menghapus folder {0}?", "FILE_DELETED_TITLE" : "File Dihapus", "EXT_MODIFIED_WARNING" : "{0} telah dimodifikasi di disk.

    Apakah Anda ingin menyimpan file dan menimpa perubahan tersebut?", diff --git a/src/nls/id/urls.js b/src/nls/id/urls.js index ef6be1c70aa..ac6a9631b6a 100644 --- a/src/nls/id/urls.js +++ b/src/nls/id/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "id/Memulai", diff --git a/src/nls/it/strings.js b/src/nls/it/strings.js index 3c5741d3789..cbc689631b8 100644 --- a/src/nls/it/strings.js +++ b/src/nls/it/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Vuoi cambiare le modifiche apportate al file {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Vuoi cambiare le modifiche apportate ai seguenti file?", "EXT_MODIFIED_TITLE" : "Modifiche esterne", - "CONFIRM_FOLDER_DELETE_TITLE" : "Confermi l'eliminazione?", + "CONFIRM_DELETE_TITLE" : "Confermi l'eliminazione?", "CONFIRM_FOLDER_DELETE" : "Sei sicuro di eliminare la cartella {0}?", "FILE_DELETED_TITLE" : "File Eliminato", "EXT_MODIFIED_WARNING" : "{0} è stato modificato sul disco.

    Vuoi salvare il file e sovrascrivere le modifiche?", @@ -571,7 +568,7 @@ define({ "EXTENSION_NOT_INSTALLED" : "Impossibile rimuovere l’estensione {0}. Non era installata.", "NO_EXTENSIONS" : "Nessuna estensione ancora installata.
    Clicca nel tab delle Disponibili per iniziare.", "NO_EXTENSION_MATCHES" : "Nessuna estensione soddisfa la tua ricerca.", - "REGISTRY_SANITY_CHECK_WARNING" : "NOTA: Queste estensioni possono provenire da autori diversi da {APP_NAME} se stessi. Le estensioni non vengono riviste e dispongono di privilegi locali completi. Fai attenzione quando installi le estensioni da sorgenti sconosciute.", + "REGISTRY_SANITY_CHECK_WARNING" : "NOTA: Queste estensioni possono provenire da autori diversi da {APP_NAME}. Le estensioni non vengono riviste e dispongono di privilegi locali completi. Fai attenzione quando installi le estensioni da sorgenti sconosciute.", "EXTENSIONS_INSTALLED_TITLE" : "Installate", "EXTENSIONS_AVAILABLE_TITLE" : "Disponibili", "EXTENSIONS_THEMES_TITLE" : "Temi", diff --git a/src/nls/it/urls.js b/src/nls/it/urls.js index 25981abf263..faaf40fee6f 100644 --- a/src/nls/it/urls.js +++ b/src/nls/it/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "it/Primi passi", diff --git a/src/nls/ja/strings.js b/src/nls/ja/strings.js index 25514830df6..588f5d67457 100644 --- a/src/nls/ja/strings.js +++ b/src/nls/ja/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -131,7 +128,7 @@ define({ "SAVE_CLOSE_MESSAGE": "文書 {0} に加えた変更を保存しますか?", "SAVE_CLOSE_MULTI_MESSAGE": "以下のファイルに対する変更を保存しますか?", "EXT_MODIFIED_TITLE": "外部で変更されました。", - "CONFIRM_FOLDER_DELETE_TITLE": "削除の確認", + "CONFIRM_DELETE_TITLE": "削除の確認", "CONFIRM_FOLDER_DELETE": "{0} フォルダーを削除してもよろしいですか?", "FILE_DELETED_TITLE": "ファイルは削除されました", "EXT_MODIFIED_WARNING": "{0} は {APP_NAME} 外のディスク上で変更されています。

    ファイルを保存し、これらの変更を上書きしますか?", diff --git a/src/nls/ja/urls.js b/src/nls/ja/urls.js index 2e14d893d56..034076c8710 100644 --- a/src/nls/ja/urls.js +++ b/src/nls/ja/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "ja/Getting Started", diff --git a/src/nls/ko/strings.js b/src/nls/ko/strings.js index 29e65285974..a19c9e60baa 100644 --- a/src/nls/ko/strings.js +++ b/src/nls/ko/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE": "문서 {0} 변경 내용을 저장 하시겠습니까?", "SAVE_CLOSE_MULTI_MESSAGE": "다음 파일에 대한 변경 사항을 저장 하시겠습니까?", "EXT_MODIFIED_TITLE": "외부 변경 감지", - "CONFIRM_FOLDER_DELETE_TITLE": "삭제 확인", + "CONFIRM_DELETE_TITLE": "삭제 확인", "CONFIRM_FOLDER_DELETE": "{0} 폴더를 삭제 하시겠습니까?", "FILE_DELETED_TITLE": "파일이 삭제되었습니다", "EXT_MODIFIED_WARNING": "{0}파일이 변경되었습니다.

    파일을 저장하여 이 변경 사항을 덮어씌우겠습니까?", diff --git a/src/nls/ko/urls.js b/src/nls/ko/urls.js index 9a4a9518243..4a24fd64d6c 100644 --- a/src/nls/ko/urls.js +++ b/src/nls/ko/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "ADOBE_THIRD_PARTY" : "http://www.adobe.com/go/thirdparty_kr/", diff --git a/src/nls/lv/strings.js b/src/nls/lv/strings.js index 7f0b03265a4..a8791eb1123 100644 --- a/src/nls/lv/strings.js +++ b/src/nls/lv/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -131,7 +128,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Vai vēlaties saglabāt veiktās izmaiņas dokumentā {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Vai vēlaties saglabāt izmaiņas šajās datnēs?", "EXT_MODIFIED_TITLE" : "Ārējas izmaiņas", - "CONFIRM_FOLDER_DELETE_TITLE" : "Apstiprināt dzēšanu", + "CONFIRM_DELETE_TITLE" : "Apstiprināt dzēšanu", "CONFIRM_FOLDER_DELETE" : "Vai tiešām vēlaties izdzēst mapi {0}?", "FILE_DELETED_TITLE" : "Datne izdzēsta", "EXT_MODIFIED_WARNING" : "{0} ir pārveidots diskā ārpus {APP_NAME}.

    Vai vēlaties saglabāt datni un pārrakstīt šīs izmaiņas?", diff --git a/src/nls/nb/strings.js b/src/nls/nb/strings.js index b97de590ee7..bf887f70c7c 100644 --- a/src/nls/nb/strings.js +++ b/src/nls/nb/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -115,7 +112,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Ønsker du å lagre enderinger i dokumentet {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Ønsker du å lagre enderinger i følgende filer?", "EXT_MODIFIED_TITLE" : "Eksterne endringer", - "CONFIRM_FOLDER_DELETE_TITLE" : "Bekreft sletting", + "CONFIRM_DELETE_TITLE" : "Bekreft sletting", "CONFIRM_FOLDER_DELETE" : "Er du sikker på at du vil slette katalogen {0}?", "FILE_DELETED_TITLE" : "Fil slettet", "EXT_MODIFIED_WARNING" : "{0} har blitt modifisert på disk.

    Vil du lagre filen og overskrive de endringene?", diff --git a/src/nls/nb/urls.js b/src/nls/nb/urls.js index 45e7a452878..96817e96c13 100644 --- a/src/nls/nb/urls.js +++ b/src/nls/nb/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "ADOBE_THIRD_PARTY" : "http://www.adobe.com/go/thirdparty/", diff --git a/src/nls/nl/strings.js b/src/nls/nl/strings.js index 7ab8096de01..4e15e6a6aee 100644 --- a/src/nls/nl/strings.js +++ b/src/nls/nl/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Wil je de wijzigingen opslaan die je maakte in het document {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Wil je je wijzigingen van de volgende bestanden opslaan?", "EXT_MODIFIED_TITLE" : "Externe wijzigingen", - "CONFIRM_FOLDER_DELETE_TITLE" : "Bevestig verwijderen", + "CONFIRM_DELETE_TITLE" : "Bevestig verwijderen", "CONFIRM_FOLDER_DELETE" : "Ben je zeker dat je de map {0} wil verwijderen?", "FILE_DELETED_TITLE" : "Bestand verwijderd", "EXT_MODIFIED_WARNING" : "{0} is gewijzigd op de schijf buiten {APP_NAME}.

    Wil je het bestand overschrijven evenals de wijzigingen buiten {APP_NAME} om?", diff --git a/src/nls/nl/urls.js b/src/nls/nl/urls.js index a08ec3cfa14..0360daa1269 100644 --- a/src/nls/nl/urls.js +++ b/src/nls/nl/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "nl/Aan-de-slag", diff --git a/src/nls/pl/strings.js b/src/nls/pl/strings.js index 69d2694fb88..f25d0a83965 100644 --- a/src/nls/pl/strings.js +++ b/src/nls/pl/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -84,7 +81,7 @@ define({ "ERROR_MULTIPLE_SHORTCUTS" : "Próbujesz przypisać kilka skrótów do następujących komend: {0}", "ERROR_DUPLICATE_SHORTCUTS" : "Upewnij się, że następujące skróty są unikalne (nie nadpisują się): {0}", "ERROR_INVALID_SHORTCUTS" : "Podane skróty są nieprawidłowe: {0}", - "ERROR_NONEXISTENT_COMMANDS" : "Próbujesz przypisać skróty do niestniejących komend: {0}", + "ERROR_NONEXISTENT_COMMANDS" : "Próbujesz przypisać skróty do niestniejących komend: {0}", // Application preferences corrupt error strings "ERROR_PREFS_CORRUPT_TITLE" : "Błąd podczas wczytywania ustawień", @@ -131,7 +128,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Czy chcesz zapisać zmiany w dokumencie {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Czy chcesz zapisać zmiany w następujących plikach?", "EXT_MODIFIED_TITLE" : "Zmiany zewnętrzne", - "CONFIRM_FOLDER_DELETE_TITLE" : "Potwierdź usunięcie", + "CONFIRM_DELETE_TITLE" : "Potwierdź usunięcie", "CONFIRM_FOLDER_DELETE" : "Czy na pewno chcesz usunąć folder {0}?", "FILE_DELETED_TITLE" : "Plik został usunięty", "EXT_MODIFIED_WARNING" : "{0} został zmodyfikowany na dysku, poza {APP_NAME}.

    Czy chcesz zapisać plik i nadpisać te zmiany?", diff --git a/src/nls/pl/urls.js b/src/nls/pl/urls.js index 28249166c89..7c9e545691d 100644 --- a/src/nls/pl/urls.js +++ b/src/nls/pl/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "pl/Szybki Start", diff --git a/src/nls/pt-br/strings.js b/src/nls/pt-br/strings.js index aa0ed06edbc..75a3b616181 100644 --- a/src/nls/pt-br/strings.js +++ b/src/nls/pt-br/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Você quer salvar as alterações feitas no documento {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Você quer salvar as alterações feitas aos seguintes arquivos?", "EXT_MODIFIED_TITLE" : "Alterações externas", - "CONFIRM_FOLDER_DELETE_TITLE" : "Confirmar exclusão", + "CONFIRM_DELETE_TITLE" : "Confirmar exclusão", "CONFIRM_FOLDER_DELETE" : "Tem certeza que deseja excluir a pasta {0}?", "FILE_DELETED_TITLE" : "Arquivo excluído", "EXT_MODIFIED_WARNING" : "{0} foi modificado no disco.

    Deseja salvar o arquivo e sobrescrever essas alterações?", @@ -621,9 +618,9 @@ define({ "HEALTH_DATA_NOTIFICATION" : "Preferências do relatório de saúde", "HEALTH_FIRST_POPUP_TITLE" : "Relatório de saúde do {APP_NAME}", "HEALTH_DATA_DO_TRACK" : "Compartilhe informações anônimas sobre como eu uso o {APP_NAME}", - "HEALTH_DATA_NOTIFICATION_MESSAGE" : "Com a intenção de melhorar a sua experiência com {APP_NAME}, nós enviamos periódicamente alguns poucos dados estatísticos de forma anônima para a Adobe, sobre como você utiliza o {APP_NAME}. Essas informações nos ajudam a priorizar novas funcionalidades, encontrar bugs, e encontrar problemas de usabilidade.

    Você pode ver e/ou escolher o que deseja compartilhar em Ajuda > Relatório de saúde Brackets.

    Aprenda mais sobre a saúde de seu {APP_NAME}", + "HEALTH_DATA_NOTIFICATION_MESSAGE" : "Com a intenção de melhorar a sua experiência com {APP_NAME}, nós enviamos periodicamente alguns poucos dados estatísticos de forma anônima para a Adobe, sobre como você utiliza o {APP_NAME}. Essas informações nos ajudam a priorizar novas funcionalidades, encontrar bugs, e encontrar problemas de usabilidade.

    Você pode ver e/ou escolher o que deseja compartilhar em Ajuda > Relatório de saúde Brackets.

    Aprenda mais sobre a saúde de seu {APP_NAME}", "HEALTH_DATA_PREVIEW" : "Relatório de saúde do {APP_NAME}", - "HEALTH_DATA_PREVIEW_INTRO" : "

    Com a intenção de melhorar a sua experiência com {APP_NAME}, nós enviamos periódicamente alguns poucos dados estatísticos de forma anônima para a Adobe, sobre como você utiliza o {APP_NAME}. Essas informações nos ajudam a priorizar novas funcionalidades, encontrar bugs, e encontrar problemas de usabilidade. Aprenda mais sobre a saúde de seu {APP_NAME} e veja como isso beneficiará a comunidade {APP_NAME}, e isso tudo mantendo sua privacidade.

    Abaixo está uma prévia de como será modelo de dados enviados em seu próximo relatório de saúde se ele for habilitado por você.

    ", + "HEALTH_DATA_PREVIEW_INTRO" : "

    Com a intenção de melhorar a sua experiência com {APP_NAME}, nós enviamos periodicamente alguns poucos dados estatísticos de forma anônima para a Adobe, sobre como você utiliza o {APP_NAME}. Essas informações nos ajudam a priorizar novas funcionalidades, encontrar bugs, e encontrar problemas de usabilidade. Aprenda mais sobre a saúde de seu {APP_NAME} e veja como isso beneficiará a comunidade {APP_NAME}, e isso tudo mantendo sua privacidade.

    Abaixo está uma prévia de como será modelo de dados enviados em seu próximo relatório de saúde se ele for habilitado por você.

    ", // extensions/default/InlineTimingFunctionEditor "INLINE_TIMING_EDITOR_TIME" : "Tempo", @@ -667,12 +664,12 @@ define({ "EXPAND_CURRENT" : "Expandir Posição Atual", // Descriptions of core preferences - "DESCRIPTION_CLOSE_BRACKETS" : "verdadeiro (true) para fechar chaves, colchetes e parênteses automáticamente", + "DESCRIPTION_CLOSE_BRACKETS" : "verdadeiro (true) para fechar chaves, colchetes e parênteses automaticamente", "DESCRIPTION_CLOSE_OTHERS_ABOVE" : "falso (false) para remover \"Fechar outros acima\" do menu de contexto Arquivos abertos", "DESCRIPTION_CLOSE_OTHERS_BELOW" : "falso (false) para remover \"Fechar outros abaixo\" do menu de contexto Arquivos abertos", "DESCRIPTION_CLOSE_OTHERS" : "falso (false) para remover \"Fechar outros\" do menu de contexto Arquivos abertos", "DESCRIPTION_CLOSE_TAGS" : "Definir opções de fechamento de tags", - "DESCRIPTION_CLOSE_TAGS_DONT_CLOSE_TAGS" : "Uma matriz de tags não deve ser automáticamente fechada", + "DESCRIPTION_CLOSE_TAGS_DONT_CLOSE_TAGS" : "Uma matriz de tags não deve ser automaticamente fechada", "DESCRIPTION_CLOSE_TAGS_WHEN_OPENING" : "Fechar > quando a abertura da tag for digitada", "DESCRIPTION_CLOSE_TAGS_WHEN_CLOSING" : "Fechar / quando o fechamento da tag for digitada", "DESCRIPTION_CLOSE_TAGS_INDENT_TAGS" : "Um vetor de tags terá uma linha em branco entre as tags quando for aberta", @@ -696,11 +693,11 @@ define({ "DESCRIPTION_HIGHLIGHT_MATCHES_SHOW_TOKEN" : "Destaque todas strings correspondentes ao símbolo em que o cursor se encontra (não é necessária uma seleção)", "DESCRIPTION_HIGHLIGHT_MATCHES_WORDS_ONLY" : "Destaque somente quando um símbolo selecionado estiver completo", "DESCRIPTION_INSERT_HINT_ON_TAB" : "verdadeiro (true) para inserir a sugestão de código ao pressionar tab", - "DESCRIPTION_NO_HINTS_ON_DOT" : "verdadeiro (true) para não mostrar automáticamente dicas para JS quando . for digitado", + "DESCRIPTION_NO_HINTS_ON_DOT" : "verdadeiro (true) para não mostrar automaticamente dicas para JS quando . for digitado", "DESCRIPTION_JSLINT_OPTIONS" : "Um objeto com valores padrões para JSLint", "DESCRIPTION_JSLINT_OPTIONS_ASS" : "verdadeiro (true) para permitir expressões de atribuição", "DESCRIPTION_JSLINT_OPTIONS_BITWISE" : "verdadeiro (true) para permitir operadores bitwise", - "DESCRIPTION_JSLINT_OPTIONS_BROWSER" : "verdadeiro (true) se as funçõesvariáveis globais do navegador devem ser predefinidos", + "DESCRIPTION_JSLINT_OPTIONS_BROWSER" : "verdadeiro (true) se as funções variáveis globais do navegador devem ser predefinidos", "DESCRIPTION_JSLINT_OPTIONS_CLOSURE" : "verdadeiro (true) para permitir expressões idiomáticas do Google Closure", "DESCRIPTION_JSLINT_OPTIONS_CONTINUE" : "verdadeiro (true) para permitir a declaração \"continue\"", "DESCRIPTION_JSLINT_OPTIONS_COUCH" : "verdadeiro (true) se as funções/variáveis globais do CouchDB devem ser predefinidos", @@ -741,8 +738,8 @@ define({ "DESCRIPTION_SCROLL_PAST_END" : "verdadeiro (true) para habilitar o scrolling após o fim do arquivo", "DESCRIPTION_SHOW_CODE_HINTS" : "falso (false) para desabilitar todos as sugestões de código", "DESCRIPTION_SHOW_CURSOR_WHEN_SELECTING" : "Mantenha o cursor visível quando houver uma seleção de texto", - "DESCRIPTION_SHOW_LINE_NUMBERS" : "verdadeiro (true) para mostrar o número das linhas na borda \"gutter\" as esquerda do editor", - "DESCRIPTION_SMART_INDENT" : "Identar automáticamente quando se criar um novo bloco", + "DESCRIPTION_SHOW_LINE_NUMBERS" : "verdadeiro (true) para mostrar o número das linhas na borda \"gutter\" à esquerda do editor", + "DESCRIPTION_SMART_INDENT" : "Identar automaticamente quando se criar um novo bloco", "DESCRIPTION_SOFT_TABS" : "falso (false) para desabilitar o comportamento de \"soft tabs\"", "DESCRIPTION_SORT_DIRECTORIES_FIRST" : "verdadeiro (true) para ordenar os diretórios no topo da árvore de projetos", "DESCRIPTION_SPACE_UNITS" : "Quantidade de espaços utilizados na identações baseada em espaços", @@ -755,14 +752,14 @@ define({ "DESCRIPTION_DETECTED_EXCLUSIONS" : "Uma lista de arquivos que foram detectados problemas fazem o Tern não funcionar corretamente", "DESCRIPTION_INFERENCE_TIMEOUT" : "Quantidade de vezes que o Tern deixará de tentar de compreender os arquivos", "DESCRIPTION_SHOW_ERRORS_IN_STATUS_BAR" : "verdadeiro (true) para mostrar os erros na barra de status", - "DESCRIPTION_QUICK_VIEW_ENABLED" : "verdadeiro (true) pra habilitar Visualização Rápida/Quick View", + "DESCRIPTION_QUICK_VIEW_ENABLED" : "verdadeiro (true) pra habilitar Visualização Rápida/Quick View", "DESCRIPTION_EXTENSION_LESS_IMAGE_PREVIEW" : "verdadeiro (true) para mostrar uma prévia de imagem para URLs sem extensões", "DESCRIPTION_THEME" : "Selecionar um tema para {APP_NAME}", "DESCRIPTION_USE_THEME_SCROLLBARS" : "verdadeiro (true) para permitir barras de rolagem customizadas", "DESCRIPTION_LINTING_COLLAPSED" : "verdadeiro (true) para agrupar painel de sugestões", "DESCRIPTION_FONT_FAMILY" : "Alterar fonte", "DESCRIPTION_FONT_SIZE" : "Alterar o tamanho da fonte; e.g. 13px", - "DESCRIPTION_FIND_IN_FILES_NODE" : "verdadeiro (true) para habilitar a búsca baseada em nós/node", + "DESCRIPTION_FIND_IN_FILES_NODE" : "verdadeiro (true) para habilitar a busca baseada em nós/node", "DESCRIPTION_FIND_IN_FILES_INSTANT" : "verdadeiro (true) para habilitar busca instantânea", "DESCRIPTION_FONT_SMOOTHING" : "Somente para Mac: \"subpixel-antialiased\" para habilitar sub-pixel antialiasing ou \"antialiased\" para gray scale antialiasing / antialiasing com escala de cinza", "DESCRIPTION_OPEN_PREFS_IN_SPLIT_VIEW" : "falso (false) para desabilitar a abertura do arquivo de preferências em tela dividida", diff --git a/src/nls/pt-br/urls.js b/src/nls/pt-br/urls.js index 56bee120510..d952c95d377 100644 --- a/src/nls/pt-br/urls.js +++ b/src/nls/pt-br/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "pt-br/Primeiros Passos" diff --git a/src/nls/pt-pt/strings.js b/src/nls/pt-pt/strings.js index 1028f9144cf..9b1db56aea9 100644 --- a/src/nls/pt-pt/strings.js +++ b/src/nls/pt-pt/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** * Errors diff --git a/src/nls/pt-pt/urls.js b/src/nls/pt-pt/urls.js index 284e1eed317..8d90b94ccb8 100644 --- a/src/nls/pt-pt/urls.js +++ b/src/nls/pt-pt/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "pt-pt/Primeiros Passos" diff --git a/src/nls/ro/strings.js b/src/nls/ro/strings.js index 5841c7768e0..27cb4b1ec31 100644 --- a/src/nls/ro/strings.js +++ b/src/nls/ro/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -129,7 +126,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Doriți să salvați modificările făcute în documentul {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Doriți să salvați modificările din următoarele fișiere?", "EXT_MODIFIED_TITLE" : "Modificări externe", - "CONFIRM_FOLDER_DELETE_TITLE" : "Confirmare ștergere dosar", + "CONFIRM_DELETE_TITLE" : "Confirmare ștergere dosar", "CONFIRM_FOLDER_DELETE" : "Sunteți sigur că doriți să ștergeți dosarul {0}?", "FILE_DELETED_TITLE" : "Fișier șters", "EXT_MODIFIED_WARNING" : "{0} a fost modificat pe disc.

    Doriți să salvați fișierul și să suprascrieți aceste modificări?", diff --git a/src/nls/root/strings-app.js b/src/nls/root/strings-app.js index f5984505b85..d4b5adfcc22 100644 --- a/src/nls/root/strings-app.js +++ b/src/nls/root/strings-app.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // product-specific strings "APP_NAME" : "Brackets", diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index 056fb163aa0..a0ee7f9e182 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -131,7 +128,8 @@ define({ "SAVE_CLOSE_MESSAGE" : "Do you want to save the changes you made in the document {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Do you want to save your changes to the following files?", "EXT_MODIFIED_TITLE" : "External Changes", - "CONFIRM_FOLDER_DELETE_TITLE" : "Confirm Delete", + "CONFIRM_DELETE_TITLE" : "Confirm Delete", + "CONFIRM_FILE_DELETE" : "Are you sure you want to delete the file {0}?", "CONFIRM_FOLDER_DELETE" : "Are you sure you want to delete the folder {0}?", "FILE_DELETED_TITLE" : "File Deleted", "EXT_MODIFIED_WARNING" : "{0} has been modified on disk outside of {APP_NAME}.

    Do you want to save the file and overwrite those changes?", @@ -505,6 +503,7 @@ define({ "VIEW_TRUNCATED_DESCRIPTION" : "View truncated description", // These must match the error codes in ExtensionsDomain.Errors.* : "INVALID_ZIP_FILE" : "The downloaded content is not a valid zip file.", + "MISSING_PACKAGE_JSON" : "The package has no package.json file.", "INVALID_PACKAGE_JSON" : "The package.json file is not valid (error was: {0}).", "MISSING_PACKAGE_NAME" : "The package.json file doesn't specify a package name.", "BAD_PACKAGE_NAME" : "{0} is an invalid package name.", @@ -744,6 +743,7 @@ define({ "DESCRIPTION_LANGUAGE" : "Language specific settings", "DESCRIPTION_LANGUAGE_FILE_EXTENSIONS" : "Additional mappings from file extension to language name", "DESCRIPTION_LANGUAGE_FILE_NAMES" : "Additional mappings from file name to language name", + "DESCRIPTION_LINEWISE_COPY_CUT" : "Doing copy and cut when there's no selection will copy or cut the whole lines that have cursors in them", "DESCRIPTION_LINTING_ENABLED" : "true to enable Code Inspection", "DESCRIPTION_ASYNC_TIMEOUT" : "The time in milliseconds after which asynchronous linters time out", "DESCRIPTION_LINTING_PREFER" : "Array of linters to run first", diff --git a/src/nls/root/urls.js b/src/nls/root/urls.js index b2af1c6abc8..ac1965a4a97 100644 --- a/src/nls/root/urls.js +++ b/src/nls/root/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "root/Getting Started", diff --git a/src/nls/ru/strings.js b/src/nls/ru/strings.js index 8350f6e9fa1..9d71e7edcb3 100644 --- a/src/nls/ru/strings.js +++ b/src/nls/ru/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -114,7 +111,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Вы хотите сохранить изменения, которые вы сделали в документе {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Вы хотите сохранить изменения для следующих файлов?", "EXT_MODIFIED_TITLE" : "Внешние изменения", - "CONFIRM_FOLDER_DELETE_TITLE" : "Подтвердить удаление", + "CONFIRM_DELETE_TITLE" : "Подтвердить удаление", "CONFIRM_FOLDER_DELETE" : "Вы уверены, что хотите удалить директорию {0}?", "FILE_DELETED_TITLE" : "Файл удален", "EXT_MODIFIED_WARNING" : "{0} был изменен на диске.

    Вы хотите сохранить ваши изменения и перезаписать внешние?", diff --git a/src/nls/ru/urls.js b/src/nls/ru/urls.js index c489b9a2830..b6b1aeefd65 100644 --- a/src/nls/ru/urls.js +++ b/src/nls/ru/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "ru/Getting Started", diff --git a/src/nls/sk/strings.js b/src/nls/sk/strings.js index 02a469fb828..b4aa05ff3f7 100644 --- a/src/nls/sk/strings.js +++ b/src/nls/sk/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -102,7 +99,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Chcete uložiť zmeny, ktoré ste spravili v dokumente {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Chcete uložiť zmeny v následujúcich súboroch?", "EXT_MODIFIED_TITLE" : "Externé zmeny", - "CONFIRM_FOLDER_DELETE_TITLE" : "Potvrdte odstránenie", + "CONFIRM_DELETE_TITLE" : "Potvrdte odstránenie", "CONFIRM_FOLDER_DELETE" : "Ste si istý zmazaním priečinku {0}?", "FILE_DELETED_TITLE" : "Súbor odstránený", "EXT_MODIFIED_MESSAGE" : "{0} bol upravený na disku, ale tiež ma neuložené zmeny in {APP_NAME}.

    Ktorú verziu chcete ponechať?", diff --git a/src/nls/sr/strings-app.js b/src/nls/sr/strings-app.js index 4747ddbb6a7..4d5276cbb1f 100644 --- a/src/nls/sr/strings-app.js +++ b/src/nls/sr/strings-app.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // product-specific strings "APP_NAME" : "Заграде" diff --git a/src/nls/sr/strings.js b/src/nls/sr/strings.js index 4512ec94401..6066b72db20 100644 --- a/src/nls/sr/strings.js +++ b/src/nls/sr/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -129,7 +126,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Да ли желите да сачувате измене које сте направили у документу {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Да ли желите да сачувате Ваше измене над следећим датотекама?", "EXT_MODIFIED_TITLE" : "Екстерне измене", - "CONFIRM_FOLDER_DELETE_TITLE" : "Потврди брисање", + "CONFIRM_DELETE_TITLE" : "Потврди брисање", "CONFIRM_FOLDER_DELETE" : "Да ли сте сигурни да желите обрисати директоријум {0}?", "FILE_DELETED_TITLE" : "Датотека обрисана", "EXT_MODIFIED_WARNING" : "Датотека {0} је измењена на диску.

    Да ли желите да сачувате датотеку и преснимите те измене?", diff --git a/src/nls/strings-app.js b/src/nls/strings-app.js index 96b6788d198..1c76630da73 100644 --- a/src/nls/strings-app.js +++ b/src/nls/strings-app.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/nls/strings.js b/src/nls/strings.js index 453c836c69e..769b0d0457b 100644 --- a/src/nls/strings.js +++ b/src/nls/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/nls/sv/strings.js b/src/nls/sv/strings.js index f7394bedb37..0119bf297f3 100644 --- a/src/nls/sv/strings.js +++ b/src/nls/sv/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Vill du spara de ändringar i dokumentet {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Vill du spara ändringarna du gjort följande filer?", "EXT_MODIFIED_TITLE" : "Externa ändringar", - "CONFIRM_FOLDER_DELETE_TITLE" : "Bekräfta borttagning", + "CONFIRM_DELETE_TITLE" : "Bekräfta borttagning", "CONFIRM_FOLDER_DELETE" : "Är du säker att du vill radera mappen {0}?", "FILE_DELETED_TITLE" : "Filen raderades", "EXT_MODIFIED_WARNING" : "{0} har ändrats.

    Vill du spara filen och skriva över dessa ändringar?", diff --git a/src/nls/sv/urls.js b/src/nls/sv/urls.js index b55eaa15381..a6d8696b4dc 100644 --- a/src/nls/sv/urls.js +++ b/src/nls/sv/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "sv/Kom igang", diff --git a/src/nls/tr/strings.js b/src/nls/tr/strings.js index aab06af334e..d405a3efe74 100644 --- a/src/nls/tr/strings.js +++ b/src/nls/tr/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** * Errors diff --git a/src/nls/tr/urls.js b/src/nls/tr/urls.js index aeb2f19d77f..54970f2eb75 100644 --- a/src/nls/tr/urls.js +++ b/src/nls/tr/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "ADOBE_THIRD_PARTY" : "http://www.adobe.com/go/thirdparty_tr/", diff --git a/src/nls/uk/strings.js b/src/nls/uk/strings.js index 54c6672c039..d156e54de90 100644 --- a/src/nls/uk/strings.js +++ b/src/nls/uk/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -129,7 +126,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "Чи бажаєте ви зберегти зміни внесені у файл {0}?", "SAVE_CLOSE_MULTI_MESSAGE" : "Чи бажаєте ви зберегти зміни до наступних файлів?", "EXT_MODIFIED_TITLE" : "Зовнішні зміни", - "CONFIRM_FOLDER_DELETE_TITLE" : "Підтвердження видалення", + "CONFIRM_DELETE_TITLE" : "Підтвердження видалення", "CONFIRM_FOLDER_DELETE" : "Ви дійсно хочете видалити теку {0}?", "FILE_DELETED_TITLE" : "Файл видалено", "EXT_MODIFIED_WARNING" : "{0} змінено на диску.

    Чи ви хочете зберегти файл і перезаписати ці зміни?", diff --git a/src/nls/urls.js b/src/nls/urls.js index 9b93083b908..e0bc1381636 100644 --- a/src/nls/urls.js +++ b/src/nls/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/nls/zh-cn/strings.js b/src/nls/zh-cn/strings.js index 4b2f8523c82..5a7a940a7d2 100644 --- a/src/nls/zh-cn/strings.js +++ b/src/nls/zh-cn/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -131,7 +128,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "保存 {0} 文件中所做的修改?", "SAVE_CLOSE_MULTI_MESSAGE" : "是否保存以下文件的修改?", "EXT_MODIFIED_TITLE" : "外部文件发生变化", - "CONFIRM_FOLDER_DELETE_TITLE" : "删除确认", + "CONFIRM_DELETE_TITLE" : "删除确认", "CONFIRM_FOLDER_DELETE" : "确认要删除目录 {0}?", "FILE_DELETED_TITLE" : "文件已删除", "EXT_MODIFIED_WARNING" : "{0} 已产生了外部修改,

    是否保存并覆盖外部修改?", diff --git a/src/nls/zh-cn/urls.js b/src/nls/zh-cn/urls.js index 4a27c16f4a7..617bdc047d5 100644 --- a/src/nls/zh-cn/urls.js +++ b/src/nls/zh-cn/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "ADOBE_THIRD_PARTY" : "http://www.adobe.com/go/thirdparty/", diff --git a/src/nls/zh-tw/strings.js b/src/nls/zh-tw/strings.js index 0e1f65c4169..f34be87c569 100644 --- a/src/nls/zh-tw/strings.js +++ b/src/nls/zh-tw/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ /** @@ -130,7 +127,7 @@ define({ "SAVE_CLOSE_MESSAGE" : "您想要儲存 {0} 檔案的變更嗎?", "SAVE_CLOSE_MULTI_MESSAGE" : "您想要儲存下列檔案的變更嗎?", "EXT_MODIFIED_TITLE" : "外部變更", - "CONFIRM_FOLDER_DELETE_TITLE" : "確定刪除", + "CONFIRM_DELETE_TITLE" : "確定刪除", "CONFIRM_FOLDER_DELETE" : "您確定要刪除 {0} 資料夾嗎?", "FILE_DELETED_TITLE" : "檔案已刪除", "EXT_MODIFIED_WARNING" : "{0} 在 {APP_NAME} 外被修改過了。

    您想要儲存檔案並覆寫蓋掉外部的變更嗎?", diff --git a/src/nls/zh-tw/urls.js b/src/nls/zh-tw/urls.js index c4ee5b6cddc..c3cfb9eeb04 100644 --- a/src/nls/zh-tw/urls.js +++ b/src/nls/zh-tw/urls.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define({ // Relative to the samples folder "GETTING_STARTED" : "zh-tw/Getting Started", diff --git a/src/preferences/PreferenceStorage.js b/src/preferences/PreferenceStorage.js index 7dbed4c27b4..08b74946214 100644 --- a/src/preferences/PreferenceStorage.js +++ b/src/preferences/PreferenceStorage.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * PreferenceStorage defines an interface for persisting preference data as * name/value pairs for a module or plugin. diff --git a/src/preferences/PreferencesBase.js b/src/preferences/PreferencesBase.js index de3d39287ec..1b5c9337faa 100644 --- a/src/preferences/PreferencesBase.js +++ b/src/preferences/PreferencesBase.js @@ -21,7 +21,7 @@ * */ -/*global define, $, console, appshell */ +/*global appshell */ /*unittests: Preferences Base */ /** diff --git a/src/preferences/PreferencesDialogs.js b/src/preferences/PreferencesDialogs.js index efba4ba2b6a..65b6ddec391 100644 --- a/src/preferences/PreferencesDialogs.js +++ b/src/preferences/PreferencesDialogs.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * PreferencesDialogs * diff --git a/src/preferences/PreferencesImpl.js b/src/preferences/PreferencesImpl.js index 7cbb87a238f..0cbfa137381 100644 --- a/src/preferences/PreferencesImpl.js +++ b/src/preferences/PreferencesImpl.js @@ -21,9 +21,6 @@ * */ - -/*global define, $, brackets */ - /** * Generates the fully configured preferences systems used throughout Brackets. This is intended * to be essentially private implementation that can be overridden for tests. diff --git a/src/preferences/PreferencesManager.js b/src/preferences/PreferencesManager.js index f2d310e896a..50b0993d5e3 100644 --- a/src/preferences/PreferencesManager.js +++ b/src/preferences/PreferencesManager.js @@ -21,8 +21,6 @@ * */ - -/*global define, localStorage, console */ /*unittests: Preferences Manager */ /** @@ -196,7 +194,7 @@ define(function (require, exports, module) { // Check localStorage for a preferencesKey. Production and unit test keys // are used to keep preferences separate within the same storage implementation. - preferencesKey = localStorage.getItem("preferencesKey"); + preferencesKey = window.localStorage.getItem("preferencesKey"); if (!preferencesKey) { // use default key if none is found @@ -204,11 +202,11 @@ define(function (require, exports, module) { doLoadPreferences = true; } else { // using a non-default key, check for additional settings - doLoadPreferences = !!(localStorage.getItem("doLoadPreferences")); + doLoadPreferences = !!(window.localStorage.getItem("doLoadPreferences")); } // Use localStorage by default - _initStorage(localStorage); + _initStorage(window.localStorage); // Public API diff --git a/src/project/FileSyncManager.js b/src/project/FileSyncManager.js index bb3d954ac9a..e8e1527a384 100644 --- a/src/project/FileSyncManager.js +++ b/src/project/FileSyncManager.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * FileSyncManager is a set of utilities to help track external modifications to the files and folders * in the currently open project. diff --git a/src/project/FileTreeView.js b/src/project/FileTreeView.js index 65c128cd501..ab21056a346 100644 --- a/src/project/FileTreeView.js +++ b/src/project/FileTreeView.js @@ -21,7 +21,6 @@ * */ -/*global define, $*/ /*unittests: FileTreeView*/ /** @@ -61,6 +60,8 @@ define(function (require, exports, module) { RIGHT_MOUSE_BUTTON = 2, LEFT_MOUSE_BUTTON = 0; + var INDENTATION_WIDTH = 10; + /** * @private * @@ -109,6 +110,40 @@ define(function (require, exports, module) { return width; } + /** + * @private + * + * Create an appropriate div based "thickness" to indent the tree correctly. + * + * @param {int} depth The depth of the current node. + * @return {ReactComponent} The resulting div. + */ + function _createThickness(depth) { + return DOM.div({ + style: { + display: "inline-block", + width: INDENTATION_WIDTH * depth + } + }); + } + + /** + * @private + * + * Create, and indent correctly, the arrow icons used for the folders. + * + * @param {int} depth The depth of the current node. + * @return {ReactComponent} The resulting ins. + */ + function _createAlignedIns(depth) { + return DOM.ins({ + className: "jstree-icon", + style: { + marginLeft: INDENTATION_WIDTH * depth + } + }); + } + /** * This is a mixin that provides rename input behavior. It is responsible for taking keyboard input * and invoking the correct action based on that input. @@ -392,6 +427,7 @@ define(function (require, exports, module) { handleClick: function (e) { // If we're renaming, allow the click to go through to the rename input. if (this.props.entry.get("rename")) { + e.stopPropagation(); return; } @@ -458,7 +494,22 @@ define(function (require, exports, module) { 'context-node': this.props.entry.get("context") }); + var liArgs = [ + { + className: this.getClasses("jstree-leaf"), + onClick: this.handleClick, + onMouseDown: this.handleMouseDown, + onDoubleClick: this.handleDoubleClick + }, + DOM.ins({ + className: "jstree-icon" + }), + ]; + + var thickness = _createThickness(this.props.depth); + if (this.props.entry.get("rename")) { + liArgs.push(thickness); nameDisplay = fileRenameInput({ actions: this.props.actions, entry: this.props.entry, @@ -470,20 +521,13 @@ define(function (require, exports, module) { var aArgs = _.flatten([{ href: "#", className: fileClasses - }, this.getIcons(), name, extension]); + }, thickness, this.getIcons(), name, extension]); nameDisplay = DOM.a.apply(DOM.a, aArgs); } - return DOM.li({ - className: this.getClasses("jstree-leaf"), - onClick: this.handleClick, - onMouseDown: this.handleMouseDown, - onDoubleClick: this.handleDoubleClick - }, - DOM.ins({ - className: "jstree-icon" - }, " "), - nameDisplay); + liArgs.push(nameDisplay); + + return DOM.li.apply(DOM.li, liArgs); } })); @@ -613,6 +657,11 @@ define(function (require, exports, module) { * If you click on a directory, it will toggle between open and closed. */ handleClick: function (event) { + if (this.props.entry.get("rename")) { + event.stopPropagation(); + return; + } + if (event.button !== LEFT_MOUSE_BUTTON) { return; } @@ -663,12 +712,12 @@ define(function (require, exports, module) { nodeClass, childNodes, children = entry.get("children"), - isOpen = entry.get("open"), - directoryClasses = ""; + isOpen = entry.get("open"); if (isOpen && children) { nodeClass = "open"; childNodes = directoryContents({ + depth: this.props.depth + 1, parentPath: this.myPath(), contents: children, extensions: this.props.extensions, @@ -681,46 +730,46 @@ define(function (require, exports, module) { nodeClass = "closed"; } - if (this.props.entry.get("selected")) { - directoryClasses += " jstree-clicked sidebar-selection"; - } + var nameDisplay, + cx = Classnames; - if (entry.get("context")) { - directoryClasses += " context-node"; - } + var directoryClasses = cx({ + 'jstree-clicked sidebar-selection': entry.get("selected"), + 'context-node': entry.get("context") + }); + + var liArgs = [ + { + className: this.getClasses("jstree-" + nodeClass), + onClick: this.handleClick, + onMouseDown: this.handleMouseDown + }, + _createAlignedIns(this.props.depth) + ]; + + var thickness = _createThickness(this.props.depth); - var nameDisplay, renameInput; if (entry.get("rename")) { - renameInput = directoryRenameInput({ + liArgs.push(thickness); + nameDisplay = directoryRenameInput({ actions: this.props.actions, - entry: this.props.entry, + entry: entry, name: this.props.name, parentPath: this.props.parentPath }); + } else { + // Need to flatten the arguments because getIcons returns an array + var aArgs = _.flatten([{ + href: "#", + className: directoryClasses + }, thickness, this.getIcons(), this.props.name]); + nameDisplay = DOM.a.apply(DOM.a, aArgs); } - // Need to flatten the arguments because getIcons returns an array - var aArgs = _.flatten([{ - href: "#", - className: directoryClasses - }, this.getIcons()]); - if (!entry.get("rename")) { - aArgs.push(this.props.name); - } - - nameDisplay = DOM.a.apply(DOM.a, aArgs); + liArgs.push(nameDisplay); + liArgs.push(childNodes); - return DOM.li({ - className: this.getClasses("jstree-" + nodeClass), - onClick: this.handleClick, - onMouseDown: this.handleMouseDown - }, - DOM.ins({ - className: "jstree-icon" - }, " "), - renameInput, - nameDisplay, - childNodes); + return DOM.li.apply(DOM.li, liArgs); } })); @@ -765,6 +814,7 @@ define(function (require, exports, module) { if (FileTreeViewModel.isFile(entry)) { return fileNode({ + depth: this.props.depth, parentPath: this.props.parentPath, name: name, entry: entry, @@ -776,6 +826,7 @@ define(function (require, exports, module) { }); } else { return directoryNode({ + depth: this.props.depth, parentPath: this.props.parentPath, name: name, entry: entry, @@ -828,16 +879,10 @@ define(function (require, exports, module) { width = selectionViewInfo.get("width"), scrollWidth = selectionViewInfo.get("scrollWidth"); - // Avoid endless horizontal scrolling - if (left + width > scrollWidth) { - left = scrollWidth - width; - } - return DOM.div({ style: { overflow: "auto", left: left, - width: width, display: this.props.visible ? "block" : "none" }, className: this.props.className @@ -978,6 +1023,7 @@ define(function (require, exports, module) { }), contents = directoryContents({ isRoot: true, + depth: 1, parentPath: this.props.parentPath, sortDirectoriesFirst: this.props.sortDirectoriesFirst, contents: this.props.treeData, diff --git a/src/project/FileTreeViewModel.js b/src/project/FileTreeViewModel.js index e41367f1223..78f4619f36c 100644 --- a/src/project/FileTreeViewModel.js +++ b/src/project/FileTreeViewModel.js @@ -21,7 +21,6 @@ * */ -/*global define */ /*unittests: FileTreeViewModel*/ /** diff --git a/src/project/FileViewController.js b/src/project/FileViewController.js index 5308f95d081..e8079a0ebd5 100644 --- a/src/project/FileViewController.js +++ b/src/project/FileViewController.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, event */ - /** * Responsible for coordinating file selection between views by permitting only one view * to show the current file selection at a time. Currently, only WorkingSetView and @@ -152,14 +149,14 @@ define(function (require, exports, module) { function _getDerivedPaneContext() { function _secondPaneContext() { - return (event.ctrlKey || event.metaKey) && event.altKey ? MainViewManager.SECOND_PANE : null; + return (window.event.ctrlKey || window.event.metaKey) && window.event.altKey ? MainViewManager.SECOND_PANE : null; } function _firstPaneContext() { - return (event.ctrlKey || event.metaKey) ? MainViewManager.FIRST_PANE : null; + return (window.event.ctrlKey || window.event.metaKey) ? MainViewManager.FIRST_PANE : null; } - return event && (_secondPaneContext() || _firstPaneContext()); + return window.event && (_secondPaneContext() || _firstPaneContext()); } if (fileSelectionFocus !== PROJECT_MANAGER && fileSelectionFocus !== WORKING_SET_VIEW) { diff --git a/src/project/ProjectManager.js b/src/project/ProjectManager.js index 9716eb91e24..c004385e200 100644 --- a/src/project/ProjectManager.js +++ b/src/project/ProjectManager.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, window */ - /** * ProjectManager glues together the project model and file tree view and integrates as needed with other parts * of Brackets. It is responsible for creating and updating the project tree when projects are opened @@ -741,7 +738,7 @@ define(function (require, exports, module) { FileSystem.on("change", _fileSystemChange); FileSystem.on("rename", _fileSystemRename); - FileSystem.watch(FileSystem.getDirectoryForPath(rootPath), ProjectModel._shouldShowName, function (err) { + FileSystem.watch(FileSystem.getDirectoryForPath(rootPath), ProjectModel._shouldShowName, ProjectModel.defaultIgnoreGlobs, function (err) { if (err === FileSystemError.TOO_MANY_ENTRIES) { if (!_projectWarnedForTooManyFiles) { _showErrorDialog(ERR_TYPE_MAX_FILES); @@ -1166,7 +1163,7 @@ define(function (require, exports, module) { */ function _setFileTreeSelectionWidth(width) { model.setSelectionWidth(width); - _renderTree(); + _renderTreeSync(); } // Initialize variables and listeners that depend on the HTML DOM diff --git a/src/project/ProjectModel.js b/src/project/ProjectModel.js index 95cf01647bc..809d175d73b 100644 --- a/src/project/ProjectModel.js +++ b/src/project/ProjectModel.js @@ -22,7 +22,6 @@ */ /* unittests: ProjectModel */ -/*global define, brackets, $ */ /** * Provides the data source for a project and manages the view model for the FileTreeView. @@ -57,7 +56,17 @@ define(function (require, exports, module) { * https://github.com/adobe/brackets/issues/6781 * @type {RegExp} */ - var _exclusionListRegEx = /\.pyc$|^\.git$|^\.gitmodules$|^\.svn$|^\.DS_Store$|^Thumbs\.db$|^\.hg$|^CVS$|^\.hgtags$|^\.idea$|^\.c9revisions$|^\.SyncArchive$|^\.SyncID$|^\.SyncIgnore$|\~$/; + var _exclusionListRegEx = /\.pyc$|^\.git$|^\.gitmodules$|^\.svn$|^\.DS_Store$|^Icon\r|^Thumbs\.db$|^\.hg$|^CVS$|^\.hgtags$|^\.idea$|^\.c9revisions$|^\.SyncArchive$|^\.SyncID$|^\.SyncIgnore$|\~$/; + + /** + * Glob definition of files and folders that should be excluded directly + * inside node domain watching with chokidar + */ + var defaultIgnoreGlobs = [ + "**/(.pyc|.git|.gitmodules|.svn|.DS_Store|Thumbs.db|.hg|CVS|.hgtags|.idea|.c9revisions|.SyncArchive|.SyncID|.SyncIgnore)", + "**/bower_components", + "**/node_modules" + ]; /** * @private @@ -89,8 +98,10 @@ define(function (require, exports, module) { // Validate file name // Checks for valid Windows filenames: // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx - return !((filename.search(new RegExp("[" + invalidChars + "]+")) !== -1) || - filename.match(_illegalFilenamesRegEx)); + return !( + new RegExp("[" + invalidChars + "]+").test(filename) || + _illegalFilenamesRegEx.test(filename) + ); } /** @@ -98,7 +109,7 @@ define(function (require, exports, module) { * @see #shouldShow */ function _shouldShowName(name) { - return !name.match(_exclusionListRegEx); + return !_exclusionListRegEx.test(name); } /** @@ -883,22 +894,23 @@ define(function (require, exports, module) { * Rename a file/folder. This will update the project tree data structures * and send notifications about the rename. * - * @param {string} oldName Old item name - * @param {string} newName New item name + * @param {string} oldPath Old name of the item with the path + * @param {string} newPath New name of the item with the path + * @param {string} newName New name of the item * @param {boolean} isFolder True if item is a folder; False if it is a file. * @return {$.Promise} A promise object that will be resolved or rejected when * the rename is finished. */ - function _renameItem(oldName, newName, isFolder) { + function _renameItem(oldPath, newPath, newName, isFolder) { var result = new $.Deferred(); - if (oldName === newName) { + if (oldPath === newPath) { result.resolve(); - } else if (!isValidFilename(FileUtils.getBaseName(newName), _invalidChars)) { + } else if (!isValidFilename(newName, _invalidChars)) { result.reject(ERROR_INVALID_FILENAME); } else { - var entry = isFolder ? FileSystem.getDirectoryForPath(oldName) : FileSystem.getFileForPath(oldName); - entry.rename(newName, function (err) { + var entry = isFolder ? FileSystem.getDirectoryForPath(oldPath) : FileSystem.getFileForPath(oldPath); + entry.rename(newPath, function (err) { if (err) { result.reject(err); } else { @@ -916,10 +928,11 @@ define(function (require, exports, module) { * Renames the item at the old path to the new name provided. * * @param {string} oldPath full path to the current location of file or directory (should include trailing slash for directory) + * @param {string} newPath full path to the new location of the file or directory * @param {string} newName new name for the file or directory */ - ProjectModel.prototype._renameItem = function (oldPath, newName) { - return _renameItem(oldPath, newName, !_pathIsFile(oldPath)); + ProjectModel.prototype._renameItem = function (oldPath, newPath, newName) { + return _renameItem(oldPath, newPath, newName, !_pathIsFile(oldPath)); }; /** @@ -974,7 +987,7 @@ define(function (require, exports, module) { renameInfo.deferred.reject(error); }); } else { - this._renameItem(oldPath, newPath).then(function () { + this._renameItem(oldPath, newPath, newName).then(function () { finalizeRename(); renameInfo.deferred.resolve({ newPath: newPath @@ -1334,7 +1347,7 @@ define(function (require, exports, module) { // Init invalid characters string if (brackets.platform === "mac") { - _invalidChars = "?*|:"; + _invalidChars = "?*|:/"; } else if (brackets.platform === "linux") { _invalidChars = "?*|/"; } else { @@ -1349,6 +1362,7 @@ define(function (require, exports, module) { exports._invalidChars = _invalidChars; exports.shouldShow = shouldShow; + exports.defaultIgnoreGlobs = defaultIgnoreGlobs; exports.isValidFilename = isValidFilename; exports.EVENT_CHANGE = EVENT_CHANGE; exports.EVENT_SHOULD_SELECT = EVENT_SHOULD_SELECT; diff --git a/src/project/SidebarView.js b/src/project/SidebarView.js index babe18c287f..f018f4bdd78 100644 --- a/src/project/SidebarView.js +++ b/src/project/SidebarView.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * The view that controls the showing and hiding of the sidebar. * @@ -190,14 +186,6 @@ define(function (require, exports, module) { $projectFilesContainer = $sidebar.find("#project-files-container"); $workingSetViewsContainer = $sidebar.find("#working-set-list-container"); - function _resizeSidebarSelection() { - var $element; - $sidebar.find(".sidebar-selection").each(function (index, element) { - $element = $(element); - $element.width($element.parent()[0].scrollWidth); - }); - } - // init $sidebar.on("panelResizeStart", function (evt, width) { $sidebar.find(".sidebar-selection-extension").css("display", "none"); @@ -205,12 +193,10 @@ define(function (require, exports, module) { }); $sidebar.on("panelResizeUpdate", function (evt, width) { - $sidebar.find(".sidebar-selection").width(width); ProjectManager._setFileTreeSelectionWidth(width); }); $sidebar.on("panelResizeEnd", function (evt, width) { - _resizeSidebarSelection(); $sidebar.find(".sidebar-selection-extension").css("display", "block").css("left", width); $sidebar.find(".scroller-shadow").css("display", "block"); $projectFilesContainer.triggerHandler("scroll"); @@ -223,7 +209,6 @@ define(function (require, exports, module) { $sidebar.on("panelExpanded", function (evt, width) { WorkingSetView.refresh(); - _resizeSidebarSelection(); $sidebar.find(".scroller-shadow").css("display", "block"); $sidebar.find(".sidebar-selection-extension").css("left", width); $projectFilesContainer.triggerHandler("scroll"); diff --git a/src/project/WorkingSetSort.js b/src/project/WorkingSetSort.js index 83a9be1a10b..a654c31af3d 100644 --- a/src/project/WorkingSetSort.js +++ b/src/project/WorkingSetSort.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Manages the workingSetList sort methods. */ diff --git a/src/project/WorkingSetView.js b/src/project/WorkingSetView.js index 0780182099b..0efc0fccb6d 100644 --- a/src/project/WorkingSetView.js +++ b/src/project/WorkingSetView.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window, brackets */ - /** * WorkingSetView generates the UI for the list of the files user is editing based on the model provided by EditorManager. * The UI allows the user to see what files are open/dirty and allows them to close files and specify the current editor. diff --git a/src/search/FileFilters.js b/src/search/FileFilters.js index ab1d508426a..9ff936068ef 100644 --- a/src/search/FileFilters.js +++ b/src/search/FileFilters.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, window */ - /** * Utilities for managing file-set filters, as used in Find in Files. * Includes both UI for selecting/editing filters, as well as the actual file-filtering implementation. diff --git a/src/search/FindBar.js b/src/search/FindBar.js index ecf8b1db9e4..c96d5c357f9 100644 --- a/src/search/FindBar.js +++ b/src/search/FindBar.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /* * UI for the Find/Replace and Find in Files modal bar. */ diff --git a/src/search/FindInFiles.js b/src/search/FindInFiles.js index 3a38d24160d..9e416b8fe17 100644 --- a/src/search/FindInFiles.js +++ b/src/search/FindInFiles.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /* * The core search functionality used by Find in Files and single-file Replace Batch. */ @@ -96,7 +93,19 @@ define(function (require, exports, module) { } function nodeFileCacheComplete(event, numFiles, cacheSize) { - var projectName = ProjectManager.getProjectRoot().name || "noName00"; + if (/\/test\/SpecRunner\.html$/.test(window.location.pathname)) { + // Ignore the event in the SpecRunner window + return; + } + + var projectRoot = ProjectManager.getProjectRoot(), + projectName = projectRoot ? projectRoot.name : null; + + if (!projectName) { + console.error("'File cache complete' event received, but no project root found"); + projectName = "noName00"; + } + FindUtils.setInstantSearchDisabled(false); // Node search could be disabled if some error has happened in node. But upon // project change, if we get this message, then it means that node search is working, @@ -649,7 +658,7 @@ define(function (require, exports, module) { * @param {array} fileList The list of files that changed. */ function filesChanged(fileList) { - if (FindUtils.isNodeSearchDisabled()) { + if (FindUtils.isNodeSearchDisabled() || fileList.length === 0) { return; } var updateObject = { @@ -795,7 +804,7 @@ define(function (require, exports, module) { var addPromise; if (entry.isDirectory) { - if (!added || !removed) { + if (!added || !removed || (added.length === 0 && removed.length === 0)) { // If the added or removed sets are null, must redo the search for the entire subtree - we // don't know which child files/folders may have been added or removed. _removeSearchResultsForEntry(entry); diff --git a/src/search/FindInFilesUI.js b/src/search/FindInFilesUI.js index a8a7e8e4dcb..51a42e82055 100644 --- a/src/search/FindInFilesUI.js +++ b/src/search/FindInFilesUI.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /* * UI and controller logic for find/replace across multiple files within the project. * diff --git a/src/search/FindReplace.js b/src/search/FindReplace.js index 435bab79ae2..5426a2be839 100644 --- a/src/search/FindReplace.js +++ b/src/search/FindReplace.js @@ -21,11 +21,8 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ /*unittests: FindReplace*/ - /** * Adds Find and Replace commands * @@ -94,24 +91,19 @@ define(function (require, exports, module) { findBar.showError(null); } - if (!queryInfo || !queryInfo.query) { + var parsed = FindUtils.parseQueryInfo(queryInfo); + if (parsed.empty === true) { return ""; } - // Is it a (non-blank) regex? - if (queryInfo.isRegexp) { - try { - return new RegExp(queryInfo.query, queryInfo.isCaseSensitive ? "" : "i"); - } catch (e) { - if (findBar) { - findBar.showError(e.message); - } - return ""; + if (!parsed.valid) { + if (findBar) { + findBar.showError(parsed.error); } - - } else { - return queryInfo.query; + return ""; } + + return parsed.queryExpr; } /** diff --git a/src/search/FindUtils.js b/src/search/FindUtils.js index d56b69768fa..38d8eac7594 100644 --- a/src/search/FindUtils.js +++ b/src/search/FindUtils.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - define(function (require, exports, module) { "use strict"; @@ -311,8 +308,6 @@ define(function (require, exports, module) { function parseQueryInfo(queryInfo) { var queryExpr; - // TODO: only major difference between this one and the one in FindReplace is that - // this always returns a regexp even for simple strings. Reconcile. if (!queryInfo || !queryInfo.query) { return {empty: true}; } diff --git a/src/search/QuickOpen.js b/src/search/QuickOpen.js index 4256cdd1784..4b1aee9b0da 100644 --- a/src/search/QuickOpen.js +++ b/src/search/QuickOpen.js @@ -21,8 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ /*unittests: QuickOpen*/ /* diff --git a/src/search/QuickOpenHelper.js b/src/search/QuickOpenHelper.js index 8e78db8ce0a..f411dd4ccd9 100644 --- a/src/search/QuickOpenHelper.js +++ b/src/search/QuickOpenHelper.js @@ -21,11 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - - - define(function (require, exports, module) { "use strict"; diff --git a/src/search/QuickSearchField.js b/src/search/QuickSearchField.js index 02081922a05..02a33e3c3a0 100644 --- a/src/search/QuickSearchField.js +++ b/src/search/QuickSearchField.js @@ -21,10 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, setTimeout */ - - /* * Text field with attached dropdown list that is updated (based on a provider) whenever the text changes. * diff --git a/src/search/ScrollTrackMarkers.js b/src/search/ScrollTrackMarkers.js index 94bd9a5461d..dc44ed4f288 100644 --- a/src/search/ScrollTrackMarkers.js +++ b/src/search/ScrollTrackMarkers.js @@ -21,10 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets */ - - /** * Manages tickmarks shown along the scrollbar track. * NOT yet intended for use by anyone other than the FindReplace module. @@ -67,8 +63,43 @@ define(function (require, exports, module) { * @type {?jQueryObject} */ var $markedTickmark; + + /** + * Vertical space above and below the scrollbar + * @type {number} + */ + var scrollbarTrackOffset; + + switch (brackets.platform) { + case "win": // Custom scrollbar CSS has no gap around the track + scrollbarTrackOffset = 0; + break; + case "mac": // Native scrollbar has padding around the track + scrollbarTrackOffset = 4; + break; + case "linux": // Custom scrollbar CSS has assymmetrical gap; this approximates it + scrollbarTrackOffset = 2; + break; + } + /** + * Vertical space above and below the scrollbar. + * @return {number} amount Value in pixels + */ + function getScrollbarTrackOffset() { + return scrollbarTrackOffset; + } + /** + * Sets how much vertical space there's above and below the scrollbar, which depends + * on the OS and may also be affected by extensions + * @param {number} offset Value in pixels + */ + function setScrollbarTrackOffset(offset) { + scrollbarTrackOffset = offset; + } + + function _getScrollbar(editor) { // Be sure to select only the direct descendant, not also elements within nested inline editors return $(editor.getRootElement()).children(".CodeMirror-vscrollbar"); @@ -81,16 +112,8 @@ define(function (require, exports, module) { trackHt = $sb[0].offsetHeight; if (trackHt > 0) { - // Scrollbar visible: determine offset of track from top of scrollbar - if (brackets.platform === "win") { - trackOffset = 0; // Custom scrollbar CSS has no gap around the track - } else if (brackets.platform === "mac") { - trackOffset = 4; // Native scrollbar has padding around the track - } else { //(Linux) - trackOffset = 2; // Custom scrollbar CSS has assymmetrical gap; this approximates it - } + trackOffset = getScrollbarTrackOffset(); trackHt -= trackOffset * 2; - } else { // No scrollbar: use the height of the entire code content var codeContainer = $(editor.getRootElement()).find("> .CodeMirror-scroll > .CodeMirror-sizer > div > .CodeMirror-lines > div")[0]; @@ -101,9 +124,31 @@ define(function (require, exports, module) { /** Add all the given tickmarks to the DOM in a batch */ function _renderMarks(posArray) { - var html = ""; + var html = "", + cm = editor._codeMirror, + editorHt = cm.getScrollerElement().scrollHeight; + + // We've pretty much taken these vars and the getY function from CodeMirror's annotatescrollbar addon + // https://github.com/codemirror/CodeMirror/blob/master/addon/scroll/annotatescrollbar.js + var wrapping = cm.getOption("lineWrapping"), + singleLineH = wrapping && cm.defaultTextHeight() * 1.5, + curLine = null, + curLineObj = null; + + function getY(cm, pos) { + if (curLine !== pos.line) { + curLine = pos.line; + curLineObj = cm.getLineHandle(curLine); + } + if (wrapping && curLineObj.height > singleLineH) { + return cm.charCoords(pos, "local").top; + } + return cm.heightAtLine(curLineObj, "local"); + } + posArray.forEach(function (pos) { - var top = Math.round(pos.line / editor.lineCount() * trackHt) + trackOffset; + var cursorTop = getY(cm, pos), + top = Math.round(cursorTop / editorHt * trackHt) + trackOffset; top--; // subtract ~1/2 the ht of a tickmark to center it on ideal pos html += "
    "; @@ -140,8 +185,8 @@ define(function (require, exports, module) { return; } - var $sb = _getScrollbar(editor); - var $overlay = $("
    "); + var $sb = _getScrollbar(editor), + $overlay = $("
    "); $sb.parent().append($overlay); _calcScaling(); @@ -201,4 +246,7 @@ define(function (require, exports, module) { exports.setVisible = setVisible; exports.addTickmarks = addTickmarks; exports.markCurrent = markCurrent; + + exports.getScrollbarTrackOffset = getScrollbarTrackOffset; + exports.setScrollbarTrackOffset = setScrollbarTrackOffset; }); diff --git a/src/search/SearchModel.js b/src/search/SearchModel.js index 9f656ce6ea7..3e90e7affd6 100644 --- a/src/search/SearchModel.js +++ b/src/search/SearchModel.js @@ -21,8 +21,6 @@ * */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/search/SearchResultsView.js b/src/search/SearchResultsView.js index 415fe6bc101..8bf172af846 100644 --- a/src/search/SearchResultsView.js +++ b/src/search/SearchResultsView.js @@ -21,8 +21,6 @@ * */ -/*global define, $, window */ - /* * Panel showing search results for a Find/Replace in Files operation. */ diff --git a/src/search/node/FindInFilesDomain.js b/src/search/node/FindInFilesDomain.js index 86ea3b1e93c..0d6e59bd9bb 100644 --- a/src/search/node/FindInFilesDomain.js +++ b/src/search/node/FindInFilesDomain.js @@ -21,669 +21,665 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, -maxerr: 50, node: true */ -/*global setImmediate*/ - -(function () { - "use strict"; - - var fs = require("fs"), - projectCache = [], - files, - _domainManager, - MAX_FILE_SIZE_TO_INDEX = 16777216, //16MB - MAX_DISPLAY_LENGTH = 200, - MAX_TOTAL_RESULTS = 100000, // only 100,000 search results are supported - MAX_RESULTS_IN_A_FILE = MAX_TOTAL_RESULTS, - MAX_RESULTS_TO_RETURN = 120; - - var results = {}, - numMatches = 0, - numFiles = 0, - evaluatedMatches, - foundMaximum = false, - exceedsMaximum = false, - currentCrawlIndex = 0, - savedSearchObject = null, - lastSearchedIndex = 0, - crawlComplete = false, - crawlEventSent = false, - collapseResults = false, - cacheSize = 0; - - /** - * Copied from StringUtils.js - * Returns a line number corresponding to an offset in some text. The text can - * be specified as a single string or as an array of strings that correspond to - * the lines of the string. - * - * Specify the text in lines when repeatedly calling the function on the same - * text in a loop. Use getLines() to divide the text into lines, then repeatedly call - * this function to compute a line number from the offset. - * - * @param {string | Array.} textOrLines - string or array of lines from which - * to compute the line number from the offset - * @param {number} offset - * @return {number} line number - */ - function offsetToLineNum(textOrLines, offset) { - if (Array.isArray(textOrLines)) { - var lines = textOrLines, - total = 0, - line; - for (line = 0; line < lines.length; line++) { - if (total < offset) { - // add 1 per line since /n were removed by splitting, but they needed to - // contribute to the total offset count - total += lines[line].length + 1; - } else if (total === offset) { - return line; - } else { - return line - 1; - } - } - - // if offset is NOT over the total then offset is in the last line - if (offset <= total) { - return line - 1; +/*eslint-env node */ +/*jslint node: true */ +/*global setImmediate */ +"use strict"; + +var fs = require("fs"), + projectCache = [], + files, + _domainManager, + MAX_FILE_SIZE_TO_INDEX = 16777216, //16MB + MAX_DISPLAY_LENGTH = 200, + MAX_TOTAL_RESULTS = 100000, // only 100,000 search results are supported + MAX_RESULTS_IN_A_FILE = MAX_TOTAL_RESULTS, + MAX_RESULTS_TO_RETURN = 120; + +var results = {}, + numMatches = 0, + numFiles = 0, + evaluatedMatches, + foundMaximum = false, + exceedsMaximum = false, + currentCrawlIndex = 0, + savedSearchObject = null, + lastSearchedIndex = 0, + crawlComplete = false, + crawlEventSent = false, + collapseResults = false, + cacheSize = 0; + +/** + * Copied from StringUtils.js + * Returns a line number corresponding to an offset in some text. The text can + * be specified as a single string or as an array of strings that correspond to + * the lines of the string. + * + * Specify the text in lines when repeatedly calling the function on the same + * text in a loop. Use getLines() to divide the text into lines, then repeatedly call + * this function to compute a line number from the offset. + * + * @param {string | Array.} textOrLines - string or array of lines from which + * to compute the line number from the offset + * @param {number} offset + * @return {number} line number + */ +function offsetToLineNum(textOrLines, offset) { + if (Array.isArray(textOrLines)) { + var lines = textOrLines, + total = 0, + line; + for (line = 0; line < lines.length; line++) { + if (total < offset) { + // add 1 per line since /n were removed by splitting, but they needed to + // contribute to the total offset count + total += lines[line].length + 1; + } else if (total === offset) { + return line; } else { - return undefined; + return line - 1; } + } + + // if offset is NOT over the total then offset is in the last line + if (offset <= total) { + return line - 1; } else { - return textOrLines.substr(0, offset).split("\n").length - 1; + return undefined; } + } else { + return textOrLines.substr(0, offset).split("\n").length - 1; } +} - /** - * Searches through the contents and returns an array of matches - * @param {string} contents - * @param {RegExp} queryExpr - * @return {!Array.<{start: {line:number,ch:number}, end: {line:number,ch:number}, line: string}>} - */ - function getSearchMatches(contents, queryExpr) { - if (!contents) { - return; - } - // Quick exit if not found or if we hit the limit - if (foundMaximum || contents.search(queryExpr) === -1) { - return []; +/** + * Searches through the contents and returns an array of matches + * @param {string} contents + * @param {RegExp} queryExpr + * @return {!Array.<{start: {line:number,ch:number}, end: {line:number,ch:number}, line: string}>} + */ +function getSearchMatches(contents, queryExpr) { + if (!contents) { + return; + } + // Quick exit if not found or if we hit the limit + if (foundMaximum || contents.search(queryExpr) === -1) { + return []; + } + + var match, lineNum, line, ch, totalMatchLength, matchedLines, numMatchedLines, lastLineLength, endCh, + padding, leftPadding, rightPadding, highlightOffset, highlightEndCh, + lines = contents.split("\n"), + matches = []; + + while ((match = queryExpr.exec(contents)) !== null) { + lineNum = offsetToLineNum(lines, match.index); + line = lines[lineNum]; + ch = match.index - contents.lastIndexOf("\n", match.index) - 1; // 0-based index + matchedLines = match[0].split("\n"); + numMatchedLines = matchedLines.length; + totalMatchLength = match[0].length; + lastLineLength = matchedLines[matchedLines.length - 1].length; + endCh = (numMatchedLines === 1 ? ch + totalMatchLength : lastLineLength); + highlightEndCh = (numMatchedLines === 1 ? endCh : line.length); + highlightOffset = 0; + + if (highlightEndCh <= MAX_DISPLAY_LENGTH) { + // Don't store more than 200 chars per line + line = line.substr(0, Math.min(MAX_DISPLAY_LENGTH, line.length)); + } else if (totalMatchLength > MAX_DISPLAY_LENGTH) { + // impossible to display the whole match + line = line.substr(ch, ch + MAX_DISPLAY_LENGTH); + highlightOffset = ch; + } else { + // Try to have both beginning and end of match displayed + padding = MAX_DISPLAY_LENGTH - totalMatchLength; + rightPadding = Math.floor(Math.min(padding / 2, line.length - highlightEndCh)); + leftPadding = Math.ceil(padding - rightPadding); + highlightOffset = ch - leftPadding; + line = line.substring(highlightOffset, highlightEndCh + rightPadding); + } + + matches.push({ + start: {line: lineNum, ch: ch}, + end: {line: lineNum + numMatchedLines - 1, ch: endCh}, + + highlightOffset: highlightOffset, + + // Note that the following offsets from the beginning of the file are *not* updated if the search + // results change. These are currently only used for multi-file replacement, and we always + // abort the replace (by shutting the results panel) if we detect any result changes, so we don't + // need to keep them up to date. Eventually, we should either get rid of the need for these (by + // doing everything in terms of line/ch offsets, though that will require re-splitting files when + // doing a replace) or properly update them. + startOffset: match.index, + endOffset: match.index + totalMatchLength, + + line: line, + result: match, + isChecked: true + }); + + // We have the max hits in just this 1 file. Stop searching this file. + // This fixed issue #1829 where code hangs on too many hits. + // Adds one over MAX_RESULTS_IN_A_FILE in order to know if the search has exceeded + // or is equal to MAX_RESULTS_IN_A_FILE. Additional result removed in SearchModel + if (matches.length > MAX_RESULTS_IN_A_FILE) { + queryExpr.lastIndex = 0; + break; + } + + // Pathological regexps like /^/ return 0-length matches. Ensure we make progress anyway + if (totalMatchLength === 0) { + queryExpr.lastIndex++; } + } - var match, lineNum, line, ch, totalMatchLength, matchedLines, numMatchedLines, lastLineLength, endCh, - padding, leftPadding, rightPadding, highlightOffset, highlightEndCh, - lines = contents.split("\n"), - matches = []; - - while ((match = queryExpr.exec(contents)) !== null) { - lineNum = offsetToLineNum(lines, match.index); - line = lines[lineNum]; - ch = match.index - contents.lastIndexOf("\n", match.index) - 1; // 0-based index - matchedLines = match[0].split("\n"); - numMatchedLines = matchedLines.length; - totalMatchLength = match[0].length; - lastLineLength = matchedLines[matchedLines.length - 1].length; - endCh = (numMatchedLines === 1 ? ch + totalMatchLength : lastLineLength); - highlightEndCh = (numMatchedLines === 1 ? endCh : line.length); - highlightOffset = 0; - - if (highlightEndCh <= MAX_DISPLAY_LENGTH) { - // Don't store more than 200 chars per line - line = line.substr(0, Math.min(MAX_DISPLAY_LENGTH, line.length)); - } else if (totalMatchLength > MAX_DISPLAY_LENGTH) { - // impossible to display the whole match - line = line.substr(ch, ch + MAX_DISPLAY_LENGTH); - highlightOffset = ch; - } else { - // Try to have both beginning and end of match displayed - padding = MAX_DISPLAY_LENGTH - totalMatchLength; - rightPadding = Math.floor(Math.min(padding / 2, line.length - highlightEndCh)); - leftPadding = Math.ceil(padding - rightPadding); - highlightOffset = ch - leftPadding; - line = line.substring(highlightOffset, highlightEndCh + rightPadding); - } + return matches; +} - matches.push({ - start: {line: lineNum, ch: ch}, - end: {line: lineNum + numMatchedLines - 1, ch: endCh}, - - highlightOffset: highlightOffset, - - // Note that the following offsets from the beginning of the file are *not* updated if the search - // results change. These are currently only used for multi-file replacement, and we always - // abort the replace (by shutting the results panel) if we detect any result changes, so we don't - // need to keep them up to date. Eventually, we should either get rid of the need for these (by - // doing everything in terms of line/ch offsets, though that will require re-splitting files when - // doing a replace) or properly update them. - startOffset: match.index, - endOffset: match.index + totalMatchLength, - - line: line, - result: match, - isChecked: true - }); - - // We have the max hits in just this 1 file. Stop searching this file. - // This fixed issue #1829 where code hangs on too many hits. - // Adds one over MAX_RESULTS_IN_A_FILE in order to know if the search has exceeded - // or is equal to MAX_RESULTS_IN_A_FILE. Additional result removed in SearchModel - if (matches.length > MAX_RESULTS_IN_A_FILE) { - queryExpr.lastIndex = 0; - break; - } +/** + * Clears the cached file contents of the project + */ +function clearProjectCache() { + projectCache = []; +} - // Pathological regexps like /^/ return 0-length matches. Ensure we make progress anyway - if (totalMatchLength === 0) { - queryExpr.lastIndex++; - } - } - return matches; +/** + * Gets the file size in bytes. + * @param {string} fileName The name of the file to get the size + * @returns {Number} the file size in bytes + */ +function getFilesizeInBytes(fileName) { + try { + var stats = fs.statSync(fileName); + return stats.size || 0; + } catch (ex) { + console.log(ex); + return 0; } +} - /** - * Clears the cached file contents of the project - */ - function clearProjectCache() { - projectCache = []; +/** + * Get the contents of a file from cache given the path. Also adds the file contents to cache from disk if not cached. + * Will not read/cache files greater than MAX_FILE_SIZE_TO_INDEX in size. + * @param {string} filePath full file path + * @return {string} contents or null if no contents + */ +function getFileContentsForFile(filePath) { + if (projectCache[filePath] || projectCache[filePath] === "") { + return projectCache[filePath]; } - - - /** - * Gets the file size in bytes. - * @param {string} fileName The name of the file to get the size - * @returns {Number} the file size in bytes - */ - function getFilesizeInBytes(fileName) { - try { - var stats = fs.statSync(fileName); - return stats.size || 0; - } catch (ex) { - console.log(ex); - return 0; + try { + if (getFilesizeInBytes(filePath) <= MAX_FILE_SIZE_TO_INDEX) { + projectCache[filePath] = fs.readFileSync(filePath, 'utf8'); + } else { + projectCache[filePath] = ""; } + } catch (ex) { + console.log(ex); + projectCache[filePath] = null; } - - /** - * Get the contents of a file from cache given the path. Also adds the file contents to cache from disk if not cached. - * Will not read/cache files greater than MAX_FILE_SIZE_TO_INDEX in size. - * @param {string} filePath full file path - * @return {string} contents or null if no contents - */ - function getFileContentsForFile(filePath) { - if (projectCache[filePath] || projectCache[filePath] === "") { - return projectCache[filePath]; - } - try { - if (getFilesizeInBytes(filePath) <= MAX_FILE_SIZE_TO_INDEX) { - projectCache[filePath] = fs.readFileSync(filePath, 'utf8'); - } else { - projectCache[filePath] = ""; - } - } catch (ex) { - console.log(ex); - projectCache[filePath] = null; - } - return projectCache[filePath]; + return projectCache[filePath]; +} + +/** + * Sets the list of matches for the given path, removing the previous match info, if any, and updating + * the total match count. Note that for the count to remain accurate, the previous match info must not have + * been mutated since it was set. + * @param {string} fullpath Full path to the file containing the matches. + * @param {!{matches: Object, collapsed: boolean=}} resultInfo Info for the matches to set: + * matches - Array of matches, in the format returned by FindInFiles.getSearchMatches() + * collapsed - Optional: whether the results should be collapsed in the UI (default false). + */ +function setResults(fullpath, resultInfo, maxResultsToReturn) { + if (results[fullpath]) { + numMatches -= results[fullpath].matches.length; + delete results[fullpath]; } - /** - * Sets the list of matches for the given path, removing the previous match info, if any, and updating - * the total match count. Note that for the count to remain accurate, the previous match info must not have - * been mutated since it was set. - * @param {string} fullpath Full path to the file containing the matches. - * @param {!{matches: Object, collapsed: boolean=}} resultInfo Info for the matches to set: - * matches - Array of matches, in the format returned by FindInFiles.getSearchMatches() - * collapsed - Optional: whether the results should be collapsed in the UI (default false). - */ - function setResults(fullpath, resultInfo, maxResultsToReturn) { - if (results[fullpath]) { - numMatches -= results[fullpath].matches.length; - delete results[fullpath]; - } + if (foundMaximum || !resultInfo || !resultInfo.matches || !resultInfo.matches.length) { + return; + } - if (foundMaximum || !resultInfo || !resultInfo.matches || !resultInfo.matches.length) { - return; - } + // Make sure that the optional `collapsed` property is explicitly set to either true or false, + // to avoid logic issues later with comparing values. + resultInfo.collapsed = collapseResults; - // Make sure that the optional `collapsed` property is explicitly set to either true or false, - // to avoid logic issues later with comparing values. - resultInfo.collapsed = collapseResults; + results[fullpath] = resultInfo; + numMatches += resultInfo.matches.length; + evaluatedMatches += resultInfo.matches.length; + maxResultsToReturn = maxResultsToReturn || MAX_RESULTS_TO_RETURN; + if (numMatches >= maxResultsToReturn || evaluatedMatches > MAX_TOTAL_RESULTS) { + foundMaximum = true; + } +} + +/** + * Finds search results in the given file and adds them to 'results' + * @param {string} filepath + * @param {string} text contents of the file + * @param {Object} queryExpr + * @param {number} maxResultsToReturn the maximum of results that should be returned in the current search. + */ +function doSearchInOneFile(filepath, text, queryExpr, maxResultsToReturn) { + var matches = getSearchMatches(text, queryExpr); + setResults(filepath, {matches: matches}, maxResultsToReturn); +} + +/** + * Search in the list of files given and populate the results + * @param {array} fileList array of file paths + * @param {Object} queryExpr + * @param {number} startFileIndex the start index of the array from which the search has to be done + * @param {number} maxResultsToReturn the maximum number of results to return in this search + */ +function doSearchInFiles(fileList, queryExpr, startFileIndex, maxResultsToReturn) { + var i; + if (fileList.length === 0) { + console.log('no files found'); + return; + + } else { + startFileIndex = startFileIndex || 0; + for (i = startFileIndex; i < fileList.length && !foundMaximum; i++) { + doSearchInOneFile(fileList[i], getFileContentsForFile(fileList[i]), queryExpr, maxResultsToReturn); + } + lastSearchedIndex = i; + } +} + +// Copied from StringUtils.js +function regexEscape(str) { + return str.replace(/([.?*+\^$\[\]\\(){}|\-])/g, "\\$1"); +} + +/** + * Parses the given query into a regexp, and returns whether it was valid or not. + * @param {{query: string, caseSensitive: boolean, isRegexp: boolean}} queryInfo + * @return {{queryExpr: RegExp, valid: boolean, empty: boolean, error: string}} + * queryExpr - the regexp representing the query + * valid - set to true if query is a nonempty string or a valid regexp. + * empty - set to true if query was empty. + * error - set to an error string if valid is false and query is nonempty. + */ +function parseQueryInfo(queryInfo) { + var queryExpr; - results[fullpath] = resultInfo; - numMatches += resultInfo.matches.length; - evaluatedMatches += resultInfo.matches.length; - maxResultsToReturn = maxResultsToReturn || MAX_RESULTS_TO_RETURN; - if (numMatches >= maxResultsToReturn || evaluatedMatches > MAX_TOTAL_RESULTS) { - foundMaximum = true; - } + // TODO: only major difference between this one and the one in FindReplace is that + // this always returns a regexp even for simple strings. Reconcile. + if (!queryInfo || !queryInfo.query) { + return {empty: true}; } - /** - * Finds search results in the given file and adds them to 'results' - * @param {string} filepath - * @param {string} text contents of the file - * @param {Object} queryExpr - * @param {number} maxResultsToReturn the maximum of results that should be returned in the current search. - */ - function doSearchInOneFile(filepath, text, queryExpr, maxResultsToReturn) { - var matches = getSearchMatches(text, queryExpr); - setResults(filepath, {matches: matches}, maxResultsToReturn); - } - - /** - * Search in the list of files given and populate the results - * @param {array} fileList array of file paths - * @param {Object} queryExpr - * @param {number} startFileIndex the start index of the array from which the search has to be done - * @param {number} maxResultsToReturn the maximum number of results to return in this search - */ - function doSearchInFiles(fileList, queryExpr, startFileIndex, maxResultsToReturn) { - var i; - if (fileList.length === 0) { - console.log('no files found'); - return; + // For now, treat all matches as multiline (i.e. ^/$ match on every line, not the whole + // document). This is consistent with how single-file find works. Eventually we should add + // an option for this. + var flags = "gm"; + if (!queryInfo.isCaseSensitive) { + flags += "i"; + } - } else { - startFileIndex = startFileIndex || 0; - for (i = startFileIndex; i < fileList.length && !foundMaximum; i++) { - doSearchInOneFile(fileList[i], getFileContentsForFile(fileList[i]), queryExpr, maxResultsToReturn); - } - lastSearchedIndex = i; + // Is it a (non-blank) regex? + if (queryInfo.isRegexp) { + try { + queryExpr = new RegExp(queryInfo.query, flags); + } catch (e) { + return {valid: false, error: e.message}; } + } else { + // Query is a plain string. Turn it into a regexp + queryExpr = new RegExp(regexEscape(queryInfo.query), flags); } + return {valid: true, queryExpr: queryExpr}; +} - // Copied from StringUtils.js - function regexEscape(str) { - return str.replace(/([.?*+\^$\[\]\\(){}|\-])/g, "\\$1"); +/** + * Crawls through the files in the project ans stores them in cache. Since that could take a while + * we do it in batches so that node wont be blocked. + */ +function fileCrawler() { + if (!files || (files && files.length === 0)) { + setTimeout(fileCrawler, 1000); + return; } - - /** - * Parses the given query into a regexp, and returns whether it was valid or not. - * @param {{query: string, caseSensitive: boolean, isRegexp: boolean}} queryInfo - * @return {{queryExpr: RegExp, valid: boolean, empty: boolean, error: string}} - * queryExpr - the regexp representing the query - * valid - set to true if query is a nonempty string or a valid regexp. - * empty - set to true if query was empty. - * error - set to an error string if valid is false and query is nonempty. - */ - function parseQueryInfo(queryInfo) { - var queryExpr; - - // TODO: only major difference between this one and the one in FindReplace is that - // this always returns a regexp even for simple strings. Reconcile. - if (!queryInfo || !queryInfo.query) { - return {empty: true}; + var contents = ""; + if (currentCrawlIndex < files.length) { + contents = getFileContentsForFile(files[currentCrawlIndex]); + if (contents) { + cacheSize += contents.length; } + currentCrawlIndex++; + } + if (currentCrawlIndex < files.length) { + crawlComplete = false; + setImmediate(fileCrawler); + } else { + crawlComplete = true; + if (!crawlEventSent) { + crawlEventSent = true; + _domainManager.emitEvent("FindInFiles", "crawlComplete", [files.length, cacheSize]); + } + setTimeout(fileCrawler, 1000); + } +} - // For now, treat all matches as multiline (i.e. ^/$ match on every line, not the whole - // document). This is consistent with how single-file find works. Eventually we should add - // an option for this. - var flags = "gm"; - if (!queryInfo.isCaseSensitive) { - flags += "i"; +/** + * Init for project, resets the old project cache, and sets the crawler function to + * restart the file crawl + * @param {array} fileList an array of files + */ +function initCache(fileList) { + files = fileList; + currentCrawlIndex = 0; + cacheSize = 0; + clearProjectCache(); + crawlEventSent = false; +} + +/** + * Counts the number of matches matching the queryExpr in the given contents + * @param {String} contents The contents to search on + * @param {Object} queryExpr + * @return {number} number of matches + */ +function countNumMatches(contents, queryExpr) { + if (!contents) { + return 0; + } + var matches = contents.match(queryExpr); + return matches ? matches.length : 0; +} + +/** + * Get the total number of matches from all the files in fileList + * @param {array} fileList file path array + * @param {Object} queryExpr + * @return {Number} total number of matches + */ +function getNumMatches(fileList, queryExpr) { + var i, + matches = 0; + for (i = 0; i < fileList.length; i++) { + var temp = countNumMatches(getFileContentsForFile(fileList[i]), queryExpr); + if (temp) { + numFiles++; + matches += temp; + } + if (matches > MAX_TOTAL_RESULTS) { + exceedsMaximum = true; + break; } + } + return matches; +} + +/** + * Do a search with the searchObject context and return the results + * @param {Object} searchObject + * @param {boolean} nextPages set to true if to indicate that next page of an existing page is being fetched + * @return {Object} search results + */ +function doSearch(searchObject, nextPages) { - // Is it a (non-blank) regex? - if (queryInfo.isRegexp) { - try { - queryExpr = new RegExp(queryInfo.query, flags); - } catch (e) { - return {valid: false, error: e.message}; - } - } else { - // Query is a plain string. Turn it into a regexp - queryExpr = new RegExp(regexEscape(queryInfo.query), flags); - } - return {valid: true, queryExpr: queryExpr}; + savedSearchObject = searchObject; + if (!files) { + console.log("no file object found"); + return {}; + } + results = {}; + numMatches = 0; + numFiles = 0; + foundMaximum = false; + if (!nextPages) { + exceedsMaximum = false; + evaluatedMatches = 0; + } + var queryObject = parseQueryInfo(searchObject.queryInfo); + if (searchObject.files) { + files = searchObject.files; + } + if (searchObject.getAllResults) { + searchObject.maxResultsToReturn = MAX_TOTAL_RESULTS; + } + doSearchInFiles(files, queryObject.queryExpr, searchObject.startFileIndex, searchObject.maxResultsToReturn); + if (crawlComplete && !nextPages) { + numMatches = getNumMatches(files, queryObject.queryExpr); + } + var send_object = { + "results": results, + "foundMaximum": foundMaximum, + "exceedsMaximum": exceedsMaximum + }; + + if (!nextPages) { + send_object.numMatches = numMatches; + send_object.numFiles = numFiles; } - /** - * Crawls through the files in the project ans stores them in cache. Since that could take a while - * we do it in batches so that node wont be blocked. - */ - function fileCrawler() { - if (!files || (files && files.length === 0)) { - setTimeout(fileCrawler, 1000); - return; - } - var contents = ""; - if (currentCrawlIndex < files.length) { - contents = getFileContentsForFile(files[currentCrawlIndex]); - if (contents) { - cacheSize += contents.length; - } - currentCrawlIndex++; - } - if (currentCrawlIndex < files.length) { - crawlComplete = false; - setImmediate(fileCrawler); - } else { - crawlComplete = true; - if (!crawlEventSent) { - crawlEventSent = true; - _domainManager.emitEvent("FindInFiles", "crawlComplete", [files.length, cacheSize]); - } - setTimeout(fileCrawler, 1000); - } + if (searchObject.getAllResults) { + send_object.allResultsAvailable = true; } + return send_object; +} - /** - * Init for project, resets the old project cache, and sets the crawler function to - * restart the file crawl - * @param {array} fileList an array of files - */ - function initCache(fileList) { - files = fileList; - currentCrawlIndex = 0; - cacheSize = 0; - clearProjectCache(); - crawlEventSent = false; - } - - /** - * Counts the number of matches matching the queryExpr in the given contents - * @param {String} contents The contents to search on - * @param {Object} queryExpr - * @return {number} number of matches - */ - function countNumMatches(contents, queryExpr) { - if (!contents) { - return 0; - } - var matches = contents.match(queryExpr); - return matches ? matches.length : 0; - } - - /** - * Get the total number of matches from all the files in fileList - * @param {array} fileList file path array - * @param {Object} queryExpr - * @return {Number} total number of matches - */ - function getNumMatches(fileList, queryExpr) { - var i, - matches = 0; - for (i = 0; i < fileList.length; i++) { - var temp = countNumMatches(getFileContentsForFile(fileList[i]), queryExpr); - if (temp) { - numFiles++; - matches += temp; - } - if (matches > MAX_TOTAL_RESULTS) { - exceedsMaximum = true; - break; - } - } - return matches; +/** + * Remove the list of given files from the project cache + * @param {Object} updateObject + */ +function removeFilesFromCache(updateObject) { + var fileList = updateObject.fileList || [], + filesInSearchScope = updateObject.filesInSearchScope || [], + i = 0; + for (i = 0; i < fileList.length; i++) { + delete projectCache[fileList[i]]; + } + function isNotInRemovedFilesList(path) { + return (filesInSearchScope.indexOf(path) === -1) ? true : false; } + files = files ? files.filter(isNotInRemovedFilesList) : files; +} - /** - * Do a search with the searchObject context and return the results - * @param {Object} searchObject - * @param {boolean} nextPages set to true if to indicate that next page of an existing page is being fetched - * @return {Object} search results - */ - function doSearch(searchObject, nextPages) { +/** + * Adds the list of given files to the project cache. However the files will not be + * read at this time. We just delete the project cache entry which will trigger a fetch on search. + * @param {Object} updateObject + */ +function addFilesToCache(updateObject) { + var fileList = updateObject.fileList || [], + filesInSearchScope = updateObject.filesInSearchScope || [], + i = 0, + changedFilesAlreadyInList = [], + newFiles = []; + for (i = 0; i < fileList.length; i++) { + // We just add a null entry indicating the precense of the file in the project list. + // The file will be later read when required. + projectCache[fileList[i]] = null; + } - savedSearchObject = searchObject; - if (!files) { - console.log("no file object found"); - return {}; - } - results = {}; - numMatches = 0; - numFiles = 0; - foundMaximum = false; - if (!nextPages) { - exceedsMaximum = false; - evaluatedMatches = 0; - } - var queryObject = parseQueryInfo(searchObject.queryInfo); - if (searchObject.files) { - files = searchObject.files; - } - if (searchObject.getAllResults) { - searchObject.maxResultsToReturn = MAX_TOTAL_RESULTS; - } - doSearchInFiles(files, queryObject.queryExpr, searchObject.startFileIndex, searchObject.maxResultsToReturn); - if (crawlComplete && !nextPages) { - numMatches = getNumMatches(files, queryObject.queryExpr); - } - var send_object = { - "results": results, - "foundMaximum": foundMaximum, - "exceedsMaximum": exceedsMaximum - }; - - if (!nextPages) { - send_object.numMatches = numMatches; - send_object.numFiles = numFiles; - } + //Now update the search scope + function isInChangedFileList(path) { + return (filesInSearchScope.indexOf(path) !== -1) ? true : false; + } + changedFilesAlreadyInList = files ? files.filter(isInChangedFileList) : []; + function isNotAlreadyInList(path) { + return (changedFilesAlreadyInList.indexOf(path) === -1) ? true : false; + } + newFiles = changedFilesAlreadyInList.filter(isNotAlreadyInList); + files.push.apply(files, newFiles); +} - if (searchObject.getAllResults) { - send_object.allResultsAvailable = true; - } +/** + * Notification function on document changed, we update the cache with the contents + * @param {Object} updateObject + */ +function documentChanged(updateObject) { + projectCache[updateObject.filePath] = updateObject.docContents; +} + +/** + * Gets the next page of results of the ongoing search + * @return {Object} search results + */ +function getNextPage() { + var send_object = { + "results": {}, + "numMatches": 0, + "foundMaximum": foundMaximum, + "exceedsMaximum": exceedsMaximum + }; + if (!savedSearchObject) { return send_object; } + savedSearchObject.startFileIndex = lastSearchedIndex; + return doSearch(savedSearchObject, true); +} - /** - * Remove the list of given files from the project cache - * @param {Object} updateObject - */ - function removeFilesFromCache(updateObject) { - var fileList = updateObject.fileList || [], - filesInSearchScope = updateObject.filesInSearchScope || [], - i = 0; - for (i = 0; i < fileList.length; i++) { - delete projectCache[fileList[i]]; - } - function isNotInRemovedFilesList(path) { - return (filesInSearchScope.indexOf(path) === -1) ? true : false; - } - files = files ? files.filter(isNotInRemovedFilesList) : files; - } - - /** - * Adds the list of given files to the project cache. However the files will not be - * read at this time. We just delete the project cache entry which will trigger a fetch on search. - * @param {Object} updateObject - */ - function addFilesToCache(updateObject) { - var fileList = updateObject.fileList || [], - filesInSearchScope = updateObject.filesInSearchScope || [], - i = 0, - changedFilesAlreadyInList = [], - newFiles = []; - for (i = 0; i < fileList.length; i++) { - // We just add a null entry indicating the precense of the file in the project list. - // The file will be later read when required. - projectCache[fileList[i]] = null; - } +/** + * Gets all the results for the saved search query if present or empty search results + * @return {Object} The results object + */ +function getAllResults() { + var send_object = { + "results": {}, + "numMatches": 0, + "foundMaximum": foundMaximum, + "exceedsMaximum": exceedsMaximum + }; + if (!savedSearchObject) { + return send_object; + } + savedSearchObject.startFileIndex = 0; + savedSearchObject.getAllResults = true; + return doSearch(savedSearchObject); +} + +/** + * Sets if the results should be collapsed + * @param {boolean} collapse true to collapse + */ +function setCollapseResults(collapse) { + collapseResults = collapse; +} - //Now update the search scope - function isInChangedFileList(path) { - return (filesInSearchScope.indexOf(path) !== -1) ? true : false; - } - changedFilesAlreadyInList = files ? files.filter(isInChangedFileList) : []; - function isNotAlreadyInList(path) { - return (changedFilesAlreadyInList.indexOf(path) === -1) ? true : false; - } - newFiles = changedFilesAlreadyInList.filter(isNotAlreadyInList); - files.push.apply(files, newFiles); - } - - /** - * Notification function on document changed, we update the cache with the contents - * @param {Object} updateObject - */ - function documentChanged(updateObject) { - projectCache[updateObject.filePath] = updateObject.docContents; - } - - /** - * Gets the next page of results of the ongoing search - * @return {Object} search results - */ - function getNextPage() { - var send_object = { - "results": {}, - "numMatches": 0, - "foundMaximum": foundMaximum, - "exceedsMaximum": exceedsMaximum - }; - if (!savedSearchObject) { - return send_object; - } - savedSearchObject.startFileIndex = lastSearchedIndex; - return doSearch(savedSearchObject, true); - } - - /** - * Gets all the results for the saved search query if present or empty search results - * @return {Object} The results object - */ - function getAllResults() { - var send_object = { - "results": {}, - "numMatches": 0, - "foundMaximum": foundMaximum, - "exceedsMaximum": exceedsMaximum - }; - if (!savedSearchObject) { - return send_object; - } - savedSearchObject.startFileIndex = 0; - savedSearchObject.getAllResults = true; - return doSearch(savedSearchObject); - } - - /** - * Sets if the results should be collapsed - * @param {boolean} collapse true to collapse - */ - function setCollapseResults(collapse) { - collapseResults = collapse; - } - - /** - * Initialize the test domain with commands and events related to find in files. - * @param {DomainManager} domainManager The DomainManager for the find in files domain "FindInFiles" - */ - function init(domainManager) { - if (!domainManager.hasDomain("FindInFiles")) { - domainManager.registerDomain("FindInFiles", {major: 0, minor: 1}); - } - _domainManager = domainManager; - domainManager.registerCommand( - "FindInFiles", // domain name - "doSearch", // command name - doSearch, // command handler function - false, // this command is synchronous in Node - "Searches in project files and returns matches", - [{name: "searchObject", // parameters - type: "object", - description: "Object containing search data"}], - [{name: "searchResults", // return values - type: "object", - description: "Object containing results of the search"}] - ); - domainManager.registerCommand( - "FindInFiles", // domain name - "nextPage", // command name - getNextPage, // command handler function - false, // this command is synchronous in Node - "get the next page of reults", - [], - [{name: "searchResults", // return values - type: "object", - description: "Object containing results of the search"}] - ); - domainManager.registerCommand( - "FindInFiles", // domain name - "getAllResults", // command name - getAllResults, // command handler function - false, // this command is synchronous in Node - "get the next page of reults", - [], - [{name: "searchResults", // return values - type: "object", - description: "Object containing all results of the search"}] - ); - domainManager.registerCommand( - "FindInFiles", // domain name - "collapseResults", // command name - setCollapseResults, // command handler function - false, // this command is synchronous in Node - "get the next page of reults", - [{name: "collapse", // return values - type: "boolean", - description: "true to collapse"}], - [] - ); - domainManager.registerCommand( - "FindInFiles", // domain name - "filesChanged", // command name - addFilesToCache, // command handler function - false, // this command is synchronous in Node - "files in the project has been changed, update cache", - [{name: "updateObject", // parameters - type: "object", - description: "Object containing list of changed files"}], - [] - ); - domainManager.registerCommand( - "FindInFiles", // domain name - "documentChanged", // command name - documentChanged, // command handler function - false, // this command is synchronous in Node - "informs that the document changed and updates the cache", - [{name: "updateObject", // parameters - type: "object", - description: "update with the contents of the object"}], - [] - ); - domainManager.registerCommand( - "FindInFiles", // domain name - "filesRemoved", // command name - removeFilesFromCache, // command handler function - false, // this command is synchronous in Node - "Searches in project files and returns matches", - [{name: "updateObject", // parameters - type: "object", - description: "Object containing list of removed files"}], - [] - ); - domainManager.registerCommand( - "FindInFiles", // domain name - "initCache", // command name - initCache, // command handler function - false, // this command is synchronous in Node - "Caches the project for find in files in node", - [{name: "fileList", // parameters - type: "Array", - description: "List of all project files - Path only"}], - [] - ); - domainManager.registerEvent( - "FindInFiles", // domain name - "crawlComplete", // event name - [ - { - name: "numFiles", - type: "number", - description: "number of files cached" - }, - { - name: "cacheSize", - type: "number", - description: "The size of the file cache epressesd as string length of files" - } - ] - ); - setTimeout(fileCrawler, 5000); - } - - exports.init = init; - -}()); +/** + * Initialize the test domain with commands and events related to find in files. + * @param {DomainManager} domainManager The DomainManager for the find in files domain "FindInFiles" + */ +function init(domainManager) { + if (!domainManager.hasDomain("FindInFiles")) { + domainManager.registerDomain("FindInFiles", {major: 0, minor: 1}); + } + _domainManager = domainManager; + domainManager.registerCommand( + "FindInFiles", // domain name + "doSearch", // command name + doSearch, // command handler function + false, // this command is synchronous in Node + "Searches in project files and returns matches", + [{name: "searchObject", // parameters + type: "object", + description: "Object containing search data"}], + [{name: "searchResults", // return values + type: "object", + description: "Object containing results of the search"}] + ); + domainManager.registerCommand( + "FindInFiles", // domain name + "nextPage", // command name + getNextPage, // command handler function + false, // this command is synchronous in Node + "get the next page of reults", + [], + [{name: "searchResults", // return values + type: "object", + description: "Object containing results of the search"}] + ); + domainManager.registerCommand( + "FindInFiles", // domain name + "getAllResults", // command name + getAllResults, // command handler function + false, // this command is synchronous in Node + "get the next page of reults", + [], + [{name: "searchResults", // return values + type: "object", + description: "Object containing all results of the search"}] + ); + domainManager.registerCommand( + "FindInFiles", // domain name + "collapseResults", // command name + setCollapseResults, // command handler function + false, // this command is synchronous in Node + "get the next page of reults", + [{name: "collapse", // return values + type: "boolean", + description: "true to collapse"}], + [] + ); + domainManager.registerCommand( + "FindInFiles", // domain name + "filesChanged", // command name + addFilesToCache, // command handler function + false, // this command is synchronous in Node + "files in the project has been changed, update cache", + [{name: "updateObject", // parameters + type: "object", + description: "Object containing list of changed files"}], + [] + ); + domainManager.registerCommand( + "FindInFiles", // domain name + "documentChanged", // command name + documentChanged, // command handler function + false, // this command is synchronous in Node + "informs that the document changed and updates the cache", + [{name: "updateObject", // parameters + type: "object", + description: "update with the contents of the object"}], + [] + ); + domainManager.registerCommand( + "FindInFiles", // domain name + "filesRemoved", // command name + removeFilesFromCache, // command handler function + false, // this command is synchronous in Node + "Searches in project files and returns matches", + [{name: "updateObject", // parameters + type: "object", + description: "Object containing list of removed files"}], + [] + ); + domainManager.registerCommand( + "FindInFiles", // domain name + "initCache", // command name + initCache, // command handler function + false, // this command is synchronous in Node + "Caches the project for find in files in node", + [{name: "fileList", // parameters + type: "Array", + description: "List of all project files - Path only"}], + [] + ); + domainManager.registerEvent( + "FindInFiles", // domain name + "crawlComplete", // event name + [ + { + name: "numFiles", + type: "number", + description: "number of files cached" + }, + { + name: "cacheSize", + type: "number", + description: "The size of the file cache epressesd as string length of files" + } + ] + ); + setTimeout(fileCrawler, 5000); +} + +exports.init = init; diff --git a/src/strings.js b/src/strings.js index 887a4967bb6..3bb386d8255 100644 --- a/src/strings.js +++ b/src/strings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global $, define, brackets, window */ - /** * This file provides the interface to user visible strings in Brackets. Code that needs * to display strings should should load this module by calling `var Strings = require("strings")`. diff --git a/src/styles/brackets.less b/src/styles/brackets.less index 9e89ef748e7..8dfad1edc4e 100644 --- a/src/styles/brackets.less +++ b/src/styles/brackets.less @@ -220,8 +220,8 @@ a, img { #status-language { border-right: 1px solid @bc-panel-border; - padding: 0px; - margin: 0px; + padding: 0; + margin: 0; .dark & { border-right: 1px solid @dark-bc-panel-separator; @@ -347,10 +347,10 @@ a, img { .image-view { overflow: hidden; position: absolute; - top: 0px; - right: 0px; - bottom: 0px; - left: 0px; + top: 0; + right: 0; + bottom: 0; + left: 0; text-align: center; .image-centering { display: inline-block; @@ -503,7 +503,7 @@ a, img { &-flipview-btn { position: relative; display: none; - top: 0px; + top: 0; padding-top: 2px; padding-right: 4px; padding-left: 4px; @@ -840,6 +840,7 @@ a, img { -webkit-transform: translateZ(0); // forces GPU mode for better filter rendering on retina transform: translateZ(0); // future proofing -webkit-filter: drop-shadow(0 1px 0 rgba(0,0,0,0.36)); + filter: drop-shadow(0 1px 0 rgba(0,0,0,0.36)); z-index: 1; } @@ -905,7 +906,7 @@ a, img { .open-files-container { .box-flex(0); - padding: 0px; + padding: 0; max-height: 200px; // TODO (Issue #276): it would be nicer to have this be 50%, but that doesn't seem to work @@ -967,6 +968,7 @@ a, img { border-bottom: 1px solid @bc-highlight; box-sizing: border-box; height: 23px; + width: 100%; position: absolute; } @@ -997,6 +999,7 @@ a, img { box-sizing: border-box; position: absolute; height: 23px; + width: 100%; } //Initially start with the open files hidden, they will get show as files are added @@ -1007,13 +1010,10 @@ a, img { #project-files-container { .box-flex(1); - ul { + div > ul { + padding-bottom: 24px; padding-left: 8px; } - - > ul { - padding-bottom: 24px; - } } .scroller-shadow { @@ -1022,6 +1022,7 @@ a, img { height: 5px; position: fixed; z-index: @z-index-brackets-scroller-shadow; + pointer-events: none; // serves as a "click through", so clicks go to the file tree behind (see #12684) &.top { #gradient > .vertical(rgba(0,0,0,0.1), rgba(0,0,0,0)); @@ -1059,22 +1060,30 @@ a, img { .jstree-brackets .jstree-no-dots .jstree-open > ins { background-position: 7px -8px; -webkit-transform: translateZ(0) rotate(90deg); - -webkit-transition: -webkit-transform 190ms cubic-bezier(.01, .91, 0, .99); + transform: translateZ(0) rotate(90deg); + transition: -webkit-transform 190ms cubic-bezier(.01, .91, 0, .99); + transition: transform 190ms cubic-bezier(.01, .91, 0, .99); -webkit-filter: drop-shadow(1px 0 1px @bc-shadow); + filter: drop-shadow(1px 0 1px @bc-shadow); .dark & { - -webkit-filter: drop-shadow(1px 0 1px @dark-bc-shadow); + -webkit-filter: drop-shadow(1px 0 1px @dark-bc-shadow); + filter: drop-shadow(1px 0 1px @dark-bc-shadow); } } .jstree-brackets .jstree-no-dots .jstree-closed > ins { background-position: 7px -8px; -webkit-transform: translateZ(0); /* Need this to make sure that the svg isn't blurry on retina. */ - -webkit-transition: -webkit-transform 90ms cubic-bezier(.01, .91, 0, .99); + transform: translateZ(0); + transition: -webkit-transform 90ms cubic-bezier(.01, .91, 0, .99); + transition: transform 90ms cubic-bezier(.01, .91, 0, .99); -webkit-filter: drop-shadow(1px 0 1px @bc-shadow); + filter: drop-shadow(1px 0 1px @bc-shadow); .dark & { - -webkit-filter: drop-shadow(1px 0 1px @dark-bc-shadow); + -webkit-filter: drop-shadow(1px 0 1px @dark-bc-shadow); + filter: drop-shadow(1px 0 1px @dark-bc-shadow); } } @@ -1123,7 +1132,7 @@ a, img { /* Styles for inline editors */ .inline-text-editor { - line-height: 0px; + line-height: 0; } .inline-widget { @@ -1158,7 +1167,7 @@ a, img { .inline-editor-header { display: inline-block; - padding: 9px 10px 1px 40px; + padding: 8px 10px 2px 40px; .filename { vertical-align: middle; @@ -1203,13 +1212,13 @@ a, img { } .shadow.top { - top: 0px; - background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0)); + top: 0; + background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0)); } .shadow.bottom { - bottom: 0px; - background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1)); + bottom: 0; + background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1)); } .CodeMirror-scroll { @@ -1303,7 +1312,7 @@ a, img { ul { margin: 0; - padding: 10px 0px 10px 5px; + padding: 10px 0 10px 5px; list-style: none; } @@ -1311,7 +1320,7 @@ a, img { color: @bc-text-emphasized; margin: 0; overflow: hidden; - padding: 2px 0px 2px 15px; + padding: 2px 0 2px 15px; text-overflow: ellipsis; white-space: nowrap; @@ -1469,6 +1478,7 @@ a, img { // Unfortunately, the way jsTree sprites are aligned within their 18px boxes doesn't look good in // other contexts, so we need some tweaks here instead of straight multiples of @jstree-sprite-size -webkit-transform: translateZ(0) rotate(90deg); + transform: translateZ(0) rotate(90deg); } } @@ -1486,7 +1496,9 @@ a, img { padding: 5px 4px 4px 14px; -webkit-transform: translate(0, 0); // Prefix still required. + transform: translate(0, 0); transition: -webkit-transform 66ms cubic-bezier(0, 0.62, 0.04, 0.99); + transition: transform 66ms cubic-bezier(0, 0.62, 0.04, 0.99); z-index: @z-index-brackets-modalbar; .dark & { @@ -1669,19 +1681,19 @@ a, img { } #replace-all.solo { border-left: none; - margin-left: 0px; + margin-left: 0; } // Make find field snug with options buttons // & replace snug with replace commands #find-what, #replace-with { - margin-right: 0px; + margin-right: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; } #find-case-sensitive, #replace-yes { border-left: none; - margin-left: 0px; + margin-left: 0; border-radius: 0; } } @@ -2024,14 +2036,14 @@ textarea.exclusions-editor { } @-webkit-keyframes spinner-rotateplane { - 0% { -webkit-transform: perspective(120px) } - 50% { -webkit-transform: perspective(120px) rotateY(180deg) } - 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) } + 0% { -webkit-transform: perspective(120px); } + 50% { -webkit-transform: perspective(120px) rotateY(180deg); } + 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg); } } @keyframes spinner-rotateplane { - 0% { -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); transform: perspective(120px) rotateX(0deg) rotateY(0deg); } - 50% { -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); } - 100% { -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } + 0% { transform: perspective(120px) rotateX(0deg) rotateY(0deg); } + 50% { transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); } + 100% { transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } } @@ -2153,7 +2165,7 @@ label input { } } &.animateOpen { - -webkit-transition: -webkit-transform 125ms; + transition: -webkit-transform 125ms; transition: transform 125ms; -webkit-transform: scale(1); transform: scale(1); @@ -2162,7 +2174,7 @@ label input { // Make the animation use the GPU--especially important for retina. -webkit-transform: translateZ(0); transform: translateZ(0); - -webkit-transition: opacity 500ms 5s ease-in, -webkit-transform 500ms 5s; + transition: opacity 500ms 5s ease-in, -webkit-transform 500ms 5s; transition: opacity 500ms 5s ease-in, transform 500ms 5s; opacity: 0.0; } diff --git a/src/styles/brackets_codemirror_override.less b/src/styles/brackets_codemirror_override.less index b33aab2f701..995cee7bbcb 100644 --- a/src/styles/brackets_codemirror_override.less +++ b/src/styles/brackets_codemirror_override.less @@ -26,12 +26,12 @@ padding: 0 @code-padding 0 0; > * { - text-indent: 0px; + text-indent: 0; } } .show-line-padding .CodeMirror pre { - padding-left: @code-padding; + padding-left: 0; } .CodeMirror-scroll { diff --git a/src/styles/brackets_mixins.less b/src/styles/brackets_mixins.less index b516398ee3c..7e5f31b5c93 100644 --- a/src/styles/brackets_mixins.less +++ b/src/styles/brackets_mixins.less @@ -24,13 +24,10 @@ /* Helpers for working with flex layouts */ /* see: https://developer.mozilla.org/en-US/docs/Web/CSS/flex */ .flex-box(@direction: row) { - display: -webkit-flex; - -webkit-flex-direction: @direction; display: flex; flex-direction: @direction; } .flex-item(@grow: 0, @shrink: 1, @basis: auto) { - -webkit-flex: @grow @shrink @basis; flex: @grow @shrink @basis; } @@ -70,8 +67,6 @@ /* Helpful for percentage-sizing items that have border/padding */ .sane-box-model { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; } diff --git a/src/styles/brackets_patterns_override.less b/src/styles/brackets_patterns_override.less index 495520c0a55..7bed48f66ae 100644 --- a/src/styles/brackets_patterns_override.less +++ b/src/styles/brackets_patterns_override.less @@ -73,10 +73,10 @@ a:focus { background: @project-panel-base-color; color: #bbb; letter-spacing: .01em; - text-shadow: 0px 1px 2px @bc-shadow-large; + text-shadow: 0 1px 2px @bc-shadow-large; .dark & { - text-shadow: 0px 1px 2px @dark-bc-shadow-large; + text-shadow: 0 1px 2px @dark-bc-shadow-large; } } @@ -88,10 +88,10 @@ a:focus { z-index: @z-index-brackets-drag-ghost; background-color: transparent; - text-shadow: 0px 1px 2px @bc-shadow-large; + text-shadow: 0 1px 2px @bc-shadow-large; .dark & { - text-shadow: 0px 1px 2px @dark-bc-shadow-large; + text-shadow: 0 1px 2px @dark-bc-shadow-large; } } @@ -156,6 +156,7 @@ a:focus { max-height: 90vh; overflow-y: auto; -webkit-animation: none; + animation: none; } } .title { @@ -179,7 +180,7 @@ a:focus { box-sizing: border-box; background: @main-toolbar-background-color; - padding: 7px 0px; + padding: 7px 0; // Ensure icons are vertically stacked & horizontally centered .vbox; @@ -199,7 +200,7 @@ a:focus { background-repeat: no-repeat; display: block; height: 24px; - margin: 7px 0px 0px 3px; + margin: 7px 0 0 3px; width: 24px; } @@ -259,8 +260,6 @@ a:focus { white-space: nowrap; overflow: hidden; - -ms-text-overflow: ellipsis; - -o-text-overflow: ellipsis; text-overflow: ellipsis; } @@ -284,6 +283,7 @@ a:focus { .dropdown-menu { .animation(dropdown, 90ms, cubic-bezier(0, .97, .2, .99)); -webkit-transform-origin: 0 0; + transform-origin: 0 0; border: none; border-radius: @bc-border-radius; @@ -305,6 +305,7 @@ a:focus { .codehint-menu.open .dropdown-menu { -webkit-animation: none; + animation: none; } .toolbar .nav, .context-menu, .codehint-menu { @@ -373,6 +374,7 @@ a:focus { // This technique won't work on all browsers; see comments in #4593 for alternative options. width: -webkit-max-content; width: -moz-max-content; + width: max-content; background-color: @bc-menu-bg; .border-radius(0 0 3px 3px); @@ -392,7 +394,7 @@ a:focus { // Slightly less padding on left to account for checkmark. // More padding on top than bottom to center font within its bg highlight better. - padding: 2px 10px 0px 6px; + padding: 2px 10px 0 6px; color: @bc-menu-text; text-shadow: none; @@ -502,7 +504,7 @@ a:focus { a { // Less padding than on menus. More padding on top than bottom // to center font within its bg highlight better. - padding: 2px 20px 0px 0px; + padding: 2px 20px 0 0; // Don't show highlighting on hover for code hints... &:hover { @@ -571,8 +573,8 @@ a:focus { .btn-dropdown::after { content: ""; display: block; - height: 0px; - width: 0px; + height: 0; + width: 0; position: absolute; right: 7px; top: 11px; @@ -678,6 +680,7 @@ a:focus { /* Status bar language picker's DropdownButton */ .dropdownbutton-popup.dropdown-status-bar { -webkit-transform-origin: 0 100%; + transform-origin: 0 100%; height: auto; max-height: 80%; @@ -1525,7 +1528,7 @@ input[type="color"], box-shadow: inset 0 1px @bc-highlight-hard; -webkit-font-smoothing: antialiased; text-shadow: none; - margin: 3px 0px 3px 3px; + margin: 3px 0 3px 3px; .dark & { background-color: @dark-bc-btn-bg; diff --git a/src/styles/images/horiz-thumb-fw-outline.png b/src/styles/images/horiz-thumb-fw-outline.png index 7ecd0c49701..10630bcf066 100644 Binary files a/src/styles/images/horiz-thumb-fw-outline.png and b/src/styles/images/horiz-thumb-fw-outline.png differ diff --git a/src/styles/images/scrollbar-mac-bg.png b/src/styles/images/scrollbar-mac-bg.png index 303b389ffad..ea81eceb1d7 100644 Binary files a/src/styles/images/scrollbar-mac-bg.png and b/src/styles/images/scrollbar-mac-bg.png differ diff --git a/src/styles/images/scrollbar-mac-corner.png b/src/styles/images/scrollbar-mac-corner.png index ce9bb06e3f8..b1b502de6a5 100644 Binary files a/src/styles/images/scrollbar-mac-corner.png and b/src/styles/images/scrollbar-mac-corner.png differ diff --git a/src/styles/images/vertical-thumb-fw-outline.png b/src/styles/images/vertical-thumb-fw-outline.png index 0f4d2c4b7b5..2fd2077a340 100644 Binary files a/src/styles/images/vertical-thumb-fw-outline.png and b/src/styles/images/vertical-thumb-fw-outline.png differ diff --git a/src/styles/jsTreeTheme.less b/src/styles/jsTreeTheme.less index 07e061bb428..a2eae59cfb7 100644 --- a/src/styles/jsTreeTheme.less +++ b/src/styles/jsTreeTheme.less @@ -27,10 +27,10 @@ @li-min-height: 23px; .jstree ul, .jstree li { display:block; margin:0 0 0 0; padding:0 0 0 0; list-style-type:none; } -.jstree li { display:block; min-height:@li-min-height; line-height:16px; white-space:nowrap; margin-left:18px; min-width:18px; } +.jstree li { display:block; min-height:@li-min-height; line-height:16px; white-space:nowrap; min-width:18px; } .jstree-rtl li { margin-left:0; margin-right:18px; } -.jstree > ul > li { margin-left:0px; } -.jstree-rtl > ul > li { margin-right:0px; } +.jstree > ul > li { margin-left:0; } +.jstree-rtl > ul > li { margin-right:0; } .jstree ins { display:inline-block; text-decoration:none; width:18px; height:18px; margin:0 0 0 0; padding:0; } .jstree a:focus { outline: none; } .jstree a > ins { height:16px; width:16px; } @@ -86,14 +86,10 @@ li.jstree-closed > ul { display:none; } color: @project-panel-text-2; } &.jstree-closed, &.jstree-open { - margin-left: 10px; > a { color: @project-panel-text-2; } } - &.jstree-leaf { - margin-left: 10px; - } } .jstree ins { @@ -155,6 +151,7 @@ ins.jstree-icon { left: 3px !important; top: 2px !important; margin: 0; + margin-bottom: 5px; /* It should instead be applyed only to folders */ padding: 0; position: relative; width: 150px; @@ -169,11 +166,11 @@ ins.jstree-icon { } #vakata-contextmenu.jstree-brackets-context, -#vakata-contextmenu.jstree-brackets-context li ul { background:#f0f0f0; border:1px solid #979797; -moz-box-shadow: 1px 1px 2px #999; -webkit-box-shadow: 1px 1px 2px #999; box-shadow: 1px 1px 2px #999; } +#vakata-contextmenu.jstree-brackets-context li ul { background:#f0f0f0; border:1px solid #979797; box-shadow: 1px 1px 2px #999; } #vakata-contextmenu.jstree-brackets-context li { } #vakata-contextmenu.jstree-brackets-context a { color:black; } #vakata-contextmenu.jstree-brackets-context a:hover, -#vakata-contextmenu.jstree-brackets-context .vakata-hover > a { padding:0 5px; background:#e8eff7; border:1px solid #aecff7; color:black; -moz-border-radius:2px; -webkit-border-radius:2px; border-radius:2px; } +#vakata-contextmenu.jstree-brackets-context .vakata-hover > a { padding:0 5px; background:#e8eff7; border:1px solid #aecff7; color:black; border-radius:2px; } #vakata-contextmenu.jstree-brackets-context li.jstree-contextmenu-disabled a, #vakata-contextmenu.jstree-brackets-context li.jstree-contextmenu-disabled a:hover { color:silver; background:transparent; border:0; padding:1px 4px; } #vakata-contextmenu.jstree-brackets-context li.vakata-separator { background:white; border-top:1px solid #e0e0e0; margin:0; } diff --git a/src/thirdparty/CodeMirror b/src/thirdparty/CodeMirror index 8f095df4c62..40210a5aa08 160000 --- a/src/thirdparty/CodeMirror +++ b/src/thirdparty/CodeMirror @@ -1 +1 @@ -Subproject commit 8f095df4c6262fb6301d66159957288b657c6a42 +Subproject commit 40210a5aa08cbb81b3b6646da5509fb20be4a258 diff --git a/src/utils/AnimationUtils.js b/src/utils/AnimationUtils.js index 972845cf846..7cea1492849 100644 --- a/src/utils/AnimationUtils.js +++ b/src/utils/AnimationUtils.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * Utilities for dealing with animations in the UI. */ @@ -40,7 +36,7 @@ define(function (require, exports, module) { * @return {string} The supported transitionend event name. */ function _detectTransitionEvent() { - var event, el = document.createElement("fakeelement"); + var event, el = window.document.createElement("fakeelement"); var transitions = { "OTransition" : "oTransitionEnd", diff --git a/src/utils/AppInit.js b/src/utils/AppInit.js index 2d2aeb03178..147ebd9d4af 100644 --- a/src/utils/AppInit.js +++ b/src/utils/AppInit.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Defines hooks to assist with module initialization. * diff --git a/src/utils/Async.js b/src/utils/Async.js index 977b2f5c53c..b4584550e5b 100644 --- a/src/utils/Async.js +++ b/src/utils/Async.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * Utilities for working with Deferred, Promise, and other asynchronous processes. */ diff --git a/src/utils/BuildInfoUtils.js b/src/utils/BuildInfoUtils.js index c61896568a5..2c1509546ba 100644 --- a/src/utils/BuildInfoUtils.js +++ b/src/utils/BuildInfoUtils.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets */ - /** * Utilities for determining the git SHA from an optional repository or from the * installed copy of Brackets. diff --git a/src/utils/ColorUtils.js b/src/utils/ColorUtils.js index 7f06532cdce..cacca39948b 100644 --- a/src/utils/ColorUtils.js +++ b/src/utils/ColorUtils.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * Utilities functions related to color matching * diff --git a/src/utils/Compatibility.js b/src/utils/Compatibility.js index dd4ac8c34e2..55a04047454 100644 --- a/src/utils/Compatibility.js +++ b/src/utils/Compatibility.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Compatibility shims for running Brackets in various environments, browsers. */ diff --git a/src/utils/DeprecationWarning.js b/src/utils/DeprecationWarning.js index 4bda8d7817d..323acf25299 100644 --- a/src/utils/DeprecationWarning.js +++ b/src/utils/DeprecationWarning.js @@ -21,8 +21,6 @@ * */ -/*global define, console */ - /** * Utilities functions to display deprecation warning in the console. * diff --git a/src/utils/DragAndDrop.js b/src/utils/DragAndDrop.js index c2cf0f8b48e..1cda399de24 100644 --- a/src/utils/DragAndDrop.js +++ b/src/utils/DragAndDrop.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/utils/DropdownEventHandler.js b/src/utils/DropdownEventHandler.js index e207c8dc64e..f5f3323b336 100644 --- a/src/utils/DropdownEventHandler.js +++ b/src/utils/DropdownEventHandler.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/utils/EventDispatcher.js b/src/utils/EventDispatcher.js index ced84b7825a..9e54fa06637 100644 --- a/src/utils/EventDispatcher.js +++ b/src/utils/EventDispatcher.js @@ -20,10 +20,6 @@ * DEALINGS IN THE SOFTWARE. */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * Implements a jQuery-like event dispatch pattern for non-DOM objects: * - Listeners are attached via on()/one() & detached via off() diff --git a/src/utils/ExtensionLoader.js b/src/utils/ExtensionLoader.js index e77acd3bcf6..d84c41b8d0e 100644 --- a/src/utils/ExtensionLoader.js +++ b/src/utils/ExtensionLoader.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets */ - /** * ExtensionLoader searches the filesystem for extensions, then creates a new context for each one and loads it. * This module dispatches the following events: @@ -45,7 +41,8 @@ define(function (require, exports, module) { FileUtils = require("file/FileUtils"), Async = require("utils/Async"), ExtensionUtils = require("utils/ExtensionUtils"), - UrlParams = require("utils/UrlParams").UrlParams; + UrlParams = require("utils/UrlParams").UrlParams, + PathUtils = require("thirdparty/path-utils/path-utils"); // default async initExtension timeout var INIT_EXTENSION_TIMEOUT = 10000; @@ -65,10 +62,14 @@ define(function (require, exports, module) { // load the text and i18n modules. srcPath = srcPath.replace(/\/test$/, "/src"); // convert from "test" to "src" - var globalConfig = { - "text" : srcPath + "/thirdparty/text/text", - "i18n" : srcPath + "/thirdparty/i18n/i18n" - }; + + // Retrieve the global paths + var globalPaths = brackets._getGlobalRequireJSConfig().paths; + + // Convert the relative paths to absolute + Object.keys(globalPaths).forEach(function (key) { + globalPaths[key] = PathUtils.makePathAbsolute(srcPath + "/" + globalPaths[key]); + }); /** * Returns the full path of the default user extensions directory. This is in the users @@ -161,8 +162,7 @@ define(function (require, exports, module) { var extensionConfig = { context: name, baseUrl: config.baseUrl, - /* FIXME (issue #1087): can we pass this from the global require context instead of hardcoding twice? */ - paths: globalConfig, + paths: globalPaths, locale: brackets.getLocale() }; @@ -286,7 +286,7 @@ define(function (require, exports, module) { var extensionRequire = brackets.libRequire.config({ context: name, baseUrl: config.baseUrl, - paths: $.extend({}, config.paths, globalConfig) + paths: $.extend({}, config.paths, globalPaths) }); extensionRequire([entryPoint], function () { diff --git a/src/utils/ExtensionUtils.js b/src/utils/ExtensionUtils.js index e8dd1c7d0cc..c5c4c4d6a5f 100644 --- a/src/utils/ExtensionUtils.js +++ b/src/utils/ExtensionUtils.js @@ -21,9 +21,7 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, less */ +/*global less */ /** * ExtensionUtils defines utility methods for implementing extensions. diff --git a/src/utils/Global.js b/src/utils/Global.js index 4f4fe328eb2..97640477b92 100644 --- a/src/utils/Global.js +++ b/src/utils/Global.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Initializes the global "brackets" variable and it's properties. * Modules should not access the global.brackets object until either @@ -125,5 +121,12 @@ define(function (require, exports, module) { // only be able to load modules that have already been loaded once. global.brackets.getModule = require; + /* API for retrieving the global RequireJS config + * For internal use only + */ + global.brackets._getGlobalRequireJSConfig = function () { + return global.require.s.contexts._.config; + }; + exports.global = global; }); diff --git a/src/utils/HealthLogger.js b/src/utils/HealthLogger.js index 831f1933c6a..a2e17008246 100644 --- a/src/utils/HealthLogger.js +++ b/src/utils/HealthLogger.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $*/ - /** * Utilities functions related to Health Data logging */ diff --git a/src/utils/KeyEvent.js b/src/utils/KeyEvent.js index a7186f91738..40c7513bc8a 100644 --- a/src/utils/KeyEvent.js +++ b/src/utils/KeyEvent.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Utilities module to provide constants for keyCodes */ diff --git a/src/utils/LocalizationUtils.js b/src/utils/LocalizationUtils.js index c04d9a648c2..718d1dafddb 100644 --- a/src/utils/LocalizationUtils.js +++ b/src/utils/LocalizationUtils.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Utilities functions related to localization/i18n */ diff --git a/src/utils/NativeApp.js b/src/utils/NativeApp.js index 778cba1c5b9..66f9bdee023 100644 --- a/src/utils/NativeApp.js +++ b/src/utils/NativeApp.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50*/ -/*global $, define, brackets */ - define(function (require, exports, module) { "use strict"; diff --git a/src/utils/NodeConnection.js b/src/utils/NodeConnection.js index 1d9a7d9929d..c6502d45fbe 100644 --- a/src/utils/NodeConnection.js +++ b/src/utils/NodeConnection.js @@ -21,11 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, -maxerr: 50, browser: true */ -/*global $, define, brackets, WebSocket, ArrayBuffer, Uint32Array */ - define(function (require, exports, module) { "use strict"; diff --git a/src/utils/NodeDomain.js b/src/utils/NodeDomain.js index 1562e61ba93..34ba13d7121 100644 --- a/src/utils/NodeDomain.js +++ b/src/utils/NodeDomain.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - define(function (require, exports, module) { "use strict"; diff --git a/src/utils/PerfUtils.js b/src/utils/PerfUtils.js index ce4c870c42f..edf868191fd 100644 --- a/src/utils/PerfUtils.js +++ b/src/utils/PerfUtils.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets */ - /** * This is a collection of utility functions for gathering performance data. */ diff --git a/src/utils/Resizer.js b/src/utils/Resizer.js index c6156428a24..36d61cc3a88 100644 --- a/src/utils/Resizer.js +++ b/src/utils/Resizer.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * Resizer is a Module utility to inject resizing capabilities to any element * inside Brackets. diff --git a/src/utils/ShellAPI.js b/src/utils/ShellAPI.js index c64f10d93a1..a59eb2f80e6 100644 --- a/src/utils/ShellAPI.js +++ b/src/utils/ShellAPI.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * This is JavaScript API exposed to the native shell when Brackets is run in a native shell rather than a browser. */ diff --git a/src/utils/StringMatch.js b/src/utils/StringMatch.js index fec3ff67fab..b496274bb08 100644 --- a/src/utils/StringMatch.js +++ b/src/utils/StringMatch.js @@ -21,8 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ /*unittests: StringMatch */ define(function (require, exports, module) { diff --git a/src/utils/StringUtils.js b/src/utils/StringUtils.js index 693a6dc3802..1f426c86db8 100644 --- a/src/utils/StringUtils.js +++ b/src/utils/StringUtils.js @@ -25,8 +25,8 @@ @CC wiki attribution: esmiralha */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50, bitwise: true */ -/*global define, brackets */ +/*eslint no-bitwise: off */ +/*jslint bitwise: true */ /** * Utilities functions related to string manipulation diff --git a/src/utils/TokenUtils.js b/src/utils/TokenUtils.js index b845431c941..c2931cf2a2c 100644 --- a/src/utils/TokenUtils.js +++ b/src/utils/TokenUtils.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * Functions for iterating through tokens in the current editor buffer. Useful for doing * light parsing that can rely purely on information gathered by the code coloring mechanism. diff --git a/src/utils/UpdateNotification.js b/src/utils/UpdateNotification.js index 81cc3cc4e91..47ded1acb6d 100644 --- a/src/utils/UpdateNotification.js +++ b/src/utils/UpdateNotification.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, window */ - /** * Utilities functions for displaying update notifications * diff --git a/src/utils/UrlParams.js b/src/utils/UrlParams.js index 1fbcb524ce5..605a1bbf480 100644 --- a/src/utils/UrlParams.js +++ b/src/utils/UrlParams.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, window */ - define(function (require, exports, module) { "use strict"; diff --git a/src/utils/ValidationUtils.js b/src/utils/ValidationUtils.js index 5f8dfa5e3b9..672c18e2270 100644 --- a/src/utils/ValidationUtils.js +++ b/src/utils/ValidationUtils.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/utils/ViewUtils.js b/src/utils/ViewUtils.js index 4e20ee2f1c0..2cde5df4e3e 100644 --- a/src/utils/ViewUtils.js +++ b/src/utils/ViewUtils.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - define(function (require, exports, module) { "use strict"; @@ -259,9 +255,6 @@ define(function (require, exports, module) { // list item position is relative to scroller var selectionMarkerTop = $listItem.offset().top - $scrollerElement.offset().top + $scrollerElement.get(0).scrollTop; - // force selection width to match scroller - $selectionMarker.width($scrollerElement.get(0).scrollWidth); - // move the selectionMarker position to align with the list item $selectionMarker.css("top", selectionMarkerTop); $selectionMarker.show(); diff --git a/src/view/MainViewFactory.js b/src/view/MainViewFactory.js index 9412664e21f..ae9dd62bf62 100644 --- a/src/view/MainViewFactory.js +++ b/src/view/MainViewFactory.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * MainViewFactory is a singleton for managing view factories. * diff --git a/src/view/MainViewManager.js b/src/view/MainViewManager.js index 1b3f3058985..1b96c2c7938 100644 --- a/src/view/MainViewManager.js +++ b/src/view/MainViewManager.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * MainViewManager manages the arrangement of all open panes as well as provides the controller * logic behind all views in the MainView (e.g. ensuring that a file doesn't appear in 2 lists) diff --git a/src/view/Pane.js b/src/view/Pane.js index cc7d9721587..21a7bc6f55f 100644 --- a/src/view/Pane.js +++ b/src/view/Pane.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $ */ - /** * Pane objects host views of files, editors, etc... Clients cannot access * Pane objects directly. Instead the implementation is protected by the diff --git a/src/view/PanelManager.js b/src/view/PanelManager.js index b4690a403f2..e83ad1b306e 100644 --- a/src/view/PanelManager.js +++ b/src/view/PanelManager.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - /** * @deprecated This module provided for backwards compatibility. Use WorkspaceManager instead. */ diff --git a/src/view/ThemeManager.js b/src/view/ThemeManager.js index 8e0687e0277..16b48638b08 100644 --- a/src/view/ThemeManager.js +++ b/src/view/ThemeManager.js @@ -21,8 +21,8 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, regexp: true, nomen: true, indent: 4, maxerr: 50 */ -/*global $, define, less */ +/*jslint regexp: true */ +/*global less */ define(function (require, exports, module) { "use strict"; diff --git a/src/view/ThemeSettings.js b/src/view/ThemeSettings.js index aded68bade7..a946eb6513b 100644 --- a/src/view/ThemeSettings.js +++ b/src/view/ThemeSettings.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global $, define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/view/ThemeView.js b/src/view/ThemeView.js index a08bb4b4fcc..26a574b40b4 100644 --- a/src/view/ThemeView.js +++ b/src/view/ThemeView.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global $, define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/view/ViewCommandHandlers.js b/src/view/ViewCommandHandlers.js index 4a65bc791fa..c4818a6588c 100644 --- a/src/view/ViewCommandHandlers.js +++ b/src/view/ViewCommandHandlers.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, brackets: false, $ */ - /** * The ViewCommandHandlers object dispatches the following event(s): * - fontSizeChange -- Triggered when the font size is changed via the diff --git a/src/view/ViewStateManager.js b/src/view/ViewStateManager.js index 5df3db179ea..50e20b3e237 100644 --- a/src/view/ViewStateManager.js +++ b/src/view/ViewStateManager.js @@ -20,8 +20,6 @@ * DEALINGS IN THE SOFTWARE. * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ /** * ViewStateManager is a singleton for views to park their global viwe state. The state is saved diff --git a/src/view/WorkspaceManager.js b/src/view/WorkspaceManager.js index d4c30dd603d..84dec97646f 100644 --- a/src/view/WorkspaceManager.js +++ b/src/view/WorkspaceManager.js @@ -21,9 +21,6 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, window, $ */ - /** * Manages layout of panels surrounding the editor area, and size of the editor area (but not its contents). * diff --git a/src/widgets/DefaultDialogs.js b/src/widgets/DefaultDialogs.js index ed457f1f6c2..55d491c9943 100644 --- a/src/widgets/DefaultDialogs.js +++ b/src/widgets/DefaultDialogs.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define */ - define(function (require, exports, module) { "use strict"; diff --git a/src/widgets/Dialogs.js b/src/widgets/Dialogs.js index 69f720ef9c8..ba4ad93fc8f 100644 --- a/src/widgets/Dialogs.js +++ b/src/widgets/Dialogs.js @@ -21,10 +21,6 @@ * */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, brackets, window */ - /** * Utilities for creating and managing standard modal dialogs. */ @@ -170,7 +166,9 @@ define(function (require, exports, module) { stopEvent(); if (e.target.tagName === "BUTTON") { this.find(e.target).click(); - } else { + } else if (e.target.tagName !== "INPUT") { + // If the target element is not BUTTON or INPUT, click the primary button + // We're making an exception for INPUT element because of this issue: GH-11416 $primaryBtn.click(); } } else if (e.which === KeyEvent.DOM_VK_SPACE) { @@ -309,6 +307,9 @@ define(function (require, exports, module) { return _keydownHook.call($dlg, e, autoDismiss); }; + // Store current focus + var lastFocus = window.document.activeElement; + // Pipe dialog-closing notification back to client code $dlg.one("hidden", function () { var buttonId = $dlg.data("buttonId"); @@ -329,6 +330,11 @@ define(function (require, exports, module) { // Remove our global keydown handler. KeyBindingManager.removeGlobalKeydownHook(keydownHook); + // Restore previous focus + if (lastFocus) { + lastFocus.focus(); + } + //Remove wrapper $(".modal-wrapper:last").remove(); }).one("shown", function () { @@ -342,7 +348,7 @@ define(function (require, exports, module) { } else if ($otherBtn.length) { $otherBtn.focus(); } else { - document.activeElement.blur(); + window.document.activeElement.blur(); } // Push our global keydown handler onto the global stack of handlers. diff --git a/src/widgets/DropdownButton.js b/src/widgets/DropdownButton.js index 77e4c0df34c..0a398b721ff 100644 --- a/src/widgets/DropdownButton.js +++ b/src/widgets/DropdownButton.js @@ -20,10 +20,6 @@ * DEALINGS IN THE SOFTWARE. */ - -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ -/*global define, $, window */ - /** * Button that opens a dropdown list when clicked. More akin to a popup menu than a combobox. Compared to a * simple