diff --git a/README.md b/README.md index 6a29c416..55ce3ff6 100644 --- a/README.md +++ b/README.md @@ -92,3 +92,4 @@ To protect the interests of the Cloud9 contributors and users we require contrib If you want to contribute to the Cloud9 SDK and/or open source plugins please go to the online form, fill it out and submit it. Happy coding, Cloud9 + diff --git a/configs/client-config_test.js b/configs/client-config_test.js new file mode 100755 index 00000000..180f521a --- /dev/null +++ b/configs/client-config_test.js @@ -0,0 +1,140 @@ +#!/usr/bin/env node +/*global describe it*/ +"use strict"; + +"use server"; + + +require("amd-loader"); +require("c9/inline-mocha")(module); + +var assert = require("assert"); +var fs = require("fs"); + +describe("client config consistency", function(){ + // this.timeout(60000); + + var fileCache = Object.create(null); + var clientOptions; + var root = __dirname + "/../"; + + it("should get clientOptions from server", function(next) { + fetchClientOptions(function(err, clientOptions) { + assert(!err && clientOptions); + next(); + }); + }); + + fs.readdirSync(root + "/configs").forEach(function(name) { + if (!/client-(workspace|ssh|default)/.test(name)) return; + + it("should not have missing plugins in config " + name, function(next) { + fetchClientOptions(function(err, clientOptions) { + if (err) return next(); + checkConfig(name, clientOptions, next); + }); + }); + }); + + function fetchClientOptions(callback) { + if (clientOptions) + return callback(null, JSON.parse(JSON.stringify(clientOptions))); + var server = require(root + "/server.js"); + server(["--_getConfig", "-l", "localhost", "--collab=true"], "", function(e, plugins) { + clientOptions = plugins.filter(function(p) { + return /standalone[\\\/]standalone/.test(p.packagePath); + })[0].options; + fetchClientOptions(callback); + }); + } + + function checkConfig(name, clientOptions, next) { + var hasError = false; + var configPath = root + "/configs/" + name; + var configPathReal = fs.realpathSync(configPath); + var clientPlugins = require(configPath)(clientOptions); + + clientPlugins = clientPlugins.map(function(p, i) { + if (typeof p == "string") + return {packagePath: p}; + return p; + }); + clientPlugins.forEach(function(p) { + if (p.packagePath) { + if (!fileCache[p.packagePath]) { + + var filePath; + try { + filePath = require.resolve(p.packagePath); + } + catch (e) { + try { + filePath = require.resolve(p.packagePath.replace(/^plugins\//, "")); + } catch (e) { + // TODO instead of quessing we need a simple way of getting pathmap + if (configPath != configPathReal) + filePath = require.resolve(configPathReal + "/../../node_modules/" + p.packagePath.replace(/^plugins\//, "")); + } + } + if (!filePath.match(/\.js$/)) + filePath += ".js"; + + fileCache[p.packagePath] = fs.readFileSync(filePath, "utf8"); + } + var source = fileCache[p.packagePath]; + p.provides = getDeps("provides", source); + p.consumes = getDeps("consumes", source); + } + }); + + var provides = {"auth.bootstrap": 1, "hub": 1}; + var paths = {}; + clientPlugins.forEach(function(p) { + if (paths[p.packagePath]) { + console.error(name, paths[p.packagePath].packagePath, p.packagePath); + hasError = true; + } + paths[p.packagePath] = p; + p.provides && p.provides.forEach(function(name) { + if (provides[name]) { + // console.warn(name, p.packagePath, provides[name]); + } + provides[name] = p.packagePath; + }); + }); + var unresolved = []; + clientPlugins.forEach(function(p) { + var missing = (p.consumes || []).filter(function(name) { + return !provides[name]; + }); + if (missing.length) { + unresolved.push({ + packagePath: p.packagePath, + missing: missing + }); + } + }); + + if (unresolved.length) { + // not throwing an error to check all configs + hasError = true; + } + + function getDeps(type, source) { + var re = new RegExp(type + /\s*=\s*(\[[^\[\]]*\])/.source); + var m = source.match(re); + if (!m) return []; + m = m[1].replace(/\/\/.*|\/\*[\s\S]*?\*\//g, "") + .replace(/,\s*\]/g, "]") + .replace(/'/g, "\""); + return JSON.parse(m); + } + assert(!unresolved.length, ( + "unresolved plugins in /configs/" + name + + JSON.stringify(unresolved, null, 4) + ).replace(/^/gm, "\t") + ); + next(); + } + +}); diff --git a/configs/client-default-local.js b/configs/client-default-local.js index 10fedaa8..f94cf36f 100644 --- a/configs/client-default-local.js +++ b/configs/client-default-local.js @@ -112,7 +112,6 @@ module.exports.makeLocal = function(config, options) { name: options.user.name, fullname: options.user.fullname, email: options.user.email, - pubkey: options.user.pubkey }, project: { id: options.project.id, diff --git a/configs/client-default-terminal.js b/configs/client-default-terminal.js new file mode 100644 index 00000000..8621f32d --- /dev/null +++ b/configs/client-default-terminal.js @@ -0,0 +1,45 @@ +"use strict"; + +module.exports = function(options) { + var plugins = require("./client-default")(options); + + // TODO: cleanup unneeded plugins? + var includes = []; + var excludes = {}; + + plugins.forEach(function(p) { + if (p.packagePath && p.packagePath.indexOf("c9.core/settings") >= 0) { + p.settings = "defaults"; + p.template = { + user: {}, + project: {}, + state: { + console: { + "@maximized": true, + type: "pane", + nodes: [] + } + } + }; + } + else if (p.packagePath == "plugins/c9.ide.console/console") { + p.defaultState = { + type: "pane", + nodes: [{ + type: "tab", + editorType: "terminal", + active: "true" + }] + }; + } + }); + + plugins = plugins + .concat(includes) + .filter(function (p) { + return !excludes[p] && !excludes[p.packagePath]; + }); + + return plugins; +}; + diff --git a/configs/client-default.js b/configs/client-default.js index 8a56d751..ade5fbf4 100644 --- a/configs/client-default.js +++ b/configs/client-default.js @@ -674,7 +674,6 @@ module.exports = function(options) { name: options.user.name, fullname: options.user.fullname, email: options.user.email, - pubkey: options.user.pubkey, date_add: options.user.date_add, active: options.user.active, c9version: options.user.c9version, diff --git a/configs/terminal.js b/configs/terminal.js new file mode 100644 index 00000000..9bc98d15 --- /dev/null +++ b/configs/terminal.js @@ -0,0 +1,11 @@ +module.exports = function(options, optimist) { + var config = require("./standalone")(options, optimist); + + // TODO: cleanup unneeded plugins? + + options.client_config = "default-terminal"; + + return config; +}; + +if (!module.parent) require("../server")([__filename].concat(process.argv.slice(2))); diff --git a/integrations/scripts/update.sh b/integrations/scripts/update.sh index 4ad703e3..8ce2487d 100755 --- a/integrations/scripts/update.sh +++ b/integrations/scripts/update.sh @@ -3,73 +3,139 @@ set -e cd `dirname $0`/.. NAME=$1 -URL=$2 +shift +BRANCH=master +URL= +FORCE= +for i in "$@"; do + case $i in + -d|--debug) + set -x + shift + ;; + -b=*|--branch=*) + BRANCH="${i#*=}" + shift + ;; + -u=*|--url=*) + URL="${i#*=}" + shift + ;; + -f|--force|--hard) + FORCE=1 + shift + ;; + *) + # unknown option + ;; + esac +done + if [ "$NAME" == "" ]; then - echo "add name [url]" + echo "add name [--url=git@github.com:c9/NAME.git] [--branch=master]" exit 0 fi -if [ "$URL" == "" ]; then - URL=git@github.com:c9/$NAME.git -fi - -if [ -d $NAME/.git ]; then +update_one() { + echo adding name=$NAME url=$URL branch=refs/remotes/origin/$BRANCH + + if [ "$URL" == "" ]; then + URL=git@github.com:c9/$NAME.git + fi + + mkdir -p $NAME pushd $NAME + + if ! [ -d .git ]; then + git init . + git remote add origin "$URL" + fi + OLD_URL=$(git config --get remote.origin.url) if [ "$OLD_URL" != "$URL" ]; then echo "folder $NAME exists and points to $OLD_URL" exit 1 fi + if ! $(git config --get-all remote.origin.fetch | grep -q pull); then + git config --add remote.origin.fetch "+refs/pull/*/head:refs/remotes/pull/*"; + fi git fetch origin + git remote set-head origin -a popd + + pushd $NAME + HASH=$(git rev-parse --revs-only refs/remotes/origin/$BRANCH) + if [ "$FORCE" == "1" ]; then + echo "hard reset $NAME to $HASH" + git reset $HASH --hard + if $(grep -q dependencies "./package.json"); then + rm -rf node_modules npm-shrinkwrap.json + git reset --hard + npm i + npm shrinkwrap + fi + fi + popd + + [ -f ./config.json ] || echo "{}" > ./config.json + node -e ' + var name = "'$NAME'"; + var url = "'$URL'"; + var hash = "'$HASH'".trim(); + var fs = require("fs"); + + function updateJSON(path, fn) { + var text = fs.readFileSync(path, "utf8"); + var indent = text.match(/^\s*(?=")/m); + indent = indent && indent[0] || 4; + console.log(indent) + var r = JSON.parse(text); + r = fn(r) || r; + text = JSON.stringify(r, null, indent) + "\n"; + fs.writeFileSync(path, text, "utf8"); + } + + updateJSON("./config.json", function(config) { + var packages = config.packages || (config.packages = {}); + config.packages[name] = { + name: name, + hash: hash, + url: url, + }; + }); + updateJSON("../package.json", function(package) { + var deps = package.dependencies; + console.log(deps[name], hash); + deps[name] = deps[name].replace(/#[a-f\d]*$/i, "#" + hash); + console.log(deps[name], hash); + }); + updateJSON("../npm-shrinkwrap.json", function(package) { + var deps = package.dependencies; + deps[name].from = deps[name].from.replace(/#[a-f\d]*$/i, "#" + hash); + deps[name].resolved = deps[name].resolved.replace(/#[a-f\d]*$/i, "#" + hash); + console.log(__dirname) + if (fs.existsSync(name + "/npm-shrinkwrap.json")) { + var shrinkwrap = JSON.parse(fs.readFileSync(name + "/npm-shrinkwrap.json", "utf8")); + deps[name].dependencies = shrinkwrap.dependencies; + } + }); + ' + + rm -rf "../node_modules/$NAME" + ln -s `pwd`/$NAME `pwd`/../node_modules/$NAME +} + + +if [ "$NAME" == "all" ]; then + for i in $(ls .); do + if [ -d "./$i/.git" ] || [ -f "./$i/package.json" ]; then + NAME=$i + URL= + update_one; + fi; + done else - mkdir -p $NAME - git clone $URL $NAME + update_one fi -pushd $NAME -HASH=$(git rev-parse --revs-only refs/remotes/origin/master) -popd - -[ -f ./config.json ] || echo "{}" > ./config.json -node -e ' - var name = "'$NAME'"; - var url = "'$URL'"; - var hash = "'$HASH'" - var fs = require("fs"); - - function updateJSON(path, fn) { - var text = fs.readFileSync(path, "utf8"); - var indent = text.match(/^\s*(?=")/m); - indent = indent && indent[0] || 4; - console.log(indent) - var r = JSON.parse(text); - r = fn(r) || r; - text = JSON.stringify(r, null, indent) + "\n"; - fs.writeFileSync(path, text, "utf8"); - } - - updateJSON("./config.json", function(config) { - var packages = config.packages || (config.packages = {}); - config.packages[name] = { - name: name, - hash: hash, - url: url, - }; - }); - updateJSON("../package.json", function(package) { - var deps = package.dependencies; - console.log(deps[name], hash) - deps[name] = deps[name].replace(/#[a-f\d]+$/i, "#" + hash) - console.log(deps[name], hash) - }); - updateJSON("../npm-shrinkwrap.json", function(package) { - var deps = package.dependencies; - deps[name].from = deps[name].from.replace(/#[a-f\d]+$/i, "#" + hash); - deps[name].resolved = deps[name].resolved.replace(/#[a-f\d]+$/i, "#" + hash); - }); -' - -rm -rf "../node_modules/$NAME" -ln -s `pwd`/$NAME `pwd`/../node_modules/$NAME diff --git a/node_modules/ace/lib/ace/mode/abc.js b/node_modules/ace/lib/ace/mode/abc.js index b6eb237a..630d3f02 100644 --- a/node_modules/ace/lib/ace/mode/abc.js +++ b/node_modules/ace/lib/ace/mode/abc.js @@ -38,12 +38,12 @@ define(function (require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var ABCHighlightRules = require("./abc_highlight_rules").ABCHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function () { this.HighlightRules = ABCHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/actionscript.js b/node_modules/ace/lib/ace/mode/actionscript.js index 7daf2941..0100c7a4 100644 --- a/node_modules/ace/lib/ace/mode/actionscript.js +++ b/node_modules/ace/lib/ace/mode/actionscript.js @@ -39,12 +39,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var ActionScriptHighlightRules = require("./actionscript_highlight_rules").ActionScriptHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = ActionScriptHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/ada.js b/node_modules/ace/lib/ace/mode/ada.js index dc1dfa14..fabf04dc 100644 --- a/node_modules/ace/lib/ace/mode/ada.js +++ b/node_modules/ace/lib/ace/mode/ada.js @@ -34,10 +34,10 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var AdaHighlightRules = require("./ada_highlight_rules").AdaHighlightRules; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = AdaHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/apache_conf.js b/node_modules/ace/lib/ace/mode/apache_conf.js index 2379b44b..dec48d15 100644 --- a/node_modules/ace/lib/ace/mode/apache_conf.js +++ b/node_modules/ace/lib/ace/mode/apache_conf.js @@ -43,12 +43,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var ApacheConfHighlightRules = require("./apache_conf_highlight_rules").ApacheConfHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = ApacheConfHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/applescript.js b/node_modules/ace/lib/ace/mode/applescript.js index 81bc3533..90a79fba 100644 --- a/node_modules/ace/lib/ace/mode/applescript.js +++ b/node_modules/ace/lib/ace/mode/applescript.js @@ -33,14 +33,13 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; -var Tokenizer = require("../tokenizer").Tokenizer; var AppleScriptHighlightRules = require("./applescript_highlight_rules").AppleScriptHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = AppleScriptHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/assembly_x86.js b/node_modules/ace/lib/ace/mode/assembly_x86.js index d6343e80..21858f42 100644 --- a/node_modules/ace/lib/ace/mode/assembly_x86.js +++ b/node_modules/ace/lib/ace/mode/assembly_x86.js @@ -44,6 +44,7 @@ var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = AssemblyX86HighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/autohotkey.js b/node_modules/ace/lib/ace/mode/autohotkey.js index d7093fd5..3ac647c8 100644 --- a/node_modules/ace/lib/ace/mode/autohotkey.js +++ b/node_modules/ace/lib/ace/mode/autohotkey.js @@ -38,12 +38,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var AutoHotKeyHighlightRules = require("./autohotkey_highlight_rules").AutoHotKeyHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = AutoHotKeyHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/batchfile.js b/node_modules/ace/lib/ace/mode/batchfile.js index e080464c..052a2384 100644 --- a/node_modules/ace/lib/ace/mode/batchfile.js +++ b/node_modules/ace/lib/ace/mode/batchfile.js @@ -48,6 +48,7 @@ var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = BatchFileHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/cirru.js b/node_modules/ace/lib/ace/mode/cirru.js index 5f1c4d9e..75a4d0c4 100644 --- a/node_modules/ace/lib/ace/mode/cirru.js +++ b/node_modules/ace/lib/ace/mode/cirru.js @@ -39,6 +39,7 @@ var CoffeeFoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = CirruHighlightRules; this.foldingRules = new CoffeeFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/clojure.js b/node_modules/ace/lib/ace/mode/clojure.js index ee44ac3e..6bb9b0ae 100644 --- a/node_modules/ace/lib/ace/mode/clojure.js +++ b/node_modules/ace/lib/ace/mode/clojure.js @@ -39,6 +39,7 @@ var MatchingParensOutdent = require("./matching_parens_outdent").MatchingParensO var Mode = function() { this.HighlightRules = ClojureHighlightRules; this.$outdent = new MatchingParensOutdent(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/cobol.js b/node_modules/ace/lib/ace/mode/cobol.js index 91713bd0..3b325985 100644 --- a/node_modules/ace/lib/ace/mode/cobol.js +++ b/node_modules/ace/lib/ace/mode/cobol.js @@ -34,10 +34,10 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var CobolHighlightRules = require("./cobol_highlight_rules").CobolHighlightRules; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = CobolHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/curly.js b/node_modules/ace/lib/ace/mode/curly.js index f7c42af9..d2bca1cf 100644 --- a/node_modules/ace/lib/ace/mode/curly.js +++ b/node_modules/ace/lib/ace/mode/curly.js @@ -41,7 +41,6 @@ var oop = require("../lib/oop"); // defines the parent mode var HtmlMode = require("./html").Mode; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; var HtmlFoldMode = require("./folding/html").FoldMode; // defines the language specific highlighters and folding rules diff --git a/node_modules/ace/lib/ace/mode/d.js b/node_modules/ace/lib/ace/mode/d.js index 03c723e0..e48aced2 100644 --- a/node_modules/ace/lib/ace/mode/d.js +++ b/node_modules/ace/lib/ace/mode/d.js @@ -43,6 +43,7 @@ var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = DHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/dot.js b/node_modules/ace/lib/ace/mode/dot.js index 53ea6be8..c081869c 100644 --- a/node_modules/ace/lib/ace/mode/dot.js +++ b/node_modules/ace/lib/ace/mode/dot.js @@ -11,6 +11,7 @@ var Mode = function() { this.HighlightRules = DotHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.foldingRules = new DotFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/drools.js b/node_modules/ace/lib/ace/mode/drools.js index 1f408c59..3a361ec8 100644 --- a/node_modules/ace/lib/ace/mode/drools.js +++ b/node_modules/ace/lib/ace/mode/drools.js @@ -34,12 +34,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var DroolsHighlightRules = require("./drools_highlight_rules").DroolsHighlightRules; -var Range = require("../range").Range; var DroolsFoldMode = require("./folding/drools").FoldMode; var Mode = function() { this.HighlightRules = DroolsHighlightRules; this.foldingRules = new DroolsFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/eiffel.js b/node_modules/ace/lib/ace/mode/eiffel.js index f8ba173b..187ced1b 100644 --- a/node_modules/ace/lib/ace/mode/eiffel.js +++ b/node_modules/ace/lib/ace/mode/eiffel.js @@ -34,10 +34,10 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var EiffelHighlightRules = require("./eiffel_highlight_rules").EiffelHighlightRules; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = EiffelHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/elixir.js b/node_modules/ace/lib/ace/mode/elixir.js index c55ea366..d0eca10a 100644 --- a/node_modules/ace/lib/ace/mode/elixir.js +++ b/node_modules/ace/lib/ace/mode/elixir.js @@ -38,12 +38,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var ElixirHighlightRules = require("./elixir_highlight_rules").ElixirHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = ElixirHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/elm.js b/node_modules/ace/lib/ace/mode/elm.js index c12135a2..329e8131 100644 --- a/node_modules/ace/lib/ace/mode/elm.js +++ b/node_modules/ace/lib/ace/mode/elm.js @@ -38,12 +38,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var HighlightRules = require("./elm_highlight_rules").ElmHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = HighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/erlang.js b/node_modules/ace/lib/ace/mode/erlang.js index 615606ca..7ab9c026 100644 --- a/node_modules/ace/lib/ace/mode/erlang.js +++ b/node_modules/ace/lib/ace/mode/erlang.js @@ -38,12 +38,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var ErlangHighlightRules = require("./erlang_highlight_rules").ErlangHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = ErlangHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/forth.js b/node_modules/ace/lib/ace/mode/forth.js index 99268d24..21f45ffd 100644 --- a/node_modules/ace/lib/ace/mode/forth.js +++ b/node_modules/ace/lib/ace/mode/forth.js @@ -39,12 +39,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var ForthHighlightRules = require("./forth_highlight_rules").ForthHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = ForthHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/fortran.js b/node_modules/ace/lib/ace/mode/fortran.js index fcac3935..41985fa7 100644 --- a/node_modules/ace/lib/ace/mode/fortran.js +++ b/node_modules/ace/lib/ace/mode/fortran.js @@ -41,6 +41,7 @@ var Range = require("../range").Range; var Mode = function() { this.HighlightRules = FortranHighlightRules; this.foldingRules = new CStyleFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/ftl.js b/node_modules/ace/lib/ace/mode/ftl.js index b818b87e..949671c3 100644 --- a/node_modules/ace/lib/ace/mode/ftl.js +++ b/node_modules/ace/lib/ace/mode/ftl.js @@ -37,6 +37,7 @@ var FtlHighlightRules = require("./ftl_highlight_rules").FtlHighlightRules; var Mode = function() { this.HighlightRules = FtlHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/gcode.js b/node_modules/ace/lib/ace/mode/gcode.js index 40c97e30..6fa8e766 100644 --- a/node_modules/ace/lib/ace/mode/gcode.js +++ b/node_modules/ace/lib/ace/mode/gcode.js @@ -38,6 +38,7 @@ define(function(require, exports, module) { var Mode = function() { this.HighlightRules = GcodeHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/gherkin.js b/node_modules/ace/lib/ace/mode/gherkin.js index 63bf51af..0ad96183 100644 --- a/node_modules/ace/lib/ace/mode/gherkin.js +++ b/node_modules/ace/lib/ace/mode/gherkin.js @@ -36,6 +36,7 @@ var GherkinHighlightRules = require("./gherkin_highlight_rules").GherkinHighligh var Mode = function() { this.HighlightRules = GherkinHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/gitignore.js b/node_modules/ace/lib/ace/mode/gitignore.js index fa263985..17c03a9d 100644 --- a/node_modules/ace/lib/ace/mode/gitignore.js +++ b/node_modules/ace/lib/ace/mode/gitignore.js @@ -8,6 +8,7 @@ var GitignoreHighlightRules = require("./gitignore_highlight_rules").GitignoreHi var Mode = function() { this.HighlightRules = GitignoreHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/gobstones.js b/node_modules/ace/lib/ace/mode/gobstones.js index f337044b..f4fd08d6 100644 --- a/node_modules/ace/lib/ace/mode/gobstones.js +++ b/node_modules/ace/lib/ace/mode/gobstones.js @@ -8,6 +8,7 @@ var GobstonesHighlightRules = require("./gobstones_highlight_rules").GobstonesHi var Mode = function() { JavaScriptMode.call(this); this.HighlightRules = GobstonesHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, JavaScriptMode); diff --git a/node_modules/ace/lib/ace/mode/haml.js b/node_modules/ace/lib/ace/mode/haml.js index 59e63555..bce4e1e9 100644 --- a/node_modules/ace/lib/ace/mode/haml.js +++ b/node_modules/ace/lib/ace/mode/haml.js @@ -48,6 +48,7 @@ var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = HamlHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/haskell.js b/node_modules/ace/lib/ace/mode/haskell.js index 833ae5ca..1a064417 100644 --- a/node_modules/ace/lib/ace/mode/haskell.js +++ b/node_modules/ace/lib/ace/mode/haskell.js @@ -49,6 +49,7 @@ var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = HaskellHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/haskell_cabal.js b/node_modules/ace/lib/ace/mode/haskell_cabal.js index 027e9d9a..2e2880c7 100644 --- a/node_modules/ace/lib/ace/mode/haskell_cabal.js +++ b/node_modules/ace/lib/ace/mode/haskell_cabal.js @@ -47,6 +47,7 @@ var FoldMode = require("./folding/haskell_cabal").FoldMode; var Mode = function() { this.HighlightRules = CabalHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/ini.js b/node_modules/ace/lib/ace/mode/ini.js index e1b5944b..9a07397a 100644 --- a/node_modules/ace/lib/ace/mode/ini.js +++ b/node_modules/ace/lib/ace/mode/ini.js @@ -40,6 +40,7 @@ var FoldMode = require("./folding/ini").FoldMode; var Mode = function() { this.HighlightRules = IniHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/io.js b/node_modules/ace/lib/ace/mode/io.js index f3cd4cf0..fd1ecf85 100644 --- a/node_modules/ace/lib/ace/mode/io.js +++ b/node_modules/ace/lib/ace/mode/io.js @@ -37,13 +37,13 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; -var Tokenizer = require("../tokenizer").Tokenizer; var IoHighlightRules = require("./io_highlight_rules").IoHighlightRules; var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = IoHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); @@ -51,7 +51,7 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = "//"; this.blockComment = {start: "/*", end: "*/"}; // Extra logic goes here. - this.$id = "ace/mode/io" + this.$id = "ace/mode/io"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/node_modules/ace/lib/ace/mode/jade.js b/node_modules/ace/lib/ace/mode/jade.js index d298dac4..fb202766 100644 --- a/node_modules/ace/lib/ace/mode/jade.js +++ b/node_modules/ace/lib/ace/mode/jade.js @@ -43,8 +43,8 @@ var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = JadeHighlightRules; - this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/javascript.js b/node_modules/ace/lib/ace/mode/javascript.js index b6ebe5a0..eecda2e1 100644 --- a/node_modules/ace/lib/ace/mode/javascript.js +++ b/node_modules/ace/lib/ace/mode/javascript.js @@ -35,7 +35,6 @@ var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; var WorkerClient = require("../worker/worker_client").WorkerClient; var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; var CStyleFoldMode = require("./folding/cstyle").FoldMode; diff --git a/node_modules/ace/lib/ace/mode/javascript_highlight_rules.js b/node_modules/ace/lib/ace/mode/javascript_highlight_rules.js index 64de72d5..0161b8ca 100644 --- a/node_modules/ace/lib/ace/mode/javascript_highlight_rules.js +++ b/node_modules/ace/lib/ace/mode/javascript_highlight_rules.js @@ -171,6 +171,9 @@ var JavaScriptHighlightRules = function(options) { token : "punctuation.operator", regex : /[.](?![.])/, next : "property" + }, { + token : "storage.type", + regex : /=>/ }, { token : "keyword.operator", regex : /--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?\:|[!$%&*+\-~\/^]=?/, diff --git a/node_modules/ace/lib/ace/mode/julia.js b/node_modules/ace/lib/ace/mode/julia.js index ddba928f..62f08c4f 100644 --- a/node_modules/ace/lib/ace/mode/julia.js +++ b/node_modules/ace/lib/ace/mode/julia.js @@ -49,6 +49,7 @@ var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = JuliaHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/latex.js b/node_modules/ace/lib/ace/mode/latex.js index 24048d5e..5caf6af8 100644 --- a/node_modules/ace/lib/ace/mode/latex.js +++ b/node_modules/ace/lib/ace/mode/latex.js @@ -5,11 +5,11 @@ var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var LatexHighlightRules = require("./latex_highlight_rules").LatexHighlightRules; var LatexFoldMode = require("./folding/latex").FoldMode; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = LatexHighlightRules; this.foldingRules = new LatexFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/liquid.js b/node_modules/ace/lib/ace/mode/liquid.js index b16c2194..e20124f7 100644 --- a/node_modules/ace/lib/ace/mode/liquid.js +++ b/node_modules/ace/lib/ace/mode/liquid.js @@ -34,11 +34,11 @@ var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var LiquidHighlightRules = require("./liquid_highlight_rules").LiquidHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = LiquidHighlightRules; this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/lisp.js b/node_modules/ace/lib/ace/mode/lisp.js index 59c97939..24060800 100644 --- a/node_modules/ace/lib/ace/mode/lisp.js +++ b/node_modules/ace/lib/ace/mode/lisp.js @@ -42,6 +42,7 @@ var LispHighlightRules = require("./lisp_highlight_rules").LispHighlightRules; var Mode = function() { this.HighlightRules = LispHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/lua.js b/node_modules/ace/lib/ace/mode/lua.js index 03525681..de5999d8 100644 --- a/node_modules/ace/lib/ace/mode/lua.js +++ b/node_modules/ace/lib/ace/mode/lua.js @@ -42,6 +42,7 @@ var Mode = function() { this.HighlightRules = LuaHighlightRules; this.foldingRules = new LuaFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/lucene.js b/node_modules/ace/lib/ace/mode/lucene.js index 56743ef9..36983e92 100644 --- a/node_modules/ace/lib/ace/mode/lucene.js +++ b/node_modules/ace/lib/ace/mode/lucene.js @@ -7,6 +7,7 @@ var LuceneHighlightRules = require("./lucene_highlight_rules").LuceneHighlightRu var Mode = function() { this.HighlightRules = LuceneHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/makefile.js b/node_modules/ace/lib/ace/mode/makefile.js index efeca6ee..df599327 100644 --- a/node_modules/ace/lib/ace/mode/makefile.js +++ b/node_modules/ace/lib/ace/mode/makefile.js @@ -43,6 +43,7 @@ var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = MakefileHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/markdown.js b/node_modules/ace/lib/ace/mode/markdown.js index efabed89..a6aaffa0 100644 --- a/node_modules/ace/lib/ace/mode/markdown.js +++ b/node_modules/ace/lib/ace/mode/markdown.js @@ -49,6 +49,7 @@ var Mode = function() { }); this.foldingRules = new MarkdownFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/matlab.js b/node_modules/ace/lib/ace/mode/matlab.js index 44b20d0d..91f6bb63 100644 --- a/node_modules/ace/lib/ace/mode/matlab.js +++ b/node_modules/ace/lib/ace/mode/matlab.js @@ -34,10 +34,10 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var MatlabHighlightRules = require("./matlab_highlight_rules").MatlabHighlightRules; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = MatlabHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/maze.js b/node_modules/ace/lib/ace/mode/maze.js index 3f1c83c1..a23631f8 100644 --- a/node_modules/ace/lib/ace/mode/maze.js +++ b/node_modules/ace/lib/ace/mode/maze.js @@ -40,6 +40,7 @@ var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = MazeHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/mushcode.js b/node_modules/ace/lib/ace/mode/mushcode.js index 632c8955..9acf5ddd 100644 --- a/node_modules/ace/lib/ace/mode/mushcode.js +++ b/node_modules/ace/lib/ace/mode/mushcode.js @@ -40,6 +40,7 @@ var Range = require("../range").Range; var Mode = function() { this.HighlightRules = MushCodeRules; this.foldingRules = new PythonFoldMode("\\:"); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/mysql.js b/node_modules/ace/lib/ace/mode/mysql.js index d0f7c123..64b06eb7 100644 --- a/node_modules/ace/lib/ace/mode/mysql.js +++ b/node_modules/ace/lib/ace/mode/mysql.js @@ -33,10 +33,10 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("../mode/text").Mode; var MysqlHighlightRules = require("./mysql_highlight_rules").MysqlHighlightRules; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = MysqlHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/nix.js b/node_modules/ace/lib/ace/mode/nix.js index c8e62a08..3048a569 100644 --- a/node_modules/ace/lib/ace/mode/nix.js +++ b/node_modules/ace/lib/ace/mode/nix.js @@ -49,6 +49,7 @@ var Mode = function() { CMode.call(this); this.HighlightRules = NixHighlightRules; this.foldingRules = new CStyleFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, CMode); diff --git a/node_modules/ace/lib/ace/mode/nsis.js b/node_modules/ace/lib/ace/mode/nsis.js index 8ec4a884..b20fce74 100644 --- a/node_modules/ace/lib/ace/mode/nsis.js +++ b/node_modules/ace/lib/ace/mode/nsis.js @@ -38,12 +38,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var NSISHighlightRules = require("./nsis_highlight_rules").NSISHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = NSISHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/objectivec.js b/node_modules/ace/lib/ace/mode/objectivec.js index 99fdb410..be243606 100644 --- a/node_modules/ace/lib/ace/mode/objectivec.js +++ b/node_modules/ace/lib/ace/mode/objectivec.js @@ -48,6 +48,7 @@ var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = ObjectiveCHighlightRules; this.foldingRules = new CStyleFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/ocaml.js b/node_modules/ace/lib/ace/mode/ocaml.js index 6313d3fb..ff7825b0 100644 --- a/node_modules/ace/lib/ace/mode/ocaml.js +++ b/node_modules/ace/lib/ace/mode/ocaml.js @@ -39,6 +39,7 @@ var Range = require("../range").Range; var Mode = function() { this.HighlightRules = OcamlHighlightRules; + this.$behaviour = this.$defaultBehaviour; this.$outdent = new MatchingBraceOutdent(); }; diff --git a/node_modules/ace/lib/ace/mode/pascal.js b/node_modules/ace/lib/ace/mode/pascal.js index 944088ca..7958ce63 100644 --- a/node_modules/ace/lib/ace/mode/pascal.js +++ b/node_modules/ace/lib/ace/mode/pascal.js @@ -49,6 +49,7 @@ var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = PascalHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/perl.js b/node_modules/ace/lib/ace/mode/perl.js index 37387344..c736ac31 100644 --- a/node_modules/ace/lib/ace/mode/perl.js +++ b/node_modules/ace/lib/ace/mode/perl.js @@ -35,7 +35,6 @@ var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var PerlHighlightRules = require("./perl_highlight_rules").PerlHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { @@ -43,6 +42,7 @@ var Mode = function() { this.$outdent = new MatchingBraceOutdent(); this.foldingRules = new CStyleFoldMode({start: "^=(begin|item)\\b", end: "^=(cut)\\b"}); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/pgsql.js b/node_modules/ace/lib/ace/mode/pgsql.js index d9775837..68693db0 100755 --- a/node_modules/ace/lib/ace/mode/pgsql.js +++ b/node_modules/ace/lib/ace/mode/pgsql.js @@ -33,10 +33,10 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("../mode/text").Mode; var PgsqlHighlightRules = require("./pgsql_highlight_rules").PgsqlHighlightRules; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = PgsqlHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); @@ -50,7 +50,7 @@ oop.inherits(Mode, TextMode); } else { return this.$getIndent(line); // Keep whatever indent the previous line has } - } + }; this.$id = "ace/mode/pgsql"; }).call(Mode.prototype); diff --git a/node_modules/ace/lib/ace/mode/praat.js b/node_modules/ace/lib/ace/mode/praat.js index 7b100ef0..17afe269 100644 --- a/node_modules/ace/lib/ace/mode/praat.js +++ b/node_modules/ace/lib/ace/mode/praat.js @@ -35,13 +35,13 @@ var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var PraatHighlightRules = require("./praat_highlight_rules").PraatHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = PraatHighlightRules; - this.$outdent = new MatchingBraceOutdent(); + this.foldingRules = new CStyleFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/prolog.js b/node_modules/ace/lib/ace/mode/prolog.js index dc64b7ea..72a39943 100644 --- a/node_modules/ace/lib/ace/mode/prolog.js +++ b/node_modules/ace/lib/ace/mode/prolog.js @@ -43,12 +43,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var PrologHighlightRules = require("./prolog_highlight_rules").PrologHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = PrologHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/properties.js b/node_modules/ace/lib/ace/mode/properties.js index 558e52e7..0541db14 100644 --- a/node_modules/ace/lib/ace/mode/properties.js +++ b/node_modules/ace/lib/ace/mode/properties.js @@ -37,6 +37,7 @@ var PropertiesHighlightRules = require("./properties_highlight_rules").Propertie var Mode = function() { this.HighlightRules = PropertiesHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/python.js b/node_modules/ace/lib/ace/mode/python.js index c4e6cebe..38af6585 100644 --- a/node_modules/ace/lib/ace/mode/python.js +++ b/node_modules/ace/lib/ace/mode/python.js @@ -40,6 +40,7 @@ var Range = require("../range").Range; var Mode = function() { this.HighlightRules = PythonHighlightRules; this.foldingRules = new PythonFoldMode("\\:"); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/r.js b/node_modules/ace/lib/ace/mode/r.js index addedd1a..d69fcf62 100644 --- a/node_modules/ace/lib/ace/mode/r.js +++ b/node_modules/ace/lib/ace/mode/r.js @@ -44,12 +44,11 @@ define(function(require, exports, module) { var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var RHighlightRules = require("./r_highlight_rules").RHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; - var unicode = require("../unicode"); - var Mode = function() - { + var Mode = function(){ this.HighlightRules = RHighlightRules; this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/rdoc.js b/node_modules/ace/lib/ace/mode/rdoc.js index bd99d4ba..220025a6 100644 --- a/node_modules/ace/lib/ace/mode/rdoc.js +++ b/node_modules/ace/lib/ace/mode/rdoc.js @@ -40,13 +40,13 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var RDocHighlightRules = require("./rdoc_highlight_rules").RDocHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; var Mode = function(suppressHighlighting) { this.HighlightRules = RDocHighlightRules; this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/rst.js b/node_modules/ace/lib/ace/mode/rst.js index 7e38b66e..bde43b17 100644 --- a/node_modules/ace/lib/ace/mode/rst.js +++ b/node_modules/ace/lib/ace/mode/rst.js @@ -36,14 +36,14 @@ var TextMode = require("./text").Mode; var RSTHighlightRules = require("./rst_highlight_rules").RSTHighlightRules; var Mode = function() { - this.HighlightRules = RSTHighlightRules; + this.HighlightRules = RSTHighlightRules; }; oop.inherits(Mode, TextMode); (function() { - this.type = "text"; + this.type = "text"; - this.$id = "ace/mode/rst"; + this.$id = "ace/mode/rst"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/node_modules/ace/lib/ace/mode/rust.js b/node_modules/ace/lib/ace/mode/rust.js index 17b6d208..29ecef9f 100644 --- a/node_modules/ace/lib/ace/mode/rust.js +++ b/node_modules/ace/lib/ace/mode/rust.js @@ -39,12 +39,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var RustHighlightRules = require("./rust_highlight_rules").RustHighlightRules; -// TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.HighlightRules = RustHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/sass.js b/node_modules/ace/lib/ace/mode/sass.js index 3025e71e..1545f869 100644 --- a/node_modules/ace/lib/ace/mode/sass.js +++ b/node_modules/ace/lib/ace/mode/sass.js @@ -39,6 +39,7 @@ var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = SassHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/scad.js b/node_modules/ace/lib/ace/mode/scad.js index 78c77f10..40a87e19 100644 --- a/node_modules/ace/lib/ace/mode/scad.js +++ b/node_modules/ace/lib/ace/mode/scad.js @@ -35,7 +35,6 @@ var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var scadHighlightRules = require("./scad_highlight_rules").scadHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; var CStyleFoldMode = require("./folding/cstyle").FoldMode; diff --git a/node_modules/ace/lib/ace/mode/scala.js b/node_modules/ace/lib/ace/mode/scala.js index be7ccc5d..bbe2b1bf 100644 --- a/node_modules/ace/lib/ace/mode/scala.js +++ b/node_modules/ace/lib/ace/mode/scala.js @@ -7,7 +7,6 @@ var ScalaHighlightRules = require("./scala_highlight_rules").ScalaHighlightRules var Mode = function() { JavaScriptMode.call(this); - this.HighlightRules = ScalaHighlightRules; }; oop.inherits(Mode, JavaScriptMode); diff --git a/node_modules/ace/lib/ace/mode/scheme.js b/node_modules/ace/lib/ace/mode/scheme.js index 2360b3da..f7f93e9d 100644 --- a/node_modules/ace/lib/ace/mode/scheme.js +++ b/node_modules/ace/lib/ace/mode/scheme.js @@ -44,6 +44,7 @@ var MatchingParensOutdent = require("./matching_parens_outdent").MatchingParensO var Mode = function() { this.HighlightRules = SchemeHighlightRules; this.$outdent = new MatchingParensOutdent(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/snippets.js b/node_modules/ace/lib/ace/mode/snippets.js index 02652515..01ffe16a 100644 --- a/node_modules/ace/lib/ace/mode/snippets.js +++ b/node_modules/ace/lib/ace/mode/snippets.js @@ -99,6 +99,7 @@ var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = SnippetGroupHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/space.js b/node_modules/ace/lib/ace/mode/space.js index 6117d053..a839cdf7 100644 --- a/node_modules/ace/lib/ace/mode/space.js +++ b/node_modules/ace/lib/ace/mode/space.js @@ -11,6 +11,7 @@ var Mode = function() { // set everything up this.HighlightRules = SpaceHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); (function() { diff --git a/node_modules/ace/lib/ace/mode/sql.js b/node_modules/ace/lib/ace/mode/sql.js index e1bf0f14..3f267c5c 100644 --- a/node_modules/ace/lib/ace/mode/sql.js +++ b/node_modules/ace/lib/ace/mode/sql.js @@ -34,10 +34,10 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var SqlHighlightRules = require("./sql_highlight_rules").SqlHighlightRules; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = SqlHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/sqlserver.js b/node_modules/ace/lib/ace/mode/sqlserver.js index 5f24730c..69e4ffd8 100644 --- a/node_modules/ace/lib/ace/mode/sqlserver.js +++ b/node_modules/ace/lib/ace/mode/sqlserver.js @@ -34,12 +34,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var SqlServerHighlightRules = require("./sqlserver_highlight_rules").SqlHighlightRules; -var Range = require("../range").Range; var SqlServerFoldMode = require("./folding/sqlserver").FoldMode; var Mode = function() { this.HighlightRules = SqlServerHighlightRules; this.foldingRules = new SqlServerFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/stylus.js b/node_modules/ace/lib/ace/mode/stylus.js index 2c9c3cf8..ce92061c 100644 --- a/node_modules/ace/lib/ace/mode/stylus.js +++ b/node_modules/ace/lib/ace/mode/stylus.js @@ -48,6 +48,7 @@ var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = StylusHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/swift.js b/node_modules/ace/lib/ace/mode/swift.js index 9b35a144..cd8647de 100644 --- a/node_modules/ace/lib/ace/mode/swift.js +++ b/node_modules/ace/lib/ace/mode/swift.js @@ -46,6 +46,7 @@ var Mode = function() { this.HighlightRules = HighlightRules; this.foldingRules = new FoldMode(); this.$behaviour = new CstyleBehaviour(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/tcl.js b/node_modules/ace/lib/ace/mode/tcl.js index 09f09a7b..a7b0e6dd 100644 --- a/node_modules/ace/lib/ace/mode/tcl.js +++ b/node_modules/ace/lib/ace/mode/tcl.js @@ -42,6 +42,7 @@ var Mode = function() { this.HighlightRules = TclHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.foldingRules = new CStyleFoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/tex.js b/node_modules/ace/lib/ace/mode/tex.js index b1d610fb..aad07763 100644 --- a/node_modules/ace/lib/ace/mode/tex.js +++ b/node_modules/ace/lib/ace/mode/tex.js @@ -50,6 +50,7 @@ var Mode = function(suppressHighlighting) { else this.HighlightRules = TexHighlightRules; this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/text.js b/node_modules/ace/lib/ace/mode/text.js index d780fdb8..731d194e 100644 --- a/node_modules/ace/lib/ace/mode/text.js +++ b/node_modules/ace/lib/ace/mode/text.js @@ -44,7 +44,7 @@ var Mode = function() { }; (function() { - this.$behaviour = new CstyleBehaviour(); + this.$defaultBehaviour = new CstyleBehaviour(); this.tokenRe = new RegExp("^[" + unicode.packages.L diff --git a/node_modules/ace/lib/ace/mode/textile.js b/node_modules/ace/lib/ace/mode/textile.js index 9a1ea809..8419c409 100644 --- a/node_modules/ace/lib/ace/mode/textile.js +++ b/node_modules/ace/lib/ace/mode/textile.js @@ -39,6 +39,7 @@ var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutd var Mode = function() { this.HighlightRules = TextileHighlightRules; this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/toml.js b/node_modules/ace/lib/ace/mode/toml.js index 9f84323c..1c4148df 100644 --- a/node_modules/ace/lib/ace/mode/toml.js +++ b/node_modules/ace/lib/ace/mode/toml.js @@ -44,6 +44,7 @@ var FoldMode = require("./folding/ini").FoldMode; var Mode = function() { this.HighlightRules = TomlHighlightRules; this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/tsx.js b/node_modules/ace/lib/ace/mode/tsx.js index 81c038d0..06564e1a 100644 --- a/node_modules/ace/lib/ace/mode/tsx.js +++ b/node_modules/ace/lib/ace/mode/tsx.js @@ -38,7 +38,7 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var tsMode = require("./typescript").Mode; -var Mode = function() { +var Mode = function() { tsMode.call(this); this.$highlightRuleConfig = {jsx: true}; }; diff --git a/node_modules/ace/lib/ace/mode/vbscript.js b/node_modules/ace/lib/ace/mode/vbscript.js index ed0ec61d..569e2e80 100644 --- a/node_modules/ace/lib/ace/mode/vbscript.js +++ b/node_modules/ace/lib/ace/mode/vbscript.js @@ -46,6 +46,7 @@ var VBScriptHighlightRules = require("./vbscript_highlight_rules").VBScriptHighl var Mode = function() { this.HighlightRules = VBScriptHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/verilog.js b/node_modules/ace/lib/ace/mode/verilog.js index 1c7f3ef5..5c2ca733 100644 --- a/node_modules/ace/lib/ace/mode/verilog.js +++ b/node_modules/ace/lib/ace/mode/verilog.js @@ -38,6 +38,7 @@ var Range = require("../range").Range; var Mode = function() { this.HighlightRules = VerilogHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/vhdl.js b/node_modules/ace/lib/ace/mode/vhdl.js index 26057bcc..247ded94 100644 --- a/node_modules/ace/lib/ace/mode/vhdl.js +++ b/node_modules/ace/lib/ace/mode/vhdl.js @@ -33,10 +33,10 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var VHDLHighlightRules = require("./vhdl_highlight_rules").VHDLHighlightRules; -var Range = require("../range").Range; var Mode = function() { this.HighlightRules = VHDLHighlightRules; + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/ace/lib/ace/mode/yaml.js b/node_modules/ace/lib/ace/mode/yaml.js index 8f7782c3..aadbb8b5 100644 --- a/node_modules/ace/lib/ace/mode/yaml.js +++ b/node_modules/ace/lib/ace/mode/yaml.js @@ -41,6 +41,7 @@ var Mode = function() { this.HighlightRules = YamlHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); diff --git a/node_modules/c9/ssh.js b/node_modules/c9/ssh.js index af30da0c..5fd562fb 100644 --- a/node_modules/c9/ssh.js +++ b/node_modules/c9/ssh.js @@ -16,18 +16,17 @@ function quote(str) { return "'" + str.replace(/'/g, "'\\''") + "'"; } -function addProxyCommand(args, proxy) { - var m = /^(.+)(?::(\d+))?$/.exec(proxy); - if (!m) - return; - var proxyHost = m[1]; - var proxyPort = parseInt(m[2], 10) || 22; +exports.quote = quote; +exports.addProxyCommand = function(args, proxy) { + var m = proxy.split(":"); + var proxyHost = m[0]; + var proxyPort = parseInt(m[1], 10) || 22; var proxyCmd = "ProxyCommand=ssh -W %h:%p " + args.map(quote).join(" "); proxyCmd += " -p " + proxyPort + " " + quote(proxyHost); args.push( "-o", proxyCmd ); -} +}; exports.buildArgs = function(prvkeyFile, host, proxy) { var args = [ @@ -45,7 +44,7 @@ exports.buildArgs = function(prvkeyFile, host, proxy) { ]; if (proxy) - addProxyCommand(args, proxy); + exports.addProxyCommand(args, proxy); if (host) { host = host.split(":"); diff --git a/node_modules/c9/ssh_test.js b/node_modules/c9/ssh_test.js new file mode 100644 index 00000000..3dd9a4c3 --- /dev/null +++ b/node_modules/c9/ssh_test.js @@ -0,0 +1,47 @@ +"use strict"; + +"use server"; + +var assert = require("assert"); +var ssh = require("./ssh"); +function arrayEqual(a, b) { + assert.equal(a.length, b.length); + for (var i = 0; i < a.length; i++) + assert.equal(a[i], b[i]); +} + +module.exports = { + + "test quote" : function() { + assert.equal(ssh.quote("a'b'c"), "'a'\\''b'\\''c'"); + assert.equal(ssh.quote("abc"), "'abc'"); + }, + + "test buildArgs": function() { + var expectedArgs = [ + "-o","PasswordAuthentication=no", + "-o","IdentityFile=/key", + "-o","UserKnownHostsFile=/dev/null", + "-o","StrictHostKeyChecking=no", + "-o","IdentitiesOnly=yes", + "-F","/dev/null","-t","-t", + "-o","BatchMode=yes", + "-o","ConnectTimeout=10", + "-p",22,"foo12@124.255.121.12" + ]; + var proxyCmd = 'ProxyCommand=ssh -W %h:%p \'-o\' \'PasswordAuthentication=no\' \'-o\' \'IdentityFile=/key\' \'-o\' \'UserKnownHostsFile=/dev/null\' \'-o\' \'StrictHostKeyChecking=no\' \'-o\' \'IdentitiesOnly=yes\' \'-F\' \'/dev/null\' \'-t\' \'-t\' \'-o\' \'BatchMode=yes\' \'-o\' \'ConnectTimeout=10\' -p 22 \'24@100.20.12.12\''; + var args = ssh.buildArgs('/key', "foo12@124.255.121.12"); + arrayEqual(args, expectedArgs); + + args = ssh.buildArgs('/key', "foo12@124.255.121.12", "24@100.20.12.12"); + expectedArgs.splice(expectedArgs.length - 3, 0, "-o", proxyCmd); + arrayEqual(args, expectedArgs); + + args = ssh.buildArgs('/key', "foo12@124.255.121.12:1888", "24@100.20.12.12:88788"); + expectedArgs[expectedArgs.length - 2] = 1888; + expectedArgs[expectedArgs.length - 4] = expectedArgs[expectedArgs.length - 4].replace(22, 88788); + arrayEqual(args, expectedArgs); + }, +}; + +!module.parent && require("asyncjs").test.testcase(module.exports).exec(); diff --git a/node_modules/connect-architect/connect.session/decrypt.js b/node_modules/connect-architect/connect.session/decrypt.js new file mode 100644 index 00000000..cb4d450f --- /dev/null +++ b/node_modules/connect-architect/connect.session/decrypt.js @@ -0,0 +1,28 @@ +"use strict"; + +var utils = require("./session/utils"); + +function decrypt(secret, rawCookie) { + // ensure secret is available or bail + if (!secret) throw new Error('`secret` option required for sessions'); + + // secret is always an array of secrets + secret = [].concat(secret); + + for (var i = 0; i < secret.length; i++) { + var unsignedCookie = utils.parseSignedCookie(rawCookie, secret[i]); + + if (unsignedCookie && unsignedCookie !== rawCookie) { + var usedSecret = secret[i]; + + return { + unsignedCookie: unsignedCookie, + usedSecret: usedSecret + }; + } + } + + return {}; +} + +module.exports.decrypt = decrypt; \ No newline at end of file diff --git a/node_modules/connect-architect/connect.session/decrypt_test.js b/node_modules/connect-architect/connect.session/decrypt_test.js new file mode 100644 index 00000000..a588387b --- /dev/null +++ b/node_modules/connect-architect/connect.session/decrypt_test.js @@ -0,0 +1,39 @@ +#!/usr/bin/env node + +/*global describe it before after beforeEach afterEach */ +"use strict"; + +"use server"; + +require("c9/inline-mocha")(module); +require("c9/setup_paths"); + +var Cookie = require("cookie"); +var assert = require("assert"); +var ConnectCookie = require("./session/cookie"); + +var encrypt = require("./encrypt"); +var decrypt = require("./decrypt"); + +describe("decrypt", function() { + + it("Should decrypt when secret is a string", function(){ + var sessionID = Math.random().toString(36); + var secret = Math.random().toString(36); + var cookieVal = encrypt(sessionID, "connect.sid", new ConnectCookie({}), secret); + var cookie = Cookie.parse(cookieVal); + var val = decrypt.decrypt(secret, cookie["connect.sid"]); + + assert.deepEqual(val, { unsignedCookie: sessionID, usedSecret: secret }); + }); + + it("Should decrypt when secret is an array", function(){ + var sessionID = Math.random().toString(36); + var secret = [Math.random().toString(36), Math.random().toString(36), Math.random().toString(36)]; + var cookieVal = encrypt(sessionID, "connect.sid", new ConnectCookie({}), secret[1]); + var cookie = Cookie.parse(cookieVal); + var val = decrypt.decrypt(secret, cookie["connect.sid"]); + + assert.deepEqual(val, { unsignedCookie: sessionID, usedSecret: secret[1] }); + }); +}); \ No newline at end of file diff --git a/node_modules/connect-architect/connect.session/encrypt.js b/node_modules/connect-architect/connect.session/encrypt.js new file mode 100644 index 00000000..6960e0f6 --- /dev/null +++ b/node_modules/connect-architect/connect.session/encrypt.js @@ -0,0 +1,12 @@ +"use strict"; + +var signature = require("cookie-signature"); + +function encrypt(sessionID, key, cookie, secret) { + var val = 's:' + signature.sign(sessionID, secret); + val = cookie.serialize(key, val); + + return val; +} + +module.exports = encrypt; \ No newline at end of file diff --git a/node_modules/connect-architect/connect.session/session-ext.js b/node_modules/connect-architect/connect.session/session-ext.js index dd8cf6ea..18d26989 100644 --- a/node_modules/connect-architect/connect.session/session-ext.js +++ b/node_modules/connect-architect/connect.session/session-ext.js @@ -1,6 +1,5 @@ -var Session = require("connect").session; +var Session = require("./session"); var assert = require("assert"); -var error = require("http-error"); module.exports = function startup(options, imports, register) { diff --git a/node_modules/connect-architect/connect.session/session.js b/node_modules/connect-architect/connect.session/session.js new file mode 100644 index 00000000..1eaff1e4 --- /dev/null +++ b/node_modules/connect-architect/connect.session/session.js @@ -0,0 +1,338 @@ +/** + * MVH 2016 Forked from connect/middleware/session + * - Added support for multiple secrets + * - Remove MemoryStore + */ +/*! + * Connect - session + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Session = require('./session/session') + , debug = require('debug')('connect:session') + , Cookie = require('./session/cookie') + , Store = require('./session/store') + , utils = require('./session/utils') + , uid = require('uid2') + , parse = require('url').parse; + +var decrypt = require("./decrypt"); +var encrypt = require("./encrypt"); +var hash = require("./session/hash"); + +/** + * Expose the middleware. + */ + +exports = module.exports = session; + +/** + * Expose constructors. + */ + +exports.Store = Store; +exports.Cookie = Cookie; +exports.Session = Session; + +/** + * Session: + * + * Setup session store with the given `options`. + * + * Session data is _not_ saved in the cookie itself, however + * cookies are used, so we must use the [cookieParser()](cookieParser.html) + * middleware _before_ `session()`. + * + * Examples: + * + * connect() + * .use(connect.cookieParser()) + * .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) + * + * Options: + * + * - `key` cookie name defaulting to `connect.sid` + * - `store` session store instance + * - `secret` session cookie is signed with this secret to prevent tampering + * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` + * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") + * + * Cookie option: + * + * By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set + * so the cookie becomes a browser-session cookie. When the user closes the + * browser the cookie (and session) will be removed. + * + * ## req.session + * + * To store or access session data, simply use the request property `req.session`, + * which is (generally) serialized as JSON by the store, so nested objects + * are typically fine. For example below is a user-specific view counter: + * + * connect() + * .use(connect.favicon()) + * .use(connect.cookieParser()) + * .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) + * .use(function(req, res, next){ + * var sess = req.session; + * if (sess.views) { + * res.setHeader('Content-Type', 'text/html'); + * res.write('

views: ' + sess.views + '

'); + * res.write('

expires in: ' + (sess.cookie.maxAge / 1000) + 's

'); + * res.end(); + * sess.views++; + * } else { + * sess.views = 1; + * res.end('welcome to the session demo. refresh!'); + * } + * } + * )).listen(3000); + * + * ## Session#regenerate() + * + * To regenerate the session simply invoke the method, once complete + * a new SID and `Session` instance will be initialized at `req.session`. + * + * req.session.regenerate(function(err){ + * // will have a new session here + * }); + * + * ## Session#destroy() + * + * Destroys the session, removing `req.session`, will be re-generated next request. + * + * req.session.destroy(function(err){ + * // cannot access session here + * }); + * + * ## Session#reload() + * + * Reloads the session data. + * + * req.session.reload(function(err){ + * // session updated + * }); + * + * ## Session#save() + * + * Save the session. + * + * req.session.save(function(err){ + * // session saved + * }); + * + * ## Session#touch() + * + * Updates the `.maxAge` property. Typically this is + * not necessary to call, as the session middleware does this for you. + * + * ## Session#cookie + * + * Each session has a unique cookie object accompany it. This allows + * you to alter the session cookie per visitor. For example we can + * set `req.session.cookie.expires` to `false` to enable the cookie + * to remain for only the duration of the user-agent. + * + * ## Session#maxAge + * + * Alternatively `req.session.cookie.maxAge` will return the time + * remaining in milliseconds, which we may also re-assign a new value + * to adjust the `.expires` property appropriately. The following + * are essentially equivalent + * + * var hour = 3600000; + * req.session.cookie.expires = new Date(Date.now() + hour); + * req.session.cookie.maxAge = hour; + * + * For example when `maxAge` is set to `60000` (one minute), and 30 seconds + * has elapsed it will return `30000` until the current request has completed, + * at which time `req.session.touch()` is called to reset `req.session.maxAge` + * to its original value. + * + * req.session.cookie.maxAge; + * // => 30000 + * + * Session Store Implementation: + * + * Every session store _must_ implement the following methods + * + * - `.get(sid, callback)` + * - `.set(sid, session, callback)` + * - `.destroy(sid, callback)` + * + * Recommended methods include, but are not limited to: + * + * - `.length(callback)` + * - `.clear(callback)` + * + * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. + * + * @param {Object} options + * @return {Function} + * @api public + */ + +function session(options){ + var options = options || {} + , key = options.key || 'connect.sid' + , store = options.store + , cookie = options.cookie || {} + , trustProxy = options.proxy + , storeReady = true + , rollingSessions = options.rolling || false; + + // generates the new session + store.generate = function(req){ + req.sessionID = uid(24); + req.session = new Session(req); + req.session.cookie = new Cookie(cookie); + }; + + store.on('disconnect', function(){ storeReady = false; }); + store.on('connect', function(){ storeReady = true; }); + + return function session(req, res, next) { + // self-awareness + if (req.session) return next(); + + // Handle connection as if there is no session if + // the store has temporarily disconnected etc + if (!storeReady) return debug('store is disconnected'), next(); + + // pathname mismatch + var originalPath = parse(req.originalUrl).pathname; + if (0 != originalPath.indexOf(cookie.path || '/')) return next(); + + // backwards compatibility for signed cookies + // req.secret is passed from the cookie parser middleware + var secret = options.secret || req.secret; + + // ensure secret is available or bail + if (!secret) throw new Error('`secret` option required for sessions'); + + // normalize secret to be an array + secret = [].concat(secret); + + var originalHash + , originalId; + + // expose store + req.sessionStore = store; + + // grab the session cookie value and check the signature + var rawCookie = req.cookies[key]; + + // get signedCookies for backwards compat with signed cookies + var unsignedCookie = req.signedCookies[key]; + var usedSecret; + + if (!unsignedCookie && rawCookie) { + var values = decrypt.decrypt(secret, rawCookie); + + usedSecret = values.usedSecret; + unsignedCookie = values.unsignedCookie; + } + + // set-cookie + res.on('header', function(){ + if (!req.session) return; + + var cookie = req.session.cookie + , proto = (req.headers['x-forwarded-proto'] || '').split(',')[0].toLowerCase().trim() + , tls = req.connection.encrypted || (trustProxy && 'https' == proto) + , isNew = unsignedCookie != req.sessionID; + + // only send secure cookies via https + if (cookie.secure && !tls) return debug('not secured'); + + var masterSecret = secret[1] || secret[0]; + + // in case of rolling session, always reset the cookie + if (usedSecret == masterSecret && !rollingSessions) { + // browser-session length cookie + if (null == cookie.expires) { + if (!isNew) return debug('already set browser-session cookie'); + // compare hashes and ids + } else if (originalHash == hash.hash(req.session) && originalId == req.session.id) { + return debug('unmodified session'); + } + } + + var val = encrypt(req.sessionID, key, cookie, masterSecret); + debug('set-cookie %s', val); + res.setHeader('Set-Cookie', val); + }); + + // proxy end() to commit the session + var end = res.end; + res.end = function(data, encoding){ + res.end = end; + if (!req.session) return res.end(data, encoding); + debug('saving'); + req.session.resetMaxAge(); + req.session.save(function(err){ + if (err) console.error(err.stack); + debug('saved'); + res.end(data, encoding); + }); + }; + + // generate the session + function generate() { + store.generate(req); + } + + // get the sessionID from the cookie + req.sessionID = unsignedCookie; + + // generate a session if the browser doesn't send a sessionID + if (!req.sessionID) { + debug('no SID sent, generating session'); + generate(); + next(); + return; + } + + // generate the session object + var pause = utils.pause(req); + debug('fetching %s', req.sessionID); + store.get(req.sessionID, function(err, sess){ + // proxy to resume() events + var _next = next; + next = function(err){ + _next(err); + pause.resume(); + }; + + // error handling + if (err) { + debug('error %j', err); + if ('ENOENT' == err.code) { + generate(); + next(); + } else { + next(err); + } + // no session + } else if (!sess) { + debug('no session found'); + generate(); + next(); + // populate req.session + } else { + debug('session found'); + store.createSession(req, sess); + originalId = req.sessionID; + originalHash = hash.hash(sess); + next(); + } + }); + }; +}; + diff --git a/node_modules/connect-architect/connect.session/session/cookie.js b/node_modules/connect-architect/connect.session/session/cookie.js new file mode 100644 index 00000000..e07877f1 --- /dev/null +++ b/node_modules/connect-architect/connect.session/session/cookie.js @@ -0,0 +1,128 @@ + +/*! + * Connect - session - Cookie + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('./utils') + , cookie = require('cookie'); + +/** + * Initialize a new `Cookie` with the given `options`. + * + * @param {IncomingMessage} req + * @param {Object} options + * @api private + */ + +var Cookie = module.exports = function Cookie(options) { + this.path = '/'; + this.maxAge = null; + this.httpOnly = true; + if (options) utils.merge(this, options); + this.originalMaxAge = undefined == this.originalMaxAge + ? this.maxAge + : this.originalMaxAge; +}; + +/*! + * Prototype. + */ + +Cookie.prototype = { + + /** + * Set expires `date`. + * + * @param {Date} date + * @api public + */ + + set expires(date) { + this._expires = date; + this.originalMaxAge = this.maxAge; + }, + + /** + * Get expires `date`. + * + * @return {Date} + * @api public + */ + + get expires() { + return this._expires; + }, + + /** + * Set expires via max-age in `ms`. + * + * @param {Number} ms + * @api public + */ + + set maxAge(ms) { + this.expires = 'number' == typeof ms + ? new Date(Date.now() + ms) + : ms; + }, + + /** + * Get expires max-age in `ms`. + * + * @return {Number} + * @api public + */ + + get maxAge() { + return this.expires instanceof Date + ? this.expires.valueOf() - Date.now() + : this.expires; + }, + + /** + * Return cookie data object. + * + * @return {Object} + * @api private + */ + + get data() { + return { + originalMaxAge: this.originalMaxAge + , expires: this._expires + , secure: this.secure + , httpOnly: this.httpOnly + , domain: this.domain + , path: this.path + } + }, + + /** + * Return a serialized cookie string. + * + * @return {String} + * @api public + */ + + serialize: function(name, val){ + return cookie.serialize(name, val, this.data); + }, + + /** + * Return JSON representation of this cookie. + * + * @return {Object} + * @api private + */ + + toJSON: function(){ + return this.data; + } +}; diff --git a/node_modules/connect-architect/connect.session/session/hash.js b/node_modules/connect-architect/connect.session/session/hash.js new file mode 100644 index 00000000..8b995352 --- /dev/null +++ b/node_modules/connect-architect/connect.session/session/hash.js @@ -0,0 +1,18 @@ +var crc32 = require('buffer-crc32'); + +/** + * Hash the given `sess` object omitting changes + * to `.cookie`. + * + * @param {Object} sess + * @return {String} + * @api private + */ + +function hash(sess) { + return crc32.signed(JSON.stringify(sess, function(key, val){ + if ('cookie' != key) return val; + })); +} + +module.exports.hash = hash; diff --git a/node_modules/connect-architect/connect.session/session/memory.js b/node_modules/connect-architect/connect.session/session/memory.js new file mode 100644 index 00000000..fb939392 --- /dev/null +++ b/node_modules/connect-architect/connect.session/session/memory.js @@ -0,0 +1,129 @@ + +/*! + * Connect - session - MemoryStore + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Store = require('./store'); + +/** + * Initialize a new `MemoryStore`. + * + * @api public + */ + +var MemoryStore = module.exports = function MemoryStore() { + this.sessions = {}; +}; + +/** + * Inherit from `Store.prototype`. + */ + +MemoryStore.prototype.__proto__ = Store.prototype; + +/** + * Attempt to fetch session by the given `sid`. + * + * @param {String} sid + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.get = function(sid, fn){ + var self = this; + process.nextTick(function(){ + var expires + , sess = self.sessions[sid]; + if (sess) { + sess = JSON.parse(sess); + expires = 'string' == typeof sess.cookie.expires + ? new Date(sess.cookie.expires) + : sess.cookie.expires; + if (!expires || new Date < expires) { + fn(null, sess); + } else { + self.destroy(sid, fn); + } + } else { + fn(); + } + }); +}; + +/** + * Commit the given `sess` object associated with the given `sid`. + * + * @param {String} sid + * @param {Session} sess + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.set = function(sid, sess, fn){ + var self = this; + process.nextTick(function(){ + self.sessions[sid] = JSON.stringify(sess); + fn && fn(); + }); +}; + +/** + * Destroy the session associated with the given `sid`. + * + * @param {String} sid + * @api public + */ + +MemoryStore.prototype.destroy = function(sid, fn){ + var self = this; + process.nextTick(function(){ + delete self.sessions[sid]; + fn && fn(); + }); +}; + +/** + * Invoke the given callback `fn` with all active sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.all = function(fn){ + var arr = [] + , keys = Object.keys(this.sessions); + for (var i = 0, len = keys.length; i < len; ++i) { + arr.push(this.sessions[keys[i]]); + } + fn(null, arr); +}; + +/** + * Clear all sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.clear = function(fn){ + this.sessions = {}; + fn && fn(); +}; + +/** + * Fetch number of sessions. + * + * @param {Function} fn + * @api public + */ + +MemoryStore.prototype.length = function(fn){ + fn(null, Object.keys(this.sessions).length); +}; diff --git a/node_modules/connect-architect/connect.session/session/session.js b/node_modules/connect-architect/connect.session/session/session.js new file mode 100644 index 00000000..e82bc914 --- /dev/null +++ b/node_modules/connect-architect/connect.session/session/session.js @@ -0,0 +1,116 @@ + +/*! + * Connect - session - Session + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('./utils'); + +/** + * Create a new `Session` with the given request and `data`. + * + * @param {IncomingRequest} req + * @param {Object} data + * @api private + */ + +var Session = module.exports = function Session(req, data) { + Object.defineProperty(this, 'req', { value: req }); + Object.defineProperty(this, 'id', { value: req.sessionID }); + if ('object' == typeof data) utils.merge(this, data); +}; + +/** + * Update reset `.cookie.maxAge` to prevent + * the cookie from expiring when the + * session is still active. + * + * @return {Session} for chaining + * @api public + */ + +Session.prototype.touch = function(){ + return this.resetMaxAge(); +}; + +/** + * Reset `.maxAge` to `.originalMaxAge`. + * + * @return {Session} for chaining + * @api public + */ + +Session.prototype.resetMaxAge = function(){ + this.cookie.maxAge = this.cookie.originalMaxAge; + return this; +}; + +/** + * Save the session data with optional callback `fn(err)`. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.save = function(fn){ + this.req.sessionStore.set(this.id, this, fn || function(){}); + return this; +}; + +/** + * Re-loads the session data _without_ altering + * the maxAge properties. Invokes the callback `fn(err)`, + * after which time if no exception has occurred the + * `req.session` property will be a new `Session` object, + * although representing the same session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.reload = function(fn){ + var req = this.req + , store = this.req.sessionStore; + store.get(this.id, function(err, sess){ + if (err) return fn(err); + if (!sess) return fn(new Error('failed to load session')); + store.createSession(req, sess); + fn(); + }); + return this; +}; + +/** + * Destroy `this` session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.destroy = function(fn){ + delete this.req.session; + this.req.sessionStore.destroy(this.id, fn); + return this; +}; + +/** + * Regenerate this request's session. + * + * @param {Function} fn + * @return {Session} for chaining + * @api public + */ + +Session.prototype.regenerate = function(fn){ + this.req.sessionStore.regenerate(this.req, fn); + return this; +}; diff --git a/node_modules/connect-architect/connect.session/session/store.js b/node_modules/connect-architect/connect.session/session/store.js new file mode 100644 index 00000000..54294cbd --- /dev/null +++ b/node_modules/connect-architect/connect.session/session/store.js @@ -0,0 +1,84 @@ + +/*! + * Connect - session - Store + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter + , Session = require('./session') + , Cookie = require('./cookie'); + +/** + * Initialize abstract `Store`. + * + * @api private + */ + +var Store = module.exports = function Store(options){}; + +/** + * Inherit from `EventEmitter.prototype`. + */ + +Store.prototype.__proto__ = EventEmitter.prototype; + +/** + * Re-generate the given requests's session. + * + * @param {IncomingRequest} req + * @return {Function} fn + * @api public + */ + +Store.prototype.regenerate = function(req, fn){ + var self = this; + this.destroy(req.sessionID, function(err){ + self.generate(req); + fn(err); + }); +}; + +/** + * Load a `Session` instance via the given `sid` + * and invoke the callback `fn(err, sess)`. + * + * @param {String} sid + * @param {Function} fn + * @api public + */ + +Store.prototype.load = function(sid, fn){ + var self = this; + this.get(sid, function(err, sess){ + if (err) return fn(err); + if (!sess) return fn(); + var req = { sessionID: sid, sessionStore: self }; + sess = self.createSession(req, sess); + fn(null, sess); + }); +}; + +/** + * Create session from JSON `sess` data. + * + * @param {IncomingRequest} req + * @param {Object} sess + * @return {Session} + * @api private + */ + +Store.prototype.createSession = function(req, sess){ + var expires = sess.cookie.expires + , orig = sess.cookie.originalMaxAge; + sess.cookie = new Cookie(sess.cookie); + if ('string' == typeof expires) sess.cookie.expires = new Date(expires); + sess.cookie.originalMaxAge = orig; + req.session = new Session(req, sess); + return req.session; +}; diff --git a/node_modules/connect-architect/connect.session/session/utils.js b/node_modules/connect-architect/connect.session/session/utils.js new file mode 100644 index 00000000..9839bc33 --- /dev/null +++ b/node_modules/connect-architect/connect.session/session/utils.js @@ -0,0 +1,408 @@ + +/*! + * Connect - utils + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http') + , crypto = require('crypto') + , parse = require('url').parse + , sep = require('path').sep + , signature = require('cookie-signature') + , nodeVersion = process.versions.node.split('.'); + +// pause is broken in node < 0.10 +exports.brokenPause = parseInt(nodeVersion[0], 10) === 0 + && parseInt(nodeVersion[1], 10) < 10; + +/** + * Return `true` if the request has a body, otherwise return `false`. + * + * @param {IncomingMessage} req + * @return {Boolean} + * @api private + */ + +exports.hasBody = function(req) { + var encoding = 'transfer-encoding' in req.headers; + var length = 'content-length' in req.headers && req.headers['content-length'] !== '0'; + return encoding || length; +}; + +/** + * Extract the mime type from the given request's + * _Content-Type_ header. + * + * @param {IncomingMessage} req + * @return {String} + * @api private + */ + +exports.mime = function(req) { + var str = req.headers['content-type'] || ''; + return str.split(';')[0]; +}; + +/** + * Generate an `Error` from the given status `code` + * and optional `msg`. + * + * @param {Number} code + * @param {String} msg + * @return {Error} + * @api private + */ + +exports.error = function(code, msg){ + var err = new Error(msg || http.STATUS_CODES[code]); + err.status = code; + return err; +}; + +/** + * Return md5 hash of the given string and optional encoding, + * defaulting to hex. + * + * utils.md5('wahoo'); + * // => "e493298061761236c96b02ea6aa8a2ad" + * + * @param {String} str + * @param {String} encoding + * @return {String} + * @api private + */ + +exports.md5 = function(str, encoding){ + return crypto + .createHash('md5') + .update(str, 'utf8') + .digest(encoding || 'hex'); +}; + +/** + * Merge object b with object a. + * + * var a = { foo: 'bar' } + * , b = { bar: 'baz' }; + * + * utils.merge(a, b); + * // => { foo: 'bar', bar: 'baz' } + * + * @param {Object} a + * @param {Object} b + * @return {Object} + * @api private + */ + +exports.merge = function(a, b){ + if (a && b) { + for (var key in b) { + a[key] = b[key]; + } + } + return a; +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Sign the given `val` with `secret`. + * + * @param {String} val + * @param {String} secret + * @return {String} + * @api private + */ + +exports.sign = function(val, secret){ + console.warn('do not use utils.sign(), use https://github.com/visionmedia/node-cookie-signature') + return val + '.' + crypto + .createHmac('sha256', secret) + .update(val) + .digest('base64') + .replace(/=+$/, ''); +}; + +/** + * Unsign and decode the given `val` with `secret`, + * returning `false` if the signature is invalid. + * + * @param {String} val + * @param {String} secret + * @return {String|Boolean} + * @api private + */ + +exports.unsign = function(val, secret){ + console.warn('do not use utils.unsign(), use https://github.com/visionmedia/node-cookie-signature') + var str = val.slice(0, val.lastIndexOf('.')); + return exports.sign(str, secret) == val + ? str + : false; +}; + +/** + * Parse signed cookies, returning an object + * containing the decoded key/value pairs, + * while removing the signed key from `obj`. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +exports.parseSignedCookies = function(obj, secret){ + var ret = {}; + Object.keys(obj).forEach(function(key){ + var val = obj[key]; + if (0 == val.indexOf('s:')) { + val = signature.unsign(val.slice(2), secret); + if (val) { + ret[key] = val; + delete obj[key]; + } + } + }); + return ret; +}; + +/** + * Parse a signed cookie string, return the decoded value + * + * @param {String} str signed cookie string + * @param {String} secret + * @return {String} decoded value + * @api private + */ + +exports.parseSignedCookie = function(str, secret){ + return 0 == str.indexOf('s:') + ? signature.unsign(str.slice(2), secret) + : str; +}; + +/** + * Parse JSON cookies. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +exports.parseJSONCookies = function(obj){ + Object.keys(obj).forEach(function(key){ + var val = obj[key]; + var res = exports.parseJSONCookie(val); + if (res) obj[key] = res; + }); + return obj; +}; + +/** + * Parse JSON cookie string + * + * @param {String} str + * @return {Object} Parsed object or null if not json cookie + * @api private + */ + +exports.parseJSONCookie = function(str) { + if (0 == str.indexOf('j:')) { + try { + return JSON.parse(str.slice(2)); + } catch (err) { + // no op + } + } +}; + +/** + * Pause `data` and `end` events on the given `obj`. + * Middleware performing async tasks _should_ utilize + * this utility (or similar), to re-emit data once + * the async operation has completed, otherwise these + * events may be lost. Pause is only required for + * node versions less than 10, and is replaced with + * noop's otherwise. + * + * var pause = utils.pause(req); + * fs.readFile(path, function(){ + * next(); + * pause.resume(); + * }); + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +exports.pause = exports.brokenPause + ? require('pause') + : function () { + return { + end: noop, + resume: noop + } + } + +/** + * Strip `Content-*` headers from `res`. + * + * @param {ServerResponse} res + * @api private + */ + +exports.removeContentHeaders = function(res){ + if (!res._headers) return; + Object.keys(res._headers).forEach(function(field){ + if (0 == field.indexOf('content')) { + res.removeHeader(field); + } + }); +}; + +/** + * Check if `req` is a conditional GET request. + * + * @param {IncomingMessage} req + * @return {Boolean} + * @api private + */ + +exports.conditionalGET = function(req) { + return req.headers['if-modified-since'] + || req.headers['if-none-match']; +}; + +/** + * Respond with 401 "Unauthorized". + * + * @param {ServerResponse} res + * @param {String} realm + * @api private + */ + +exports.unauthorized = function(res, realm) { + res.statusCode = 401; + res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"'); + res.end('Unauthorized'); +}; + +/** + * Respond with 304 "Not Modified". + * + * @param {ServerResponse} res + * @param {Object} headers + * @api private + */ + +exports.notModified = function(res) { + exports.removeContentHeaders(res); + res.statusCode = 304; + res.end(); +}; + +/** + * Return an ETag in the form of `"-"` + * from the given `stat`. + * + * @param {Object} stat + * @return {String} + * @api private + */ + +exports.etag = function(stat) { + return '"' + stat.size + '-' + Number(stat.mtime) + '"'; +}; + +/** + * Parse the given Cache-Control `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +exports.parseCacheControl = function(str){ + var directives = str.split(',') + , obj = {}; + + for(var i = 0, len = directives.length; i < len; i++) { + var parts = directives[i].split('=') + , key = parts.shift().trim() + , val = parseInt(parts.shift(), 10); + + obj[key] = isNaN(val) ? true : val; + } + + return obj; +}; + +/** + * Parse the `req` url with memoization. + * + * @param {ServerRequest} req + * @return {Object} + * @api private + */ + +exports.parseUrl = function(req){ + var parsed = req._parsedUrl; + if (parsed && parsed.href == req.url) { + return parsed; + } else { + parsed = parse(req.url); + + if (parsed.auth && !parsed.protocol && ~parsed.href.indexOf('//')) { + // This parses pathnames, and a strange pathname like //r@e should work + parsed = parse(req.url.replace(/@/g, '%40')); + } + + return req._parsedUrl = parsed; + } +}; + +/** + * Parse byte `size` string. + * + * @param {String} size + * @return {Number} + * @api private + */ + +exports.parseBytes = require('bytes'); + +/** + * Normalizes the path separator from system separator + * to URL separator, aka `/`. + * + * @param {String} path + * @return {String} + * @api private + */ + +exports.normalizeSlashes = function normalizeSlashes(path) { + return path.split(sep).join('/'); +}; + +function noop() {} diff --git a/node_modules/connect-architect/connect.session/session_test.js b/node_modules/connect-architect/connect.session/session_test.js new file mode 100644 index 00000000..86052f1f --- /dev/null +++ b/node_modules/connect-architect/connect.session/session_test.js @@ -0,0 +1,186 @@ +#!/usr/bin/env node + +/*global describe it before after beforeEach afterEach */ +"use strict"; +"use server"; + +require("c9/inline-mocha")(module); +require("c9/setup_paths"); + +var assert = require("assert"); +var ConnectCookie = require("./session/cookie"); +var Cookie = require("cookie"); +var session = require("./session"); +var EventEmitter = require("events").EventEmitter; +var sinon = require("sinon"); + +var Store = require("connect").session.MemoryStore; + +var encrypt = require("./encrypt"); +var decrypt = require("./decrypt"); +var hash = require("./session/hash"); + +describe("lib/session", function() { + + function mockReq() { + var req = new EventEmitter(); + req.originalUrl = "/"; + req.cookies = {}; + req.signedCookies = {}; + req.headers = {}; + req.connection = {}; + + return req; + } + + function mockRes() { + var res = new EventEmitter(); + res.setHeader = function(key, value) {}; + sinon.spy(res, "setHeader"); + return res; + } + + it("Returns a middleware", function() { + var middleware = session({ + store: new Store() + }); + + assert.equal(middleware.length, 3, "Has an arity of 3"); + }); + + it("Encrypts a cookie", function(done) { + var middleware = session({ + store: new Store(), + secret: "limecat" + }); + + var res = mockRes(); + + middleware(mockReq(), res, function() { + res.emit("header"); + + assert.ok(res.setHeader.calledOnce); + var args = res.setHeader.args[0]; + + assert.equal(args[0], "Set-Cookie"); + assert.ok(/connect.sid=.+?; Path=\/; HttpOnly/.test(args[1])); + done(); + }); + }); + + it("Does not create a new cookie if the secret remains the same", function(done) { + var sessionID = "123"; + var secret = "limecat"; + + var cookieVal = encrypt(sessionID, "connect.sid", new ConnectCookie({}), secret); + + var req = mockReq(); + var res = mockRes(); + var store = new Store(); + + var mw = session({ + secret: ["newsecret", secret], + store: store + }); + + sinon.stub(hash, "hash", function() { + return; + }); + + req.cookies = Cookie.parse(cookieVal); + + mw(req, res, function() { + var sessionCalled = 0; + var sessionCookie = new ConnectCookie({}); + + // force the code down a certain path + sessionCookie.expires = new Date(Date.now() + 1000); + + Object.defineProperty(req, "session", { + get: function() { + sessionCalled++; + return { + cookie: sessionCookie + }; + } + }); + + res.emit("header"); + + assert.ok(hash.hash.calledOnce, "we know the hash got called (asserts the code path)"); + assert.equal(sessionCalled, 4, "session was accessed, this asserts the code-path"); + hash.hash.restore(); + assert.ok(res.setHeader.notCalled); + done(); + }); + }); + + it("Rotates the secret: it encrypts using the new secret", function(done) { + var sessionID = Math.random().toString(36); + var secret = [Math.random().toString(36), Math.random().toString(36), Math.random().toString(36)]; + + // use the encryption funciton used in session to create a fake cookie + var cookie = encrypt(sessionID, "connect.sid", new ConnectCookie({}), secret[2]); + var req = mockReq(); + var res = mockRes(); + + var mw = session({ + secret: secret, + store: new Store() + }); + + req.sessionID = sessionID; + req.cookies = Cookie.parse(cookie); + + var decryptSpy = sinon.spy(decrypt, "decrypt"); + + // forces code down the path in L262 + sinon.stub(hash, "hash", function() { + return; + }); + + mw(req, res, function() { + // The cookie must have been decrypted by know, using one of the + // available secrets. + assert.deepEqual(decryptSpy.returnValues[0], { + unsignedCookie: sessionID, + usedSecret: secret[2] + }, "our cookie was decrypted"); + + // in the "header" listener we check for the cookie. + var sessionCookie = new ConnectCookie({}); + + // forces the if on L259 + sessionCookie.expires = new Date(Date.now() + 1000); + + // we need to mock req.session. The listener assumes this to be + // set in a later code path. + req.session = { + cookie: sessionCookie + }; + + // kick of the listener + res.emit("header"); + + // check that L262 was NOT executed + assert.ok(hash.hash.notCalled, "hash should be called on L262"); + + // we expect we got a fresh cookie + assert.ok(res.setHeader.calledOnce, "we expect a new cookie"); + + var cookie = res.setHeader.args[0][1]; + var parsed = Cookie.parse(cookie); + + var val = decrypt.decrypt(secret[1], parsed["connect.sid"]); + + assert.deepEqual(val, { + unsignedCookie: req.sessionID, + usedSecret: secret[1] + }); + + hash.hash.restore(); + done(); + }); + }); + +}); \ No newline at end of file diff --git a/node_modules/msgpack-js/README.markdown b/node_modules/msgpack-js/README.markdown new file mode 100644 index 00000000..e8757048 --- /dev/null +++ b/node_modules/msgpack-js/README.markdown @@ -0,0 +1,41 @@ +# msgpack for node + +[![Build Status](https://secure.travis-ci.org/creationix/msgpack-js.png)](http://travis-ci.org/creationix/msgpack-js) + +A handwritten msgpack encoder and decoder for Node.JS. + +The original format can be found at + + +## Extension + +I've extended the format a little to allow for encoding and decoding of `undefined` and `Buffer` instances. + +This required three new type codes that were previously marked as "reserved". +This change means that using these new types will render your serialized data +incompatible with other messagepack implementations that don't have the same +extension. + +There are two new types for storing node `Buffer` instances. These work just +like "raw 16" and "raw 32" except they are node buffers instead of strings. + + buffer 16 11011000 0xd8 + buffer 32 11011001 0xd9 + +Also I've added a type for `undefined` that works just like the `null` type. + + undefined 11000100 0xc4 + +## Usage + +``` javascript +var msgpack = require('msgpack'); +var assert = require('assert'); + +var initial = {Hello: "World"}; +var encoded = msgpack.encode(initial); +var decoded = msgpack.decode(encoded); + +assert.deepEqual(initial, decoded); +``` + diff --git a/node_modules/msgpack-js/msgpack.js b/node_modules/msgpack-js/msgpack.js new file mode 100644 index 00000000..abfcc904 --- /dev/null +++ b/node_modules/msgpack-js/msgpack.js @@ -0,0 +1,473 @@ +exports.encode = function (value) { + var buffer = new Buffer(sizeof(value)); + encode(value, buffer, 0); + return buffer; +}; + +exports.decode = decode; + +// http://wiki.msgpack.org/display/MSGPACK/Format+specification +// I've extended the protocol to have two new types that were previously reserved. +// buffer 16 11011000 0xd8 +// buffer 32 11011001 0xd9 +// These work just like raw16 and raw32 except they are node buffers instead of strings. +// +// Also I've added a type for `undefined` +// undefined 11000100 0xc4 + +function Decoder(buffer, offset) { + this.offset = offset || 0; + this.buffer = buffer; +} +Decoder.prototype.map = function (length) { + var value = {}; + for (var i = 0; i < length; i++) { + var key = this.parse(); + value[key] = this.parse(); + } + return value; +}; +Decoder.prototype.buf = function (length) { + var value = this.buffer.slice(this.offset, this.offset + length); + this.offset += length; + return value; +}; +Decoder.prototype.raw = function (length) { + var value = this.buffer.toString('utf8', this.offset, this.offset + length); + this.offset += length; + return value; +}; +Decoder.prototype.array = function (length) { + var value = new Array(length); + for (var i = 0; i < length; i++) { + value[i] = this.parse(); + } + return value; +}; +Decoder.prototype.parse = function () { + var type = this.buffer[this.offset]; + var value, length; + // FixRaw + if ((type & 0xe0) === 0xa0) { + length = type & 0x1f; + this.offset++; + return this.raw(length); + } + // FixMap + if ((type & 0xf0) === 0x80) { + length = type & 0x0f; + this.offset++; + return this.map(length); + } + // FixArray + if ((type & 0xf0) === 0x90) { + length = type & 0x0f; + this.offset++; + return this.array(length); + } + // Positive FixNum + if ((type & 0x80) === 0x00) { + this.offset++; + return type; + } + // Negative Fixnum + if ((type & 0xe0) === 0xe0) { + value = this.buffer.readInt8(this.offset); + this.offset++; + return value; + } + switch (type) { + // raw 16 + case 0xda: + length = this.buffer.readUInt16BE(this.offset + 1); + this.offset += 3; + return this.raw(length); + // raw 32 + case 0xdb: + length = this.buffer.readUInt32BE(this.offset + 1); + this.offset += 5; + return this.raw(length); + // nil + case 0xc0: + this.offset++; + return null; + // false + case 0xc2: + this.offset++; + return false; + // true + case 0xc3: + this.offset++; + return true; + // undefined + case 0xc4: + this.offset++; + return undefined; + // uint8 + case 0xcc: + value = this.buffer[this.offset + 1]; + this.offset += 2; + return value; + // uint 16 + case 0xcd: + value = this.buffer.readUInt16BE(this.offset + 1); + this.offset += 3; + return value; + // uint 32 + case 0xce: + value = this.buffer.readUInt32BE(this.offset + 1); + this.offset += 5; + return value; + // uint64 + case 0xcf: + value = this.buffer.readUInt64BE(this.offset + 1); + this.offset += 9; + return value; + // int 8 + case 0xd0: + value = this.buffer.readInt8(this.offset + 1); + this.offset += 2; + return value; + // int 16 + case 0xd1: + value = this.buffer.readInt16BE(this.offset + 1); + this.offset += 3; + return value; + // int 32 + case 0xd2: + value = this.buffer.readInt32BE(this.offset + 1); + this.offset += 5; + return value; + // int 64 + case 0xd3: + value = this.buffer.readInt64BE(this.offset + 1); + this.offset += 9; + return value; + // map 16 + case 0xde: + length = this.buffer.readUInt16BE(this.offset + 1); + this.offset += 3; + return this.map(length); + // map 32 + case 0xdf: + length = this.buffer.readUInt32BE(this.offset + 1); + this.offset += 5; + return this.map(length); + // array 16 + case 0xdc: + length = this.buffer.readUInt16BE(this.offset + 1); + this.offset += 3; + return this.array(length); + // array 32 + case 0xdd: + length = this.buffer.readUInt32BE(this.offset + 1); + this.offset += 5; + return this.array(length); + // buffer 16 + case 0xd8: + length = this.buffer.readUInt16BE(this.offset + 1); + this.offset += 3; + return this.buf(length); + // buffer 32 + case 0xd9: + length = this.buffer.readUInt32BE(this.offset + 1); + this.offset += 5; + return this.buf(length); + // float + case 0xca: + value = this.buffer.readFloatBE(this.offset + 1); + this.offset += 5; + return value; + // double + case 0xcb: + value = this.buffer.readDoubleBE(this.offset + 1); + this.offset += 9; + return value; + } + throw new Error("Unknown type 0x" + type.toString(16)); +}; +function decode(buffer) { + var decoder = new Decoder(buffer); + var value = decoder.parse(); + if (decoder.offset !== buffer.length) throw new Error((buffer.length - decoder.offset) + " trailing bytes"); + return value; +} + +function encode(value, buffer, offset) { + var type = typeof value; + + // Strings Bytes + if (type === "string") { + var length = Buffer.byteLength(value); + // fix raw + if (length < 0x20) { + buffer[offset] = length | 0xa0; + length && buffer.write(value, offset + 1); + return 1 + length; + } + // raw 16 + if (length < 0x10000) { + buffer[offset] = 0xda; + buffer.writeUInt16BE(length, offset + 1); + buffer.write(value, offset + 3); + return 3 + length; + } + // raw 32 + if (length < 0x100000000) { + buffer[offset] = 0xdb; + buffer.writeUInt32BE(length, offset + 1); + buffer.write(value, offset + 5); + return 5 + length; + } + } + + if (Buffer.isBuffer(value)) { + var length = value.length; + // buffer 16 + if (length < 0x10000) { + buffer[offset] = 0xd8; + buffer.writeUInt16BE(length, offset + 1); + value.copy(buffer, offset + 3); + return 3 + length; + } + // buffer 32 + if (length < 0x100000000) { + buffer[offset] = 0xd9; + buffer.writeUInt32BE(length, offset + 1); + value.copy(buffer, offset + 5); + return 5 + length; + } + } + + if (type === "number") { + // Floating Point + if ((value << 0) !== value) { + buffer[offset] = 0xcb; + buffer.writeDoubleBE(value, offset + 1); + return 9; + } + + // Integers + if (value >=0) { + // positive fixnum + if (value < 0x80) { + buffer[offset] = value; + return 1; + } + // uint 8 + if (value < 0x100) { + buffer[offset] = 0xcc; + buffer[offset + 1] = value; + return 2; + } + // uint 16 + if (value < 0x10000) { + buffer[offset] = 0xcd; + buffer.writeUInt16BE(value, offset + 1); + return 3; + } + // uint 32 + if (value < 0x100000000) { + buffer[offset] = 0xce; + buffer.writeUInt32BE(value, offset + 1); + return 5; + } + // uint 64 + if (value < 0x10000000000000000) { + buffer[offset] = 0xcf; + buffer.writeUInt64BE(value, offset + 1); + return 9; + } + throw new Error("Number too big 0x" + value.toString(16)); + } + // negative fixnum + if (value >= -0x20) { + buffer.writeInt8(value, offset); + return 1; + } + // int 8 + if (value >= -0x80) { + buffer[offset] = 0xd0; + buffer.writeInt8(value, offset + 1); + return 2; + } + // int 16 + if (value >= -0x8000) { + buffer[offset] = 0xd1; + buffer.writeInt16BE(value, offset + 1); + return 3; + } + // int 32 + if (value >= -0x80000000) { + buffer[offset] = 0xd2; + buffer.writeInt32BE(value, offset + 1); + return 5; + } + // int 64 + if (value >= -0x8000000000000000) { + buffer[offset] = 0xd3; + buffer.writeInt64BE(value, offset + 1); + return 9; + } + throw new Error("Number too small -0x" + value.toString(16).substr(1)); + } + + // undefined + if (type === "undefined") { + buffer[offset] = 0xc4; + return 1; + } + + // null + if (value === null) { + buffer[offset] = 0xc0; + return 1; + } + + // Boolean + if (type === "boolean") { + buffer[offset] = value ? 0xc3 : 0xc2; + return 1; + } + + // Container Types + if (type === "object") { + var length, size = 0; + var isArray = Array.isArray(value); + + if (isArray) { + length = value.length; + } + else { + var keys = Object.keys(value); + length = keys.length; + } + + var size; + if (length < 0x10) { + buffer[offset] = length | (isArray ? 0x90 : 0x80); + size = 1; + } + else if (length < 0x10000) { + buffer[offset] = isArray ? 0xdc : 0xde; + buffer.writeUInt16BE(length, offset + 1); + size = 3; + } + else if (length < 0x100000000) { + buffer[offset] = isArray ? 0xdd : 0xdf; + buffer.writeUInt32BE(length, offset + 1); + size = 5; + } + + if (isArray) { + for (var i = 0; i < length; i++) { + size += encode(value[i], buffer, offset + size); + } + } + else { + for (var i = 0; i < length; i++) { + var key = keys[i]; + size += encode(key, buffer, offset + size); + size += encode(value[key], buffer, offset + size); + } + } + + return size; + } + throw new Error("Unknown type " + type); +} + +function sizeof(value) { + var type = typeof value; + + // Raw Bytes + if (type === "string") { + var length = Buffer.byteLength(value); + if (length < 0x20) { + return 1 + length; + } + if (length < 0x10000) { + return 3 + length; + } + if (length < 0x100000000) { + return 5 + length; + } + } + + if (Buffer.isBuffer(value)) { + var length = value.length; + if (length < 0x10000) { + return 3 + length; + } + if (length < 0x100000000) { + return 5 + length; + } + } + + if (type === "number") { + // Floating Point + // double + if (value << 0 !== value) return 9; + + // Integers + if (value >=0) { + // positive fixnum + if (value < 0x80) return 1; + // uint 8 + if (value < 0x100) return 2; + // uint 16 + if (value < 0x10000) return 3; + // uint 32 + if (value < 0x100000000) return 5; + // uint 64 + if (value < 0x10000000000000000) return 9; + throw new Error("Number too big 0x" + value.toString(16)); + } + // negative fixnum + if (value >= -0x20) return 1; + // int 8 + if (value >= -0x80) return 2; + // int 16 + if (value >= -0x8000) return 3; + // int 32 + if (value >= -0x80000000) return 5; + // int 64 + if (value >= -0x8000000000000000) return 9; + throw new Error("Number too small -0x" + value.toString(16).substr(1)); + } + + // Boolean, null, undefined + if (type === "boolean" || type === "undefined" || value === null) return 1; + + // Container Types + if (type === "object") { + var length, size = 0; + if (Array.isArray(value)) { + length = value.length; + for (var i = 0; i < length; i++) { + size += sizeof(value[i]); + } + } + else { + var keys = Object.keys(value); + length = keys.length; + for (var i = 0; i < length; i++) { + var key = keys[i]; + size += sizeof(key) + sizeof(value[key]); + } + } + if (length < 0x10) { + return 1 + size; + } + if (length < 0x10000) { + return 3 + size; + } + if (length < 0x100000000) { + return 5 + size; + } + throw new Error("Array or object too long 0x" + length.toString(16)); + } + throw new Error("Unknown type " + type); +} + + diff --git a/node_modules/msgpack-js/package.json b/node_modules/msgpack-js/package.json new file mode 100644 index 00000000..1faefac8 --- /dev/null +++ b/node_modules/msgpack-js/package.json @@ -0,0 +1,25 @@ +{ + "author": { + "name": "Tim Caswell", + "email": "tim@creationix.com" + }, + "name": "msgpack-js", + "description": "msgpack encoder and decoder in pure node js", + "version": "0.1.5", + "repository": { + "type": "git", + "url": "git://github.com/creationix/msgpack-js.git" + }, + "main": "msgpack.js", + "engines": { + "node": ">=0.6.0" + }, + "dependencies": {}, + "devDependencies": {}, + "optionalDependencies": {}, + "readmeFilename": "README.markdown", + "bugs": { + "url": "https://github.com/creationix/msgpack-js/issues" + }, + "homepage": "https://github.com/creationix/msgpack-js#readme" +} diff --git a/node_modules/smith/smith.js b/node_modules/smith/smith.js index d0f8d989..b97fe583 100644 --- a/node_modules/smith/smith.js +++ b/node_modules/smith/smith.js @@ -363,7 +363,7 @@ Agent.prototype.send = function (message) { } try { var result = this.transport.send(message); } - catch(e) { console.error("Could not send message: ", e.message ); } + catch(e) { console.error("Agent Smith Could not send message: ", e.stack, e.message); } return result; }; diff --git a/package.json b/package.json index 51fa97dd..2d8879fe 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "c9", "description": "New Cloud9 Client", - "version": "3.1.2952", + "version": "3.1.3131", "author": "Ajax.org B.V. ", "private": true, "main": "bin/c9", @@ -16,7 +16,7 @@ "connect": "~2.12.0", "debug": "~0.7.4", "ejs": "~1.0.0", - "emmet": "git://github.com/cloud9ide/emmet-core.git#2ff6dc06ad", + "emmet": "git+https://github.com/cloud9ide/emmet-core.git#2ff6dc06ad", "engine.io": "1.6.9", "engine.io-client": "1.6.9", "jsonm": "1.0.6", @@ -25,19 +25,19 @@ "mime": "~1.2.9", "mkdirp": "~0.3.5", "msgpack-js-browser": "~0.1.4", - "nak": "https://github.com/cloud9ide/nak.git#6deef931594", + "nak": "git+https://github.com/cloud9ide/nak.git#6deef931594", "netutil": "~0.0.2", "optimist": "~0.6.0", "qs": "0.6.6", "rusha": "^0.8.3", "send": "~0.1.4", "simple-mime": "~0.0.8", - "tern": "https://github.com/cloud9ide/tern.git#39015d544d4c00c7899fea4c95c2e5bc2720e68e", - "tern_from_ts": "https://github.com/cloud9ide/tern_from_ts.git#84d51dcb9b16b126a206789d4d4237cde2801fe4", + "tern": "git+https://github.com/cloud9ide/tern.git#39015d544d4c00c7899fea4c95c2e5bc2720e68e", + "tern_from_ts": "git+https://github.com/cloud9ide/tern_from_ts.git#84d51dcb9b16b126a206789d4d4237cde2801fe4", "through": "2.2.0", "tmp": "~0.0.20", "uglify-js": "~2.6.2", - "ws": "0.4.31", + "ws": "1.0.1", "read": "~1.0.5", "form-data": "~0.2.0", "chai": "~1.5.0", @@ -54,10 +54,11 @@ "amd-loader", "architect", "architect-build", + "msgpack-js", "c9" ], "c9plugins": { - "c9.ide.language": "#0426ee345b", + "c9.ide.language": "#f55c832376", "c9.ide.language.core": "#bfb5dd2acc", "c9.ide.language.css": "#46ad561506", "c9.ide.language.generic": "#b47cbe58f9", @@ -69,17 +70,17 @@ "c9.ide.language.javascript.tern": "#0545a6385d", "c9.ide.language.javascript.infer": "#b9c2e4bdb8", "c9.ide.language.jsonalyzer": "#a0549e14ff", - "c9.ide.language.codeintel": "#4e0a272229", - "c9.ide.collab": "#321a40889f", + "c9.ide.language.codeintel": "#0fe92d6f46", + "c9.ide.collab": "#54aa1cbee0", "c9.ide.local": "#9169fec157", "c9.ide.find": "#e632ecf4be", "c9.ide.find.infiles": "#ad9ff74638", "c9.ide.find.replace": "#8468067976", - "c9.ide.run.debug": "#651451a7c2", + "c9.ide.run.debug": "#f10c7e7d19", "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#6dc4585e02", "c9.ide.ace.gotoline": "#d33220b1e0", - "c9.ide.ace.keymaps": "#334a65192f", + "c9.ide.ace.keymaps": "#15e7d23a2a", "c9.ide.ace.repl": "#4b88a85b7b", "c9.ide.ace.split": "#0ae0151c78", "c9.ide.ace.statusbar": "#3aab0b67e0", @@ -89,7 +90,7 @@ "c9.ide.configuration": "#a936df26bb", "c9.ide.dialog.wizard": "#7667ec79a8", "c9.ide.fontawesome": "#781602c5d8", - "c9.ide.format": "#f99082ff4c", + "c9.ide.format": "#1e7a5b30a3", "c9.ide.help.support": "#fbe8eb5c36", "c9.ide.imgeditor": "#612e75ef4f", "c9.ide.immediate": "#0b0ee744f9", @@ -107,7 +108,7 @@ "c9.ide.recentfiles": "#7c099abf40", "c9.ide.remote": "#301d2ab519", "c9.ide.processlist": "#2b12cd1bdd", - "c9.ide.run": "#bf68394c6f", + "c9.ide.run": "#3cd1f257ca", "c9.ide.run.build": "#0598fff697", "c9.ide.run.debug.xdebug": "#054367574c", "c9.ide.save": "#25a63f31e2", @@ -119,7 +120,7 @@ "c9.ide.threewaymerge": "#229382aa0b", "c9.ide.undo": "#b028bcb4d5", "c9.ide.upload": "#e4351f5a2b", - "c9.ide.welcome": "#5b86c44e92", + "c9.ide.welcome": "#7b75aefc28", "c9.ide.guide": "#19f6087429" } } \ No newline at end of file diff --git a/plugins/c9.ide.ace/ace.js b/plugins/c9.ide.ace/ace.js index 98172b82..da050694 100644 --- a/plugins/c9.ide.ace/ace.js +++ b/plugins/c9.ide.ace/ace.js @@ -241,32 +241,33 @@ define(function(require, exports, module) { ["newLineMode", "unix", STRING, "newlinemode", 1], // Per document ["tabSize", "4", NUMBER, "tabsize", 1], - ["useSoftTabs", "true", BOOL, "softtabs", 1], - ["guessTabSize", "true", BOOL, "guesstabsize", 1], - ["useWrapMode", "false", BOOL, "wrapmode"], - ["wrapToView", "true", BOOL, "wrapmodeViewport"], + ["useSoftTabs", true, BOOL, "softtabs", 1], + ["guessTabSize", true, BOOL, "guesstabsize", 1], + ["useWrapMode", false, BOOL, "wrapmode"], + ["wrapToView", true, BOOL, "wrapmodeViewport"], // Ace ["fontSize", "12", NUMBER, "fontsize"], ["fontFamily", font, STRING, "fontfamily"], - ["antialiasedfonts", "false", BOOL], - ["overwrite", "false", BOOL, "overwrite"], + ["antialiasedfonts", false, BOOL], + ["overwrite", false, BOOL, "overwrite"], ["selectionStyle", "line", STRING, "selectstyle"], ["cursorStyle", "ace", STRING, "cursorstyle"], - ["highlightActiveLine", "true", BOOL, "activeline"], - ["highlightGutterLine", "true", BOOL, "gutterline"], - ["showInvisibles", "false", BOOL, "showinvisibles"], - ["showPrintMargin", "true", BOOL, "showprintmargin"], - ["displayIndentGuides", "true", BOOL, "showindentguides"], + ["highlightActiveLine", true, BOOL, "activeline"], + ["highlightGutterLine", true, BOOL, "gutterline"], + ["showInvisibles", false, BOOL, "showinvisibles"], + ["showPrintMargin", true, BOOL, "showprintmargin"], + ["displayIndentGuides", true, BOOL, "showindentguides"], ["printMarginColumn", "80", NUMBER, "printmargincolumn"], - ["behavioursEnabled", "true", BOOL, "behaviors"], - ["wrapBehavioursEnabled", "false", BOOL, "wrapbehaviors"], + ["behavioursEnabled", true, BOOL, "behaviors"], + ["wrapBehavioursEnabled", false, BOOL, "wrapbehaviors"], ["scrollSpeed", "2", NUMBER, "scrollspeed"], - ["showGutter", "true", BOOL, "gutter"], - ["showFoldWidgets", "true", BOOL, "folding"], - ["fadeFoldWidgets", "true", BOOL, "fadefoldwidgets"], - ["highlightSelectedWord", "true", BOOL, "highlightselectedword"], - ["animatedScroll", "true", BOOL, "animatedscroll"], + ["showGutter", true, BOOL, "gutter"], + ["showLineNumbers", true, STRING], + ["showFoldWidgets", true, BOOL, "folding"], + ["fadeFoldWidgets", true, BOOL, "fadefoldwidgets"], + ["highlightSelectedWord", true, BOOL, "highlightselectedword"], + ["animatedScroll", true, BOOL, "animatedscroll"], ["scrollPastEnd", "0.5", NUMBER], ["mergeUndoDeltas", "off", STRING], ["theme", defaultThemes[skin], STRING, "theme"] @@ -588,8 +589,26 @@ define(function(require, exports, module) { new Divider({ position: 60 }, handle) ] }, handle); + menus.addItemByPath("context/ace/", mnuAce, 0, handle); + + menus.addItemByPath("context/ace-gutter/", mnuGutter = new Menu({ + id: "menuGutter", + items: [ + new Divider({ position: 1000 }, handle), + ] + }, handle), 0, handle); + menus.addItemByPath("context/ace-gutter/Gutter Options/", new ui.menu({}), 1100, handle); + menus.addItemByPath("context/ace-gutter/Gutter Options/Show Line Numbers", new ui.item({ + caption: "Show Line Numbers", + type: "check", + checked: "user/ace/@showLineNumbers" + }, handle), 100, handle); + menus.addItemByPath("context/ace-gutter/Gutter Options/Show Fold Widgets", new ui.item({ + caption: "Show Fold Widgets", + type: "check", + checked: "user/ace/@showFoldWidgets" + }, handle), 200, handle); - mnuGutter = new Menu({ id: "menuGutter" }, handle); mnuGutter.on("show", function(e) { var ace = tabs.focussedTab.editor.ace; var region = ace.renderer.$gutterLayer.getRegion(e); @@ -825,6 +844,17 @@ define(function(require, exports, module) { position: 6000, path: "user/ace/@showGutter" }, + "Show Line Numbers" : { + type: "dropdown", + width: 150, + path: "user/ace/@showLineNumbers", + items: [ + { caption : "Normal", value : true }, + { caption : "Relative", value : "relative" }, + { caption : "None", value : false } + ], + position: 6250 + }, "Show Indent Guides" : { type: "checkbox", position: 6500, @@ -1531,6 +1561,41 @@ define(function(require, exports, module) { return s; } + /***** Gutter Renderers *****/ + + var relativeNumbers = { + getText: function(session, row) { + return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? "\xb7" : ""))) + ""; + }, + getWidth: function(session, lastLineNumber, config) { + return session.getLength().toString().length * config.characterWidth; + }, + update: function(e, editor) { + editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER); + }, + attach: function(editor) { + editor.renderer.$gutterLayer.$renderer = this; + editor.on("changeSelection", this.update); + }, + detach: function(editor) { + editor.renderer.$gutterLayer.$renderer = null; + editor.off("changeSelection", this.update); + } + }; + + var noNumbers = { + getText: function(session, row) { + return ""; + }, + getWidth: function(session, lastLineNumber, config) { + return ""; + }, + attach: function(editor) { + }, + detach: function(editor) { + }, + }; + /** * The ace handle, responsible for events that involve all ace * instances. This is the object you get when you request the ace @@ -2148,6 +2213,23 @@ define(function(require, exports, module) { if (session) session.$guessTabSize = false; break; + case "showLineNumbers": + var renderer = ace.renderer; + var gutterRenderer = renderer.$gutterLayer.$renderer; + if (gutterRenderer && gutterRenderer.detach) + gutterRenderer.detach(ace); + if (value == "relative") + gutterRenderer = relativeNumbers; + else if (value) + gutterRenderer = null; + else + gutterRenderer = noNumbers; + dom.setCssClass(renderer.$gutter, "ace_gutter-compact", !value); + renderer.$gutterLayer.$renderer = gutterRenderer; + if (gutterRenderer && gutterRenderer.attach) + gutterRenderer.attach(ace); + renderer.$loop.schedule(renderer.CHANGE_GUTTER); + return; } if (session && docLut[name]) // this can be called for session different than current ace session diff --git a/plugins/c9.ide.ace/style.less b/plugins/c9.ide.ace/style.less index 8d263c67..bd5e1d3c 100644 --- a/plugins/c9.ide.ace/style.less +++ b/plugins/c9.ide.ace/style.less @@ -26,6 +26,15 @@ z-index : -1; } +.ace_gutter-compact:not(.ace_folding-enabled) > .ace_gutter-layer > .ace_gutter-cell { + padding-left: 15px!important; + padding-right: 5px!important; +} +.ace_gutter-compact.ace_folding-enabled > .ace_gutter-layer > .ace_gutter-cell { + padding-left: 16px!important; + padding-right: 12px!important; +} + .dark .ace_gutter .ace_gutter_active_line { background-color: rgba(255, 255, 255, 0.07); } diff --git a/plugins/c9.ide.layout.classic/themes/default-flat-light.less b/plugins/c9.ide.layout.classic/themes/default-flat-light.less index 74aa8f16..aec1cd3f 100644 --- a/plugins/c9.ide.layout.classic/themes/default-flat-light.less +++ b/plugins/c9.ide.layout.classic/themes/default-flat-light.less @@ -328,7 +328,7 @@ @time-slider-revert-active-gradient: linear-gradient(top, #98c878 0%, #98c878 100%); @time-slider-revert-active-padding: @time-slider-revert-padding; -@time-slider-close-image: "@{image-path}/close_tab_btn_flat_light.png"; +@time-slider-close-image: "@{image-path}/close_tab_btn.png"; @time-slider-close-image-width: 42px; @time-slider-close-image-height: 28px; @time-slider-close-idle-position: 0 0; @@ -1711,4 +1711,4 @@ @form-bar-border-bottom: 1px solid #DEDEDE; @form-bar-box-shadow: 0 1px @border-highlight; -@panel-settings-changes-top: 53px; \ No newline at end of file +@panel-settings-changes-top: 53px; diff --git a/plugins/c9.ide.tree/tree.js b/plugins/c9.ide.tree/tree.js index 4dfb3dbc..6d28ceac 100644 --- a/plugins/c9.ide.tree/tree.js +++ b/plugins/c9.ide.tree/tree.js @@ -551,6 +551,7 @@ define(function(require, exports, module) { var mnuCtxTree = plugin.getElement("mnuCtxTree"); menus.decorate(mnuCtxTree); plugin.addElement(mnuCtxTree); + menus.addItemByPath("context/tree/", mnuCtxTree, 0, plugin); menus.addItemToMenu(mnuCtxTree, new ui.item({ match: "file", diff --git a/plugins/c9.ide.ui/menus.js b/plugins/c9.ide.ui/menus.js index 0c06c306..e4266d09 100644 --- a/plugins/c9.ide.ui/menus.js +++ b/plugins/c9.ide.ui/menus.js @@ -466,14 +466,14 @@ define(function(require, exports, module) { return; } + if (!plugin) + plugin = menu, menu = null; if (index && typeof index == "object") plugin = index, index = null; - else if (menu instanceof Menu) + else if (!plugin && menu && menu.aml) menu = menu.aml; - else if (menu && !menu.nodeFunc) - plugin = menu, menu = null; - if (menuItem instanceof MenuItem || menuItem instanceof Divider) + if (menuItem && menuItem.aml) menuItem = menuItem.aml; assert(plugin !== undefined, "addItemByPath requires a plugin argument"); diff --git a/plugins/c9.ide.watcher/gui.js b/plugins/c9.ide.watcher/gui.js index 011c7b4f..cec4bd21 100644 --- a/plugins/c9.ide.watcher/gui.js +++ b/plugins/c9.ide.watcher/gui.js @@ -82,31 +82,23 @@ define(function(require, exports, module) { }, plugin); } - tabManager.getTabs().forEach(function(tab) { - if (!tab.path) - return; + function initializeTab(tab) { + if (!tab.path) return; if (tab.document.undoManager.isAtBookmark()) { initializeDocument(tab.document); } - else { - console.error("Unsupported state"); - } - if (tab.classList.contains("conflict")) { addChangedTab(tab, comparisonType.TIMESTAMP_AND_CONTENTS); } - }); + } + tabManager.getTabs().forEach(initializeTab); tabManager.on("open", function(e) { - initializeDocument(e.tab.document); - if (e.tab.classList.contains("conflict")) { - addChangedTab(e.tab, comparisonType.TIMESTAMP_AND_CONTENTS); - } + initializeTab(e.tab); }, plugin); // Hook the save of the document value - save.on("beforeSave", function(e) { e.document.meta.$savingValue = e.save; if (e.tab.classList.contains("conflict")) { @@ -178,6 +170,17 @@ define(function(require, exports, module) { delete changedPaths[path]; } + function resolve(doc, path) { + if (collabEnabled && collab.send) + collab.send({type: "RESOLVE_CONFLICT", data: {docId: path}}); + resolveConflict(doc, path); + } + + + function isTabSaving(tab) { + return !!tab.document.meta.$saving; + } + function addChangedTab(tab, doubleCheckComparisonType) { // If we already have a dialog open, just update it, but mark the value dirty if (changedPaths[tab.path]) { @@ -188,133 +191,115 @@ define(function(require, exports, module) { } // Ignore changes that come in while tab is being saved - if (tab.document.meta.$saving) { - console.log("[watchers] Watcher fired, but tab is still saving", path); - return; - } - - var doc = tab.document; - var path = tab.path; - - changedPaths[tab.path] = { tab: tab, resolve: resolve }; + if (isTabSaving(tab)) return; // If the terminal is currently focussed, lets wait until // another tab is focussed - if (tabManager.focussedTab - && tabManager.focussedTab.editorType == "terminal") { + if (tabManager.focussedTab && tabManager.focussedTab.editorType == "terminal") { tabManager.once("focus", function(){ addChangedTab(tab, comparisonType.CONTENTS); }); return; } - function resolve() { - collab.send({type: "RESOLVE_CONFLICT", data: {docId: path}}); - resolveConflict(doc, path); - } - + var doc = tab.document; + var path = tab.path; + + changedPaths[tab.path] = { tab: tab, resolve: resolve.bind(null, doc, path) }; + switch (doubleCheckComparisonType) { case comparisonType.TIMESTAMP_AND_CONTENTS: - checkByStatOrContents(); + checkByStatOrContents(tab); break; case comparisonType.CONTENTS: - checkByContents(); + checkByContents(tab); break; case comparisonType.NONE: - dialog(); + showChangeDialog(tab); break; } + } - function dialog(data) { - if (!changedPaths[path]) - return; - changedPaths[path].data = data || changedPaths[path].data; - - if (changeDialog) { - // The dialog is visible - if (changeDialog.visible === 1) { - question.all = true; - return; - } - // The dialog still is to become visible - else if (changeDialog.visible === undefined) { - changeDialog.on("show", function(){ - question.all = true; - }); - return; - } - } - - if (tabManager.focussedTab && !changedPaths[tabManager.focussedTab.path]) { - doc.tab.classList.add("conflict"); - // Let's try again later, maybe then one of our paths gets focus - return tabManager.once("focus", function() { - dialog(); - }); - } - - if (!tabManager.findTab(path)) // drat! tab is gone - return; - - // Show dialogs for changed tabs - for (var changedPath in changedPaths) { - tab = changedPaths[changedPath].tab; - data = changedPaths[changedPath].data; + function createChangeDialog(tab, data) { + var doc = tab.document; + var path = tab.path; + + if (!changedPaths[path]) + return; + changedPaths[path].data = data || changedPaths[path].data; + + if (tabManager.focussedTab && !changedPaths[tabManager.focussedTab.path]) { + doc.tab.classList.add("conflict"); + // Let's try again later, maybe then one of our paths gets focus + tabManager.once("focus", function() { showChangeDialog(tab, data); + }); + return; + } + + if (!tabManager.findTab(path)) // drat! tab is gone + return; + + // Show dialogs for changed tab + showChangeDialog(tab, data); + } + + function checkByStatOrContents(tab) { + var doc = tab.document; + var path = tab.path; + + fs.stat(path, function(err, stat) { + if (!err && doc.meta.timestamp >= stat.mtime) + return resolve(doc, path); + checkByContents(tab, stat); + }); + } + + function checkByContents(tab, stat) { + var doc = tab.document; + var path = tab.path; + + fs.readFile(path, function(err, data) { + if (err) { + console.warn("[watchers] Could not read", path, "will assume it got changed"); + return createChangeDialog(tab); } - } - - function checkByStatOrContents() { - fs.stat(path, function(err, stat) { - if (!err && doc.meta.timestamp >= stat.mtime) - return resolve(); - checkByContents(stat); - }); - } - - function checkByContents(stat) { - fs.readFile(path, function(err, data) { - if (err) { - console.warn("[watchers] Could not read", path, "will assume it got changed"); - return dialog(); - } - - // false alarm. File content didn't change - if (data === doc.meta.$savedValue) - return resolve(); + + // false alarm. File content didn't change + if (data === doc.meta.$savedValue) + return resolve(doc, path); + + // Store base value for merges + if (doc.meta.$mergeRoot == undefined) + doc.meta.$mergeRoot = doc.meta.$savedValue || doc.recentValue; + // Update saved value + doc.meta.$savedValue = data; + if (stat) + doc.meta.timestamp = stat.mtime; - // Store base value for merges - if (doc.meta.$mergeRoot == undefined) - doc.meta.$mergeRoot = doc.meta.$savedValue || doc.recentValue; - // Update saved value - doc.meta.$savedValue = data; - if (stat) - doc.meta.timestamp = stat.mtime; - - // short cut: remote value is the same as the current value - if (data === doc.value) { // Expensive check - - // Remove the changed state from the document - doc.undoManager.bookmark(); - - // Mark as resolved - resolve(); - - return; - } else { - // if this is the first time change notification comes - // remember undomanger state for deciding to merge or not - if (doc.meta.$merge == undefined) - doc.meta.$merge = !doc.undoManager.isAtBookmark(); - doc.undoManager.bookmark(-2); - } + // short cut: remote value is the same as the current value + if (data === doc.value) { // Expensive check - if (automerge(tab, data)) - resolve(); - else - dialog(data); - }); - } + // Remove the changed state from the document + doc.undoManager.bookmark(); + + // Mark as resolved + resolve(doc, path); + + return; + } else { + // if this is the first time change notification comes + // remember undomanger state for deciding to merge or not + if (doc.meta.$merge == undefined) + doc.meta.$merge = !doc.undoManager.isAtBookmark(); + doc.undoManager.bookmark(-2); + } + + if (automerge(tab, data)) + resolve(doc, path); + else + createChangeDialog(tab, data); + }); } function automerge(tab, data) { @@ -367,8 +352,8 @@ define(function(require, exports, module) { var doc = tab.document; doc.setBookmarkedValue(data, true); doc.meta.timestamp = Date.now() - settings.timeOffset; - save.save(tab); changedPaths[path].resolve(); + save.save(tab); } function mergeChangedPath(err, path, data) { @@ -379,13 +364,19 @@ define(function(require, exports, module) { function showChangeDialog(tab, data) { var path, merge; - if (!tab) { - for (path in changedPaths) { - tab = changedPaths[path].tab; - data = changedPaths[path].data; - break; + if (changeDialog) { + // The dialog is visible + if (changeDialog.visible === 1) { + question.all = true; + return; + } + // The dialog still is to become visible + else if (changeDialog.visible === undefined) { + changeDialog.on("show", function(){ + question.all = true; + }); + return; } - if (!tab) return; } path = tab.path; @@ -403,7 +394,7 @@ define(function(require, exports, module) { changedPaths[path].tab.document.undoManager.bookmark(-2); changedPaths[path].resolve(); } - checkEmptyQueue(); + checkIfQueueIsEmpty(); } function yes(all) { // Remote | Yes @@ -413,12 +404,10 @@ define(function(require, exports, module) { } } else { - getLatestValue(path, function(err, path, data) { - updateChangedPath(err, path, data); - }); + getLatestValue(path, updateChangedPath); } - checkEmptyQueue(); + checkIfQueueIsEmpty(); } if (merge) { @@ -438,13 +427,10 @@ define(function(require, exports, module) { } else { askAutoMerge(); - - getLatestValue(path, function(err, path, data) { - mergeChangedPath(err, path, data); - }); + getLatestValue(path, mergeChangedPath); } - checkEmptyQueue(); + checkIfQueueIsEmpty(); }, { merge: true, @@ -486,7 +472,7 @@ define(function(require, exports, module) { fs.stat(tab.path, function(err, data) { if (err && err.code === "ENOENT") { - removedPaths[tab.path] = tab; + removedPaths[tab.path] = {tab: tab}; if (deleteDialog) { // The dialog is visible @@ -516,16 +502,7 @@ define(function(require, exports, module) { } function showDeleteDialog(tab) { - var path; - if (!tab) { - for (path in removedPaths) { - tab = removedPaths[path]; - break; - } - if (!tab) return; - } - - path = tab.path; + var path = tab.path; deleteDialog = question.show( "File removed, keep tab open?", @@ -536,36 +513,34 @@ define(function(require, exports, module) { if (all) { for (var id in removedPaths) { - doc = removedPaths[id].document; + doc = removedPaths[id].tab.document; doc.undoManager.bookmark(-2); doc.meta.newfile = true; } removedPaths = {}; } else { - doc = removedPaths[path].document; + doc = removedPaths[path].tab.document; doc.undoManager.bookmark(-2); doc.meta.newfile = true; delete removedPaths[path]; - showDeleteDialog(); } - checkEmptyQueue(); + checkIfQueueIsEmpty(); }, function(all, cancel) { // No if (all) { for (var id in removedPaths) { - closeTab(removedPaths[id], true); + closeTab(removedPaths[id].tab, true); } removedPaths = {}; } else { - closeTab(removedPaths[path]); + closeTab(removedPaths[path].tab); delete removedPaths[path]; - showDeleteDialog(); } - checkEmptyQueue(); + checkIfQueueIsEmpty(); }, { all: Object.keys(removedPaths).length > 1 } ); @@ -582,9 +557,13 @@ define(function(require, exports, module) { tabManager.focusTab(tab); } - function checkEmptyQueue(){ - for (var prop in changedPaths) return; - for (var prop in removedPaths) return; + function checkIfQueueIsEmpty(){ + for (var path in changedPaths) { + return showChangeDialog(changedPaths[path].tab, changedPaths[path].data); + } + for (var path in removedPaths) { + return showDeleteDialog(removedPaths[path].tab); + }; if (initialFocus) { tabManager.focusTab(initialFocus); diff --git a/plugins/c9.static/unpacked_helper.js b/plugins/c9.static/unpacked_helper.js deleted file mode 100644 index c5bb48ef..00000000 --- a/plugins/c9.static/unpacked_helper.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * unpacked_helper speeds up the unpacked version of Cloud9 - * by using more parallel connections and avoiding - * subsubdomains on dogfooding (e.g., ide.dev-lennartcl.c9.io, where - * Chrome doesn't support any caching). - */ -"use strict"; - -plugin.consumes = [ - "db", "connect.static" -]; -plugin.provides = [ - "unpacked_helper" -]; - -module.exports = plugin; - -function plugin(options, imports, register) { - var connectStatic = imports["connect.static"]; - var assert = require("assert"); - var baseUrl = options.baseUrl; - var ideBaseUrl = options.ideBaseUrl; - assert(baseUrl, "baseUrl must be set"); - assert(ideBaseUrl, "ideBaseUrl must be set"); - - var balancers = [ - baseUrl + "/_unp", - baseUrl + ":8080/_unp", - baseUrl + ":8081/_unp", - baseUrl + ":8082/_unp", - ]; - - connectStatic.getRequireJsConfig().baseUrlLoadBalancers = balancers; - assert(connectStatic.getRequireJsConfig().baseUrlLoadBalancers); - - register(null, { - "unpacked_helper": {} - }); -} \ No newline at end of file diff --git a/plugins/c9.vfs.server/vfs.server.js b/plugins/c9.vfs.server/vfs.server.js index 3be49599..069fd3ed 100644 --- a/plugins/c9.vfs.server/vfs.server.js +++ b/plugins/c9.vfs.server/vfs.server.js @@ -277,7 +277,7 @@ function plugin(options, imports, register) { var vfsid = req.params.vfsid; var scope = req.params.scope; var path = req.params.path; - + var entry = cache.get(vfsid); if (!entry) { var err = new error.PreconditionFailed("VFS connection does not exist"); @@ -335,10 +335,34 @@ function plugin(options, imports, register) { user.save && user.save(function() {}); } } - + + function handlePublish(vfs, messageString) { + var message = JSON.parse(messageString); + switch (message.action) { + case "remove_member": + case "update_member_access": + handleProjectMemberAccessChange(vfs, message); + break; + default: + break; + } + } + + function handleProjectMemberAccessChange(vfs, message) { + if (vfs.uid !== message.body.uid) return; + + console.log("Removing ", vfs.id, " for user ", vfs.uid, " project ", vfs.pid, " from the vfs connection cache"); + + // Remove next tick so client has time to recieve final "You've been removed" PubSub message. + setTimeout(function() { + cache.remove(vfs.id); + }, 100); + } + register(null, { "vfs.server": { - get section() { return section; } + get section() { return section; }, + get handlePublish() { return handlePublish; } } }); } diff --git a/scripts/install-sdk.sh b/scripts/install-sdk.sh index 52fb07b9..5a58f3ee 100755 --- a/scripts/install-sdk.sh +++ b/scripts/install-sdk.sh @@ -15,8 +15,8 @@ else exit 1 fi -cd `dirname $0`/.. -SOURCE=`pwd` +cd "$(dirname "$0")/.." +SOURCE=$(pwd) uname="$(uname -a)" os= @@ -44,37 +44,38 @@ blue=$'\e[01;34m' magenta=$'\e[01;35m' resetColor=$'\e[0m' -NO_PULL= -NO_GLOBAL_INSTALL= -FORCE= +# NO_PULL= +# NO_GLOBAL_INSTALL= +# FORCE= updatePackage() { name=$1 + cd "$SOURCE" REPO=https://github.com/c9/$name echo "${green}checking out ${resetColor}$REPO" - if ! [[ -d ./plugins/$name ]]; then - mkdir -p ./plugins/$name + if ! [[ -d ./plugins/"$name" ]]; then + mkdir -p ./plugins/"$name" fi - pushd ./plugins/$name + pushd ./plugins/"$name" if ! [[ -d .git ]]; then git init # git remote rm origin || true - git remote add origin $REPO + git remote add origin "$REPO" fi - version=`"$NODE" -e 'console.log((require("../../package.json").c9plugins["'$name'"].substr(1) || "origin/master"))'`; - rev=`git rev-parse --revs-only $version` + version=$("$NODE" -e 'console.log((require("../../package.json").c9plugins["'"$name"'"].substr(1) || "origin/master"))'); + rev=$(git rev-parse --revs-only "$version") if [ "$rev" == "" ]; then git fetch origin fi - status=`git status --porcelain --untracked-files=no` - if [ "$status" == "" ]; then - git reset $version --hard + status=$(git status --porcelain --untracked-files=no) + if [ "$status" == "" ] || [ "$FORCE" == "1" ]; then + git reset "$version" --hard else echo "${yellow}$name ${red}contains uncommited changes.${yellow} Skipping...${resetColor}" fi @@ -82,22 +83,23 @@ updatePackage() { } updateAllPackages() { - c9packages=`"$NODE" -e 'console.log(Object.keys(require("./package.json").c9plugins).join(" "))'`; - count=${#c9packages[@]} + c9packages=$("$NODE" -p 'Object.keys(require("./package.json").c9plugins).join(" ")'); + count=$("$NODE" -p 'Object.keys(require("./package.json").c9plugins).length') i=0 - for m in ${c9packages[@]}; do echo $m; - i=$(($i + 1)) + for m in ${c9packages[@]}; do + echo "$m" + i=$((i + 1)) echo "updating plugin ${blue}$i${resetColor} of ${blue}$count${resetColor}" - updatePackage $m + updatePackage "$m" || updatePackage "$m" done } updateNodeModules() { echo "${magenta}--- Running npm install --------------------------------------------${resetColor}" safeInstall(){ - deps=`"$NODE" -e 'console.log(Object.keys(require("./package.json").dependencies).join(" "))'`; - for m in ${deps[@]}; do echo $m; - "$NPM" install --loglevel warn $m || true + deps=$("$NODE" -e 'console.log(Object.keys(require("./package.json").dependencies).join(" "))'); + for m in ${deps[@]}; do echo "$m"; + "$NPM" install --loglevel warn "$m" done } "$NPM" install || safeInstall @@ -111,7 +113,7 @@ updateCore() { # without this git merge fails on windows mv ./scripts/install-sdk.sh './scripts/.#install-sdk-tmp.sh' - rm ./scripts/.install-sdk-tmp.sh + rm -f ./scripts/.install-sdk-tmp.sh cp './scripts/.#install-sdk-tmp.sh' ./scripts/install-sdk.sh git checkout -- ./scripts/install-sdk.sh @@ -144,7 +146,7 @@ installGlobalDeps() { ############################################################################ export C9_DIR="$HOME"/.c9 -if ! [[ `which npm` ]]; then +if ! [[ $(which npm) ]]; then if [[ $os == "windows" ]]; then export PATH="$C9_DIR:$C9_DIR/node_modules/.bin:$PATH" else