From 9c51235cf6e5abb601a1f7fa013422a3cb03b4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Wed, 7 May 2014 14:24:20 +0200 Subject: [PATCH 001/351] Fix #354: correct typo --- client/core/addons.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/core/addons.js b/client/core/addons.js index 0a4c45df..01c2b53e 100644 --- a/client/core/addons.js +++ b/client/core/addons.js @@ -49,7 +49,7 @@ define([ return operations.start("addon.uninstall", function(op) { return addons.uninstall(_name); }, { - title: "Uinstalling add-on" + title: "Uninstalling add-on" }); }) } From db589fe426db5531eb53bcbb7b00e4950d5aa441 Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Tue, 13 May 2014 12:53:37 +0200 Subject: [PATCH 002/351] Added preview view for HTML files --- addons/cb.files.preview/client.js | 19 +++++++++++++++++++ addons/cb.files.preview/package.json | 19 +++++++++++++++++++ .../cb.files.preview/stylesheets/preview.less | 8 ++++++++ .../cb.files.preview/templates/preview.html | 3 +++ addons/cb.files.preview/views/preview.js | 19 +++++++++++++++++++ 5 files changed, 68 insertions(+) create mode 100644 addons/cb.files.preview/client.js create mode 100644 addons/cb.files.preview/package.json create mode 100644 addons/cb.files.preview/stylesheets/preview.less create mode 100644 addons/cb.files.preview/templates/preview.html create mode 100644 addons/cb.files.preview/views/preview.js diff --git a/addons/cb.files.preview/client.js b/addons/cb.files.preview/client.js new file mode 100644 index 00000000..d3468ee1 --- /dev/null +++ b/addons/cb.files.preview/client.js @@ -0,0 +1,19 @@ +define([ + "views/preview" +], function(PreviewView) { + var _ = codebox.require("hr/utils"); + var files = codebox.require("core/files"); + + var htmlExts = [ + ".html", ".htm" + ]; + + files.addHandler("preview", { + name: "Preview", + position: 10, + View: PreviewView, + valid: function(file) { + return (!file.isDirectory() && _.contains(htmlExts, file.extension())); + } + }); +}); \ No newline at end of file diff --git a/addons/cb.files.preview/package.json b/addons/cb.files.preview/package.json new file mode 100644 index 00000000..b55c2d7e --- /dev/null +++ b/addons/cb.files.preview/package.json @@ -0,0 +1,19 @@ +{ + "name": "cb.files.preview", + "version": "0.0.1", + "title": "HTML Preview", + "description": "Adds option to preview file in a new tab.", + "homepage": "https://github.com/invokr/codebox", + "license": "Apache", + "author": { + "name": "Robin Dietrich", + "email": "me@invokr.org", + "url": "" + }, + "client": { + "main": "client" + }, + "engines": { + "codebox": ">=0.7.0" + } +} diff --git a/addons/cb.files.preview/stylesheets/preview.less b/addons/cb.files.preview/stylesheets/preview.less new file mode 100644 index 00000000..0d1f11b5 --- /dev/null +++ b/addons/cb.files.preview/stylesheets/preview.less @@ -0,0 +1,8 @@ +.addon-files-previewviewer { + iframe { + border: 0px; + width: 100%; + height: 100%; + background-color: #fff; + } +} \ No newline at end of file diff --git a/addons/cb.files.preview/templates/preview.html b/addons/cb.files.preview/templates/preview.html new file mode 100644 index 00000000..bcc3b8c9 --- /dev/null +++ b/addons/cb.files.preview/templates/preview.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/addons/cb.files.preview/views/preview.js b/addons/cb.files.preview/views/preview.js new file mode 100644 index 00000000..11085297 --- /dev/null +++ b/addons/cb.files.preview/views/preview.js @@ -0,0 +1,19 @@ +define([ + "text!templates/preview.html", + "less!stylesheets/preview.less" +], function(templateFile) { + var _ = codebox.require("hr/utils"); + var $ = codebox.require("hr/dom"); + var hr = codebox.require("hr/hr"); + var Dialogs = codebox.require("utils/dialogs"); + var FilesBaseView = codebox.require("views/files/base"); + + var PreviewView = FilesBaseView.extend({ + className: "addon-files-previewviewer", + templateLoader: "text", + template: templateFile, + events: {} + }); + + return PreviewView; +}); \ No newline at end of file From 7d5caaab9a7d5671a924bcfb6230fedfe3e77fb4 Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Wed, 14 May 2014 10:29:35 +0200 Subject: [PATCH 003/351] Added icon to preview menu entry --- addons/cb.files.preview/client.js | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/cb.files.preview/client.js b/addons/cb.files.preview/client.js index d3468ee1..78adc544 100644 --- a/addons/cb.files.preview/client.js +++ b/addons/cb.files.preview/client.js @@ -10,6 +10,7 @@ define([ files.addHandler("preview", { name: "Preview", + icon: "eye", position: 10, View: PreviewView, valid: function(file) { From a1c0ed8e686c8ab56719b60abe85250f213700cf Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Wed, 14 May 2014 10:30:19 +0200 Subject: [PATCH 004/351] Added automatic refreshing of open preview tabs on file save --- addons/cb.files.preview/views/preview.js | 40 +++++++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/addons/cb.files.preview/views/preview.js b/addons/cb.files.preview/views/preview.js index 11085297..84b831f5 100644 --- a/addons/cb.files.preview/views/preview.js +++ b/addons/cb.files.preview/views/preview.js @@ -4,15 +4,45 @@ define([ ], function(templateFile) { var _ = codebox.require("hr/utils"); var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var Dialogs = codebox.require("utils/dialogs"); - var FilesBaseView = codebox.require("views/files/base"); + var box = codebox.require("core/box"); + var FilesTabView = codebox.require("views/files/tab"); - var PreviewView = FilesBaseView.extend({ + var PreviewView = FilesTabView.extend({ className: "addon-files-previewviewer", templateLoader: "text", template: templateFile, - events: {} + events: {}, + + initialize: function() { + PreviewView.__super__.initialize.apply(this, arguments); + var that = this; + + // add refresh menu option + this.tab.menu.menuSection([ + { + 'type': "action", + 'title': "Refresh", + 'shortcuts': [ + "mod+r" + ], + 'bindKeyboard': true, + 'action': function() { + that.refresh(); + } + } + ]); + + // bind save event + box.on("box:watch:change:update", function() { + that.refresh(); + }, this); + + return this; + }, + + refresh: function() { + $(this.$el).find("iframe").attr('src', function ( i, val ) { return val; }); + } }); return PreviewView; From dc680dcb9e1e734a7a5b9dbb8c40ead7345c8500 Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Wed, 14 May 2014 10:46:26 +0200 Subject: [PATCH 005/351] Added Reload-On-Save to settings --- addons/cb.files.preview/settings.js | 17 +++++++++++++++++ addons/cb.files.preview/views/preview.js | 9 ++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 addons/cb.files.preview/settings.js diff --git a/addons/cb.files.preview/settings.js b/addons/cb.files.preview/settings.js new file mode 100644 index 00000000..d1b4a1fa --- /dev/null +++ b/addons/cb.files.preview/settings.js @@ -0,0 +1,17 @@ +define([], function() { + var settings = codebox.require("core/settings"); + + return settings.add({ + 'namespace': "preview", + 'title': "Preview", + 'defaults': { + 'refresh': true + }, + 'fields': { + 'refresh': { + 'label': "Reload on Save", + 'type': "checkbox" + } + } + }); +}); \ No newline at end of file diff --git a/addons/cb.files.preview/views/preview.js b/addons/cb.files.preview/views/preview.js index 84b831f5..eff2fdbe 100644 --- a/addons/cb.files.preview/views/preview.js +++ b/addons/cb.files.preview/views/preview.js @@ -1,7 +1,8 @@ define([ + "../settings", "text!templates/preview.html", "less!stylesheets/preview.less" -], function(templateFile) { +], function(settings, templateFile) { var _ = codebox.require("hr/utils"); var $ = codebox.require("hr/dom"); var box = codebox.require("core/box"); @@ -34,7 +35,9 @@ define([ // bind save event box.on("box:watch:change:update", function() { - that.refresh(); + if (settings.user.get("refresh")) { + that.refresh(); + } }, this); return this; @@ -46,4 +49,4 @@ define([ }); return PreviewView; -}); \ No newline at end of file +}); From b71109b789f9214e43370483b79a1388bf24aa02 Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Thu, 15 May 2014 12:20:46 +0200 Subject: [PATCH 006/351] Renamed preview to html_preview --- addons/cb.files.preview/client.js | 6 +++--- .../templates/{preview.html => preview_html.html} | 0 .../cb.files.preview/views/{preview.js => preview_html.js} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename addons/cb.files.preview/templates/{preview.html => preview_html.html} (100%) rename addons/cb.files.preview/views/{preview.js => preview_html.js} (96%) diff --git a/addons/cb.files.preview/client.js b/addons/cb.files.preview/client.js index 78adc544..3053f925 100644 --- a/addons/cb.files.preview/client.js +++ b/addons/cb.files.preview/client.js @@ -1,6 +1,6 @@ define([ - "views/preview" -], function(PreviewView) { + "views/preview_html" +], function(PreviewHtml) { var _ = codebox.require("hr/utils"); var files = codebox.require("core/files"); @@ -12,7 +12,7 @@ define([ name: "Preview", icon: "eye", position: 10, - View: PreviewView, + View: PreviewHtml, valid: function(file) { return (!file.isDirectory() && _.contains(htmlExts, file.extension())); } diff --git a/addons/cb.files.preview/templates/preview.html b/addons/cb.files.preview/templates/preview_html.html similarity index 100% rename from addons/cb.files.preview/templates/preview.html rename to addons/cb.files.preview/templates/preview_html.html diff --git a/addons/cb.files.preview/views/preview.js b/addons/cb.files.preview/views/preview_html.js similarity index 96% rename from addons/cb.files.preview/views/preview.js rename to addons/cb.files.preview/views/preview_html.js index eff2fdbe..9fc20ef9 100644 --- a/addons/cb.files.preview/views/preview.js +++ b/addons/cb.files.preview/views/preview_html.js @@ -1,6 +1,6 @@ define([ - "../settings", - "text!templates/preview.html", + "settings", + "text!templates/preview_html.html", "less!stylesheets/preview.less" ], function(settings, templateFile) { var _ = codebox.require("hr/utils"); From ae235938a737d8da3fb0ba38a3b67302522ef1f8 Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Thu, 15 May 2014 12:21:11 +0200 Subject: [PATCH 007/351] Added dependency for markdown-js --- addons/cb.files.preview/package.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/cb.files.preview/package.json b/addons/cb.files.preview/package.json index b55c2d7e..9c5dea70 100644 --- a/addons/cb.files.preview/package.json +++ b/addons/cb.files.preview/package.json @@ -1,19 +1,22 @@ { "name": "cb.files.preview", "version": "0.0.1", - "title": "HTML Preview", - "description": "Adds option to preview file in a new tab.", + "title": "HTML / Markdown Preview", + "description": "Adds option to preview files in a new tab.", "homepage": "https://github.com/invokr/codebox", "license": "Apache", "author": { "name": "Robin Dietrich", "email": "me@invokr.org", - "url": "" + "url": "https://github.com/invokr" }, "client": { "main": "client" }, "engines": { "codebox": ">=0.7.0" + }, + "dependencies": { + "markdown": "git+https://github.com/evilstreak/markdown-js" } } From 6fead0768f360d21e29ac93100f71b44e513359e Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Thu, 15 May 2014 13:09:18 +0200 Subject: [PATCH 008/351] Added markdown preview handler --- addons/cb.files.preview/client.js | 19 ++++++- .../templates/preview_markdown.html | 1 + .../views/preview_markdown.js | 56 +++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 addons/cb.files.preview/templates/preview_markdown.html create mode 100644 addons/cb.files.preview/views/preview_markdown.js diff --git a/addons/cb.files.preview/client.js b/addons/cb.files.preview/client.js index 3053f925..42cd79c4 100644 --- a/addons/cb.files.preview/client.js +++ b/addons/cb.files.preview/client.js @@ -1,6 +1,7 @@ define([ - "views/preview_html" -], function(PreviewHtml) { + "views/preview_html", + "views/preview_markdown" +], function(PreviewHtml, PreviewMarkdown) { var _ = codebox.require("hr/utils"); var files = codebox.require("core/files"); @@ -17,4 +18,18 @@ define([ return (!file.isDirectory() && _.contains(htmlExts, file.extension())); } }); + + var markdownExts = [ + ".md", ".markdown", ".txt" + ]; + + files.addHandler("preview-markdown", { + name: "Preview", + icon: "eye", + position: 10, + View: PreviewMarkdown, + valid: function(file) { + return (!file.isDirectory() && _.contains(markdownExts, file.extension())); + } + }); }); \ No newline at end of file diff --git a/addons/cb.files.preview/templates/preview_markdown.html b/addons/cb.files.preview/templates/preview_markdown.html new file mode 100644 index 00000000..6595a5bb --- /dev/null +++ b/addons/cb.files.preview/templates/preview_markdown.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/addons/cb.files.preview/views/preview_markdown.js b/addons/cb.files.preview/views/preview_markdown.js new file mode 100644 index 00000000..e7756b23 --- /dev/null +++ b/addons/cb.files.preview/views/preview_markdown.js @@ -0,0 +1,56 @@ +define([ + "settings", + "node_modules/markdown/src/markdown", + "text!templates/preview_markdown.html", + "less!stylesheets/preview.less" +], function(settings, markdown, templateFile) { + var _ = codebox.require("hr/utils"); + var $ = codebox.require("hr/dom"); + var box = codebox.require("core/box"); + var FilesTabView = codebox.require("views/files/tab"); + + var MarkdownView = FilesTabView.extend({ + className: "addon-files-previewviewer", + templateLoader: "text", + template: templateFile, + events: {}, + + initialize: function() { + MarkdownView.__super__.initialize.apply(this, arguments); + var that = this; + + // add refresh menu option + this.tab.menu.menuSection([ + { + 'type': "action", + 'title': "Refresh", + 'shortcuts': [ + "mod+r" + ], + 'bindKeyboard': true, + 'action': function() { + that.refresh(); + } + } + ]); + + this.model.on("file:change:update", function() { + if (settings.user.get("refresh")) { + that.refresh(); + } + }, this); + + this.refresh(); + return this; + }, + + refresh: function() { + var that = this; + this.model.download().then(function (content) { + that.$el.html("
"+markdown.toHTML(content)+"
"); + }); + } + }); + + return MarkdownView; +}); From 606f4e70f37acadd4dd7e0e2457e3d0ca76dd8fd Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Thu, 15 May 2014 13:10:04 +0200 Subject: [PATCH 009/351] Adjusted CSS to accommodate markdown changes --- addons/cb.files.preview/stylesheets/preview.less | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/addons/cb.files.preview/stylesheets/preview.less b/addons/cb.files.preview/stylesheets/preview.less index 0d1f11b5..bc878aa7 100644 --- a/addons/cb.files.preview/stylesheets/preview.less +++ b/addons/cb.files.preview/stylesheets/preview.less @@ -1,8 +1,19 @@ .addon-files-previewviewer { + height: 100%; + iframe { border: 0px; width: 100%; height: 100%; background-color: #fff; } + + .markdown { + border: 0px; + width: 100%; + height: 100%; + background-color: #fff; + margin-top: 1px; + padding: 3px; + } } \ No newline at end of file From df716743da50b61cc4ac8871124026fc4b1779d6 Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Thu, 15 May 2014 13:36:48 +0200 Subject: [PATCH 010/351] Updated preview FileHandler names --- addons/cb.files.preview/client.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/cb.files.preview/client.js b/addons/cb.files.preview/client.js index 42cd79c4..d6c621ba 100644 --- a/addons/cb.files.preview/client.js +++ b/addons/cb.files.preview/client.js @@ -10,7 +10,7 @@ define([ ]; files.addHandler("preview", { - name: "Preview", + name: "HTML Preview", icon: "eye", position: 10, View: PreviewHtml, @@ -24,7 +24,7 @@ define([ ]; files.addHandler("preview-markdown", { - name: "Preview", + name: "Markdown Preview", icon: "eye", position: 10, View: PreviewMarkdown, From ce7889668aac755ecf1bba9a303dff490239be82 Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Thu, 15 May 2014 15:49:39 +0200 Subject: [PATCH 011/351] Added option to strip trailing spaces on save --- addons/cb.files.editor/editor/settings.js | 5 +++++ addons/cb.files.editor/editor/view.js | 19 ++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/addons/cb.files.editor/editor/settings.js b/addons/cb.files.editor/editor/settings.js index 1765a6b2..61e696dd 100644 --- a/addons/cb.files.editor/editor/settings.js +++ b/addons/cb.files.editor/editor/settings.js @@ -15,6 +15,7 @@ define([], function() { 'wraplimitrange': 80, 'enablesoftwrap': false, 'enablesofttabs': true, + 'stripspaces': false, 'autocollaboration': true, 'tabsize': 4, 'keyboard': "textinput" @@ -74,6 +75,10 @@ define([], function() { 'label': "Use Soft Tabs", 'type': "checkbox" }, + 'stripspaces': { + 'label': "Strip Whitespaces", + 'type': "checkbox" + }, 'tabsize': { 'label': "Tab Size", 'type': "number", diff --git a/addons/cb.files.editor/editor/view.js b/addons/cb.files.editor/editor/view.js index d6c1b358..1defa14c 100644 --- a/addons/cb.files.editor/editor/view.js +++ b/addons/cb.files.editor/editor/view.js @@ -321,11 +321,11 @@ define([ this.markersC[cId] = this.editor.getSession().addMarker(range, "marker-cursor marker-"+c.color.replace("#", ""), function(html, range, left, top, config){ html.push("
" + "
 "+name+" 
" - + "
 
"); + + " "); }, true); }, this); - // Participant selection + // Participant selection this.sync.on("selection:move", function(cId, c) { var range = new aceRange.Range(c.start.y, c.start.x, c.end.y, c.end.x); if (this.markersS[cId]) this.editor.getSession().removeMarker(this.markersS[cId]); @@ -510,6 +510,19 @@ define([ // (action) Save file saveFile: function(e) { if (e) e.preventDefault(); + + if (editorSettings.user.get("stripspaces")) { + // strip all whitespaces from the current document + var doc = this.editor.session.doc; + var lines = doc.getAllLines(); + + for (var i = 0; i < lines.length; ++i) { + var index = lines[i].search(/\s+$/); + if (index !== -1 && index != 0) + doc.removeInLine(i, index, lines[i].length); + } + } + this.sync.save(); }, @@ -555,4 +568,4 @@ define([ }); return FileEditorView; -}); \ No newline at end of file +}); From a87856f6644a4be484f11494a8b43fd29d4c9ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Fri, 16 May 2014 23:54:00 +0200 Subject: [PATCH 012/351] Fix markdown previewer dependency --- addons/cb.files.preview/package.json | 2 +- addons/cb.files.preview/views/preview_markdown.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/cb.files.preview/package.json b/addons/cb.files.preview/package.json index 9c5dea70..a9f506a6 100644 --- a/addons/cb.files.preview/package.json +++ b/addons/cb.files.preview/package.json @@ -17,6 +17,6 @@ "codebox": ">=0.7.0" }, "dependencies": { - "markdown": "git+https://github.com/evilstreak/markdown-js" + "markdown": "0.5.0" } } diff --git a/addons/cb.files.preview/views/preview_markdown.js b/addons/cb.files.preview/views/preview_markdown.js index e7756b23..8ab7eba4 100644 --- a/addons/cb.files.preview/views/preview_markdown.js +++ b/addons/cb.files.preview/views/preview_markdown.js @@ -1,6 +1,6 @@ define([ "settings", - "node_modules/markdown/src/markdown", + "node_modules/markdown/lib/markdown", "text!templates/preview_markdown.html", "less!stylesheets/preview.less" ], function(settings, markdown, templateFile) { @@ -14,11 +14,11 @@ define([ templateLoader: "text", template: templateFile, events: {}, - + initialize: function() { MarkdownView.__super__.initialize.apply(this, arguments); var that = this; - + // add refresh menu option this.tab.menu.menuSection([ { @@ -33,17 +33,17 @@ define([ } } ]); - + this.model.on("file:change:update", function() { if (settings.user.get("refresh")) { that.refresh(); } }, this); - + this.refresh(); return this; }, - + refresh: function() { var that = this; this.model.download().then(function (content) { From 530b00a71b5d68d119992ce122fd5e193a443fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sat, 17 May 2014 00:00:30 +0200 Subject: [PATCH 013/351] Fix markdown previewer --- addons/cb.files.preview/views/preview_markdown.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/cb.files.preview/views/preview_markdown.js b/addons/cb.files.preview/views/preview_markdown.js index 8ab7eba4..7fe530f5 100644 --- a/addons/cb.files.preview/views/preview_markdown.js +++ b/addons/cb.files.preview/views/preview_markdown.js @@ -3,12 +3,14 @@ define([ "node_modules/markdown/lib/markdown", "text!templates/preview_markdown.html", "less!stylesheets/preview.less" -], function(settings, markdown, templateFile) { +], function(settings, _markdown, templateFile) { var _ = codebox.require("hr/utils"); var $ = codebox.require("hr/dom"); var box = codebox.require("core/box"); var FilesTabView = codebox.require("views/files/tab"); + var markdown = window.markdown; + var MarkdownView = FilesTabView.extend({ className: "addon-files-previewviewer", templateLoader: "text", From 89769cd0b78bdaa749e0e98fc9c1e63a159e549a Mon Sep 17 00:00:00 2001 From: Robin Dietrich Date: Sat, 17 May 2014 20:12:08 +0200 Subject: [PATCH 014/351] Added stripspaces function and corresponding menu entry --- addons/cb.files.editor/editor/view.js | 30 +++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/addons/cb.files.editor/editor/view.js b/addons/cb.files.editor/editor/view.js index 1defa14c..fd723f82 100644 --- a/addons/cb.files.editor/editor/view.js +++ b/addons/cb.files.editor/editor/view.js @@ -138,6 +138,12 @@ define([ 'action': function() { aceWhitespace.convertIndentation(that.editor.session, "\t", 1); } + }, + { + 'title':"Strip Whitespaces", + 'action': function() { + that.stripspaces(); + } } ]).menuSection([ this.collaboratorsMenu @@ -512,19 +518,25 @@ define([ if (e) e.preventDefault(); if (editorSettings.user.get("stripspaces")) { - // strip all whitespaces from the current document - var doc = this.editor.session.doc; - var lines = doc.getAllLines(); - - for (var i = 0; i < lines.length; ++i) { - var index = lines[i].search(/\s+$/); - if (index !== -1 && index != 0) - doc.removeInLine(i, index, lines[i].length); - } + this.stripspaces(); } this.sync.save(); }, + + stripspaces: function(e) { + if (e) e.preventDefault(); + + // strip all whitespaces from the current document + var doc = this.editor.session.doc; + var lines = doc.getAllLines(); + + for (var i = 0; i < lines.length; ++i) { + var index = lines[i].search(/\s+$/); + if (index !== -1 && index != 0) + doc.removeInLine(i, index, lines[i].length); + } + }, // (action) Run this file runFile: function(e) { From 8dc1c460f80b36b1aa7936148a1c6ada58fabe38 Mon Sep 17 00:00:00 2001 From: Carlos Arturo Prieto Date: Tue, 3 Jun 2014 21:17:55 -0500 Subject: [PATCH 015/351] Running app engine apps on virtual machine with this correction it is possible to run App Engine apps on a different machine that runs Codebox such as virtual machines --- core/cb.project/appengine/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cb.project/appengine/run.sh b/core/cb.project/appengine/run.sh index 318ece90..d68cdf37 100755 --- a/core/cb.project/appengine/run.sh +++ b/core/cb.project/appengine/run.sh @@ -4,4 +4,4 @@ WORKSPACE=$1 PORT=$2 -cd $WORKSPACE && dev_appserver.py ./ --port=${PORT} \ No newline at end of file +cd $WORKSPACE && dev_appserver.py ./ --port=${PORT} --host=0.0.0.0 From 924bcdbb78258017c91ab1aec79262928c299eaa Mon Sep 17 00:00:00 2001 From: Jan Henrik Date: Wed, 11 Jun 2014 23:52:03 +0200 Subject: [PATCH 016/351] Fixed typo --- bin/codebox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/codebox.js b/bin/codebox.js index aef2cb61..5051d6e6 100755 --- a/bin/codebox.js +++ b/bin/codebox.js @@ -20,7 +20,7 @@ cli.option('-t, --title [project title]', 'Title for the project.'); cli.option('-s, --sample [project type]', 'Replace directory content by a sample (warning: erase content).'); cli.option('-o, --open', 'Open the IDE in your favorite browser'); cli.option('-e, --email [email address]', 'Email address to use as a default authentication'); -cli.option('-u, --users [list users]', 'List of coma seperated users and password (formatted as "username:passowrd")'); +cli.option('-u, --users [list users]', 'List of coma seperated users and password (formatted as "username:password")'); // An authentication hook that uses a dictionary of users From 0227cd8165f72bb4bfb9cb57b8ee758cfef1e4fc Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Wed, 25 Jun 2014 00:15:03 -0700 Subject: [PATCH 017/351] Remove useless "./utils" require, fixes #397 --- core/codebox.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/codebox.js b/core/codebox.js index f2c9c8b4..219f956b 100644 --- a/core/codebox.js +++ b/core/codebox.js @@ -2,7 +2,6 @@ var Q = require('q'); var _ = require('lodash'); -var urils = require('./utils'); var os = require('os'); var path = require('path'); var Gittle = require('gittle'); @@ -291,4 +290,4 @@ var start = function(config) { module.exports = { 'start': start -}; \ No newline at end of file +}; From 53dd064993fe2fe2e957c539265918e3389f0c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Tue, 15 Jul 2014 19:46:31 -0700 Subject: [PATCH 018/351] Base for new version --- .gitignore | 3 +- Gruntfile.js | 261 +- README.md | 57 +- addons/cb.debug/client.js | 72 - addons/cb.debug/package.json | 19 - addons/cb.debug/settings.js | 42 - addons/cb.debug/stylesheets/tab.less | 99 - addons/cb.debug/views/backtrace.js | 35 - addons/cb.debug/views/breakpoints.js | 39 - addons/cb.debug/views/console.js | 107 - addons/cb.debug/views/locals.js | 39 - addons/cb.debug/views/section.js | 100 - addons/cb.debug/views/tab.js | 201 - addons/cb.deploy/client.js | 240 - addons/cb.deploy/package.json | 19 - addons/cb.files.editor/ace.js | 10 - addons/cb.files.editor/build.sh | 55 - addons/cb.files.editor/client.js | 28 - addons/cb.files.editor/download_ace.sh | 28 - addons/cb.files.editor/editor/breakpoints.js | 102 - addons/cb.files.editor/editor/codecomplete.js | 31 - addons/cb.files.editor/editor/jshint.js | 48 - addons/cb.files.editor/editor/settings.js | 93 - addons/cb.files.editor/editor/view.js | 583 -- addons/cb.files.editor/package.json | 28 - addons/cb.files.editor/stylesheets/file.less | 114 - addons/cb.files.editor/templates/file.html | 3 - addons/cb.files.editor/theme/textmate.js | 10 - addons/cb.files.editor/theme/textmate.less | 182 - addons/cb.files.image/client.js | 19 - addons/cb.files.image/package.json | 19 - addons/cb.files.image/stylesheets/image.less | 5 - addons/cb.files.image/templates/image.html | 1 - addons/cb.files.image/views/image.js | 19 - addons/cb.files.preview/client.js | 35 - addons/cb.files.preview/package.json | 22 - addons/cb.files.preview/settings.js | 17 - .../cb.files.preview/stylesheets/preview.less | 19 - .../templates/preview_html.html | 3 - .../templates/preview_markdown.html | 1 - addons/cb.files.preview/views/preview_html.js | 52 - .../views/preview_markdown.js | 58 - addons/cb.git/client.js | 251 - addons/cb.git/node/main.js | 29 - addons/cb.git/node/service.js | 150 - addons/cb.git/package.json | 31 - addons/cb.git/stylesheets/git.less | 64 - addons/cb.git/templates/dialog.html | 28 - addons/cb.git/views/dialog.js | 75 - addons/cb.help/client.js | 80 - addons/cb.help/package.json | 19 - addons/cb.help/welcome.md | 22 - addons/cb.offline/client.js | 80 - addons/cb.offline/menus.js | 87 - addons/cb.offline/package.json | 19 - addons/cb.offline/settings.js | 30 - addons/cb.panel.files/client.js | 85 - addons/cb.panel.files/package.json | 19 - addons/cb.panel.files/settings.js | 25 - addons/cb.panel.files/stylesheets/files.less | 97 - addons/cb.panel.files/stylesheets/panel.less | 9 - addons/cb.panel.files/templates/item.html | 14 - addons/cb.panel.files/views/panel.js | 58 - addons/cb.panel.files/views/tree.js | 168 - addons/cb.panel.outline/client.js | 30 - addons/cb.panel.outline/package.json | 19 - addons/cb.panel.outline/settings.js | 23 - .../cb.panel.outline/stylesheets/panel.less | 107 - addons/cb.panel.outline/views/panel.js | 13 - addons/cb.panel.outline/views/tags.js | 182 - addons/cb.project/autorun.js | 146 - addons/cb.project/client.js | 77 - addons/cb.project/package.json | 19 - addons/cb.project/ports.js | 43 - addons/cb.project/runner.js | 42 - addons/cb.project/samples.js | 49 - addons/cb.project/settings.js | 19 - addons/cb.settings/client.js | 29 - addons/cb.settings/package.json | 19 - addons/cb.settings/stylesheets/dialog.less | 57 - addons/cb.settings/templates/dialog.html | 34 - addons/cb.settings/views/dialog.js | 66 - addons/cb.terminal/client.js | 137 - addons/cb.terminal/package.json | 22 - addons/cb.terminal/stylesheets/tab.less | 76 - addons/cb.terminal/views/tab.js | 177 - addons/cb.theme.dark/ace/theme.js | 10 - addons/cb.theme.dark/ace/theme.less | 206 - addons/cb.theme.dark/main.js | 128 - addons/cb.theme.dark/package.json | 19 - bin/codebox.js | 161 +- client/collections/addons.js | 233 - client/collections/changes.js | 27 - client/collections/commands.js | 16 - client/collections/files.js | 11 - client/collections/operations.js | 66 - client/collections/tabs.js | 25 - client/collections/users.js | 27 - client/core/addons.js | 59 - client/core/app.js | 252 - client/core/backends/vfs.js | 176 - client/core/box.js | 20 - client/core/collaborators.js | 19 - client/core/commands/menu.js | 50 - client/core/commands/palette.js | 26 - client/core/commands/statusbar.js | 20 - client/core/commands/toolbar.js | 11 - client/core/debug/breakpoints.js | 47 - client/core/debug/manager.js | 60 - client/core/debug/session.js | 198 - client/core/files.js | 255 - client/core/globals.js | 7 - client/core/localfs.js | 519 -- client/core/operations.js | 6 - client/core/panels.js | 6 - client/core/search.js | 121 - client/core/search/addons.js | 111 - client/core/search/code.js | 155 - client/core/search/commands.js | 29 - client/core/search/files.js | 54 - client/core/search/tags.js | 40 - client/core/session.js | 66 - client/core/settings.js | 78 - client/core/tabs.js | 6 - client/core/themes.js | 161 - client/core/user.js | 8 - client/index.html | 14 - client/main.js | 20 - client/models/addon.js | 98 - client/models/box.js | 269 - client/models/change.js | 85 - client/models/command.js | 222 - client/models/file.js | 897 --- client/models/operation.js | 44 - client/models/shell.js | 109 - client/models/tab.js | 142 - client/models/user.js | 86 - .../fonts/fontawesome/FontAwesome.otf | Bin 63008 -> 0 bytes .../fonts/fontawesome/fontawesome-webfont.eot | Bin 38239 -> 0 bytes .../fonts/fontawesome/fontawesome-webfont.svg | 414 - .../fonts/fontawesome/fontawesome-webfont.ttf | Bin 80776 -> 0 bytes .../fontawesome/fontawesome-webfont.woff | Bin 44476 -> 0 bytes client/resources/fonts/helvetica/normal.eot | Bin 50032 -> 0 bytes client/resources/fonts/helvetica/normal.svg | 240 - client/resources/fonts/helvetica/normal.ttf | Bin 49832 -> 0 bytes client/resources/fonts/helvetica/normal.woff | Bin 25784 -> 0 bytes .../resources/fonts/helvetica/ultralight.eot | Bin 50360 -> 0 bytes .../resources/fonts/helvetica/ultralight.svg | 239 - .../resources/fonts/helvetica/ultralight.ttf | Bin 50148 -> 0 bytes .../resources/fonts/helvetica/ultralight.woff | Bin 26020 -> 0 bytes client/resources/images/icons/128.png | Bin 2487 -> 0 bytes client/resources/images/icons/32.png | Bin 863 -> 0 bytes client/resources/images/icons/48.png | Bin 1581 -> 0 bytes client/resources/images/icons/512.png | Bin 5925 -> 0 bytes client/resources/images/icons/72.png | Bin 1897 -> 0 bytes client/resources/images/icons/ios.png | Bin 3159 -> 0 bytes client/resources/resources.js | 10 - .../stylesheets/bootstrap/alerts.less | 67 - .../stylesheets/bootstrap/badges.less | 51 - .../stylesheets/bootstrap/bootstrap.less | 59 - .../stylesheets/bootstrap/breadcrumbs.less | 23 - .../stylesheets/bootstrap/button-groups.less | 248 - .../stylesheets/bootstrap/buttons.less | 160 - .../stylesheets/bootstrap/carousel.less | 209 - .../stylesheets/bootstrap/close.less | 33 - .../resources/stylesheets/bootstrap/code.less | 56 - .../bootstrap/component-animations.less | 29 - .../stylesheets/bootstrap/dropdowns.less | 193 - .../stylesheets/bootstrap/forms.less | 353 - .../stylesheets/bootstrap/glyphicons.less | 232 - .../resources/stylesheets/bootstrap/grid.less | 346 - .../stylesheets/bootstrap/input-groups.less | 127 - .../stylesheets/bootstrap/jumbotron.less | 40 - .../stylesheets/bootstrap/labels.less | 58 - .../stylesheets/bootstrap/list-group.less | 88 - .../stylesheets/bootstrap/media.less | 56 - .../stylesheets/bootstrap/mixins.less | 723 -- .../stylesheets/bootstrap/modals.less | 141 - .../stylesheets/bootstrap/navbar.less | 621 -- .../resources/stylesheets/bootstrap/navs.less | 229 - .../stylesheets/bootstrap/normalize.less | 396 - .../stylesheets/bootstrap/pager.less | 55 - .../stylesheets/bootstrap/pagination.less | 83 - .../stylesheets/bootstrap/panels.less | 148 - .../stylesheets/bootstrap/popovers.less | 133 - .../stylesheets/bootstrap/print.less | 100 - .../stylesheets/bootstrap/progress-bars.less | 95 - .../bootstrap/responsive-utilities.less | 220 - .../stylesheets/bootstrap/scaffolding.less | 130 - .../stylesheets/bootstrap/tables.less | 236 - .../stylesheets/bootstrap/theme.less | 232 - .../stylesheets/bootstrap/thumbnails.less | 31 - .../stylesheets/bootstrap/tooltip.less | 95 - .../resources/stylesheets/bootstrap/type.less | 238 - .../stylesheets/bootstrap/utilities.less | 42 - .../stylesheets/bootstrap/variables.less | 620 -- .../stylesheets/bootstrap/wells.less | 29 - .../fontawesome/bordered-pulled.less | 16 - .../stylesheets/fontawesome/core.less | 12 - .../stylesheets/fontawesome/fixed-width.less | 6 - .../stylesheets/fontawesome/font-awesome.less | 38 - .../stylesheets/fontawesome/icons.less | 412 - .../stylesheets/fontawesome/larger.less | 13 - .../stylesheets/fontawesome/list.less | 19 - .../stylesheets/fontawesome/mixins.less | 20 - .../stylesheets/fontawesome/path.less | 14 - .../fontawesome/rotated-flipped.less | 9 - .../stylesheets/fontawesome/spinning.less | 30 - .../stylesheets/fontawesome/stacked.less | 20 - .../stylesheets/fontawesome/variables.less | 382 - client/resources/stylesheets/fonts.less | 17 - client/resources/stylesheets/main.less | 74 - client/resources/stylesheets/tabs/base.less | 96 - .../resources/stylesheets/tabs/manager.less | 6 - .../resources/stylesheets/tabs/section.less | 50 - client/resources/stylesheets/tabs/tab.less | 105 - client/resources/stylesheets/ui/alert.less | 21 - client/resources/stylesheets/ui/body.less | 13 - client/resources/stylesheets/ui/grid.less | 46 - .../resources/stylesheets/ui/lateralbar.less | 23 - client/resources/stylesheets/ui/loading.less | 68 - client/resources/stylesheets/ui/login.less | 46 - client/resources/stylesheets/ui/menu.less | 97 - client/resources/stylesheets/ui/menubar.less | 64 - .../resources/stylesheets/ui/operations.less | 28 - client/resources/stylesheets/ui/palette.less | 76 - client/resources/stylesheets/ui/panels.less | 52 - .../resources/stylesheets/ui/statusbar.less | 84 - client/resources/stylesheets/ui/toolbar.less | 47 - client/resources/stylesheets/variables.less | 55 - .../resources/templates/commands/command.html | 3 - .../templates/commands/palette/command.html | 14 - .../templates/commands/palette/input.html | 2 - client/resources/templates/dialogs/alert.html | 14 - .../resources/templates/dialogs/confirm.html | 15 - .../resources/templates/dialogs/fields.html | 54 - .../resources/templates/dialogs/prompt.html | 15 - .../resources/templates/dialogs/select.html | 19 - client/resources/templates/main.html | 61 - .../templates/operations/operation.html | 5 - client/resources/templates/settings/base.html | 39 - client/utils/alerts.js | 44 - client/utils/clipboard.js | 90 - client/utils/contextmenu.js | 138 - client/utils/css.js | 62 - client/utils/dialogs.js | 148 - client/utils/filesync.js | 876 --- client/utils/gravatar.js | 19 - client/utils/hash.js | 270 - client/utils/keyboard.js | 119 - client/utils/languages.js | 1533 ---- client/utils/loading.js | 34 - client/utils/string.js | 100 - client/utils/uploader.js | 178 - client/utils/url.js | 74 - client/vendors/bootstrap/affix.js | 126 - client/vendors/bootstrap/alert.js | 98 - client/vendors/bootstrap/button.js | 109 - client/vendors/bootstrap/carousel.js | 217 - client/vendors/bootstrap/collapse.js | 179 - client/vendors/bootstrap/dropdown.js | 154 - client/vendors/bootstrap/modal.js | 246 - client/vendors/bootstrap/popover.js | 117 - client/vendors/bootstrap/scrollspy.js | 158 - client/vendors/bootstrap/tab.js | 135 - client/vendors/bootstrap/tooltip.js | 386 - client/vendors/bootstrap/transition.js | 56 - client/vendors/crypto.js | 16 - client/vendors/diff_match_patch.js | 2196 ------ client/vendors/filer.js | 854 -- client/vendors/idb.filesystem.js | 916 --- client/vendors/moment.js | 6 - client/vendors/mousetrap.js | 953 --- client/vendors/socket.io.js | 3781 --------- client/vendors/taphold.js | 92 - client/views/commands/manager.js | 69 - client/views/commands/menu.js | 156 - client/views/commands/menubar.js | 74 - client/views/commands/palette.js | 308 - client/views/commands/statusbar.js | 11 - client/views/commands/toolbar.js | 59 - client/views/dialogs/base.js | 162 - client/views/files/base.js | 70 - client/views/files/tab.js | 29 - client/views/operations/manager.js | 38 - client/views/panels/base.js | 92 - client/views/panels/file.js | 104 - client/views/panels/manager.js | 138 - client/views/settings/base.js | 87 - client/views/tabs/base.js | 213 - client/views/tabs/file.js | 98 - client/views/tabs/manager.js | 355 - client/views/tabs/section.js | 144 - client/views/tabs/tab.js | 169 - core/cb.addons/addon.js | 234 - core/cb.addons/main.js | 239 - core/cb.addons/manager.js | 95 - core/cb.addons/package.json | 16 - core/cb.addons/registry.js | 27 - .../require-tools/css/css-builder.js | 162 - core/cb.addons/require-tools/css/css.js | 131 - core/cb.addons/require-tools/css/normalize.js | 137 - .../require-tools/less/less-builder.js | 121 - core/cb.addons/require-tools/less/less.js | 78 - core/cb.addons/require-tools/less/lessc.js | 6914 ----------------- .../cb.addons/require-tools/less/normalize.js | 138 - core/cb.addons/require-tools/text/text.js | 386 - core/cb.codecomplete.ctags/main.js | 25 - core/cb.codecomplete.ctags/package.json | 15 - core/cb.codecomplete.ctags/tags.js | 62 - core/cb.codecomplete/codecomplete.js | 168 - core/cb.codecomplete/main.js | 19 - core/cb.codecomplete/package.json | 19 - core/cb.core/main.js | 28 - core/cb.core/package.json | 16 - core/cb.core/user.js | 46 - core/cb.core/workspace.js | 166 - core/cb.deploy.appengine/main.js | 67 - core/cb.deploy.appengine/package.json | 10 - core/cb.deploy.ftp/main.js | 74 - core/cb.deploy.ftp/package.json | 10 - core/cb.deploy.ftp/upload.sh | 21 - core/cb.deploy.ghpages/main.js | 46 - core/cb.deploy.ghpages/package.json | 10 - core/cb.deploy.heroku/api.js | 29 - core/cb.deploy.heroku/main.js | 76 - core/cb.deploy.heroku/package.json | 10 - core/cb.deploy.parse/main.js | 67 - core/cb.deploy.parse/package.json | 10 - core/cb.deploy/main.js | 40 - core/cb.deploy/package.json | 16 - core/cb.deploy/solution.js | 40 - core/cb.events.log/main.js | 24 - core/cb.events.log/package.json | 16 - core/cb.events.socketio/main.js | 36 - core/cb.events.socketio/package.json | 15 - core/cb.events.webhook/main.js | 61 - core/cb.events.webhook/package.json | 17 - core/cb.events/main.js | 18 - core/cb.events/package.json | 14 - core/cb.export/main.js | 28 - core/cb.export/package.json | 18 - core/cb.files.service/main.js | 23 - core/cb.files.service/package.json | 17 - core/cb.files.service/service.js | 113 - core/cb.files.sync/environment.js | 294 - core/cb.files.sync/main.js | 28 - core/cb.files.sync/manager.js | 138 - core/cb.files.sync/models/cursor.js | 7 - core/cb.files.sync/models/document.js | 115 - core/cb.files.sync/models/selection.js | 11 - core/cb.files.sync/models/user.js | 94 - core/cb.files.sync/package.json | 16 - core/cb.files.sync/utils.js | 32 - core/cb.files.sync/validators.js | 71 - core/cb.hooks/main.js | 131 - core/cb.hooks/package.json | 16 - core/cb.logger/main.js | 53 - core/cb.logger/package.json | 16 - core/cb.main/main.js | 31 - core/cb.main/package.json | 17 - core/cb.offline/main.js | 71 - core/cb.offline/manifest.js | 75 - core/cb.offline/package.json | 16 - core/cb.proc/http.js | 143 - core/cb.proc/main.js | 31 - core/cb.proc/package.json | 16 - core/cb.project/appengine/detector.sh | 8 - core/cb.project/appengine/index.js | 15 - core/cb.project/appengine/run.sh | 7 - core/cb.project/appengine/sample/app.yaml | 9 - .../cb.project/appengine/sample/helloworld.py | 13 - core/cb.project/c/detector.sh | 8 - core/cb.project/c/index.js | 9 - core/cb.project/c/sample/Makefile | 10 - core/cb.project/c/sample/main.c | 7 - core/cb.project/clojure/detector.sh | 13 - core/cb.project/clojure/index.js | 15 - core/cb.project/clojure/run.sh | 7 - core/cb.project/clojure/sample/.gitignore | 10 - core/cb.project/clojure/sample/project.clj | 8 - .../clojure/sample/src/helloworld.clj | 13 - core/cb.project/d/detector.sh | 7 - core/cb.project/d/index.js | 15 - core/cb.project/d/run.sh | 30 - core/cb.project/d/sample/main.d | 10 - core/cb.project/dart/detector.sh | 8 - core/cb.project/dart/index.js | 30 - core/cb.project/dart/run_build.sh | 6 - core/cb.project/dart/run_clean.sh | 6 - core/cb.project/dart/run_serve.sh | 7 - core/cb.project/dart/sample/pubspec.lock | 7 - core/cb.project/dart/sample/pubspec.yaml | 4 - .../cb.project/dart/sample/web/helloworld.css | 27 - .../dart/sample/web/helloworld.dart | 16 - core/cb.project/dart/sample/web/index.html | 21 - core/cb.project/django/detector.sh | 10 - core/cb.project/django/index.js | 14 - core/cb.project/django/run.sh | 11 - core/cb.project/go/detector.sh | 8 - core/cb.project/go/index.js | 15 - core/cb.project/go/run.sh | 30 - core/cb.project/go/sample/main.go | 7 - core/cb.project/gradle/detector.sh | 8 - core/cb.project/gradle/index.js | 15 - core/cb.project/gradle/run.sh | 6 - core/cb.project/gradle/sample/build.gradle | 13 - core/cb.project/grails/detector.sh | 8 - core/cb.project/grails/index.js | 14 - core/cb.project/grails/run.sh | 6 - core/cb.project/java/detector.sh | 20 - core/cb.project/java/index.js | 15 - core/cb.project/java/run.sh | 33 - core/cb.project/java/sample/HelloWorld.java | 12 - core/cb.project/logo/detector.sh | 18 - core/cb.project/logo/index.js | 8 - core/cb.project/lua/detector.sh | 8 - core/cb.project/lua/index.js | 15 - core/cb.project/lua/run.sh | 30 - core/cb.project/lua/sample/main.lua | 13 - core/cb.project/main.js | 175 - core/cb.project/makefile/detector.sh | 8 - core/cb.project/makefile/index.js | 20 - core/cb.project/makefile/run_all.sh | 6 - core/cb.project/makefile/run_clean.sh | 6 - core/cb.project/maven/detector.sh | 10 - core/cb.project/maven/index.js | 18 - core/cb.project/maven/install.sh | 7 - core/cb.project/maven/run.sh | 7 - core/cb.project/meteor/detector.sh | 8 - core/cb.project/meteor/index.js | 31 - core/cb.project/meteor/mrt_install.sh | 7 - core/cb.project/meteor/mrt_update.sh | 7 - core/cb.project/meteor/run.sh | 7 - .../meteor/sample/.meteor/.gitignore | 1 - .../cb.project/meteor/sample/.meteor/packages | 9 - core/cb.project/meteor/sample/.meteor/release | 1 - core/cb.project/meteor/sample/hello.css | 1 - core/cb.project/meteor/sample/hello.html | 13 - core/cb.project/meteor/sample/hello.js | 19 - core/cb.project/node/detector.sh | 8 - core/cb.project/node/index.js | 25 - core/cb.project/node/install.sh | 6 - core/cb.project/node/run.sh | 7 - core/cb.project/node/sample/package.json | 13 - core/cb.project/node/sample/web.js | 12 - core/cb.project/package.json | 18 - core/cb.project/parse/detector.sh | 8 - core/cb.project/parse/index.js | 16 - core/cb.project/parse/run.sh | 12 - core/cb.project/parse/sample/cloud/main.js | 6 - .../parse/sample/config/global.json | 14 - .../cb.project/parse/sample/public/index.html | 9 - core/cb.project/php/_waitfile.sh | 29 - core/cb.project/php/detector.sh | 8 - core/cb.project/php/index.js | 22 - core/cb.project/php/run.sh | 18 - core/cb.project/php/run_apache.sh | 221 - core/cb.project/php/sample/index.php | 3 - core/cb.project/play/detector.sh | 12 - core/cb.project/play/index.js | 14 - core/cb.project/play/run.sh | 6 - core/cb.project/procfile/detector.sh | 8 - core/cb.project/procfile/index.js | 14 - core/cb.project/procfile/run.sh | 140 - core/cb.project/project.js | 215 - core/cb.project/python/detector.sh | 22 - core/cb.project/python/index.js | 15 - core/cb.project/python/run.sh | 30 - core/cb.project/python/sample/app.py | 14 - .../cb.project/python/sample/requirements.txt | 6 - core/cb.project/ruby/detector.sh | 8 - core/cb.project/ruby/index.js | 15 - core/cb.project/ruby/run.sh | 30 - core/cb.project/ruby/sample/Gemfile | 2 - core/cb.project/ruby/sample/main.rb | 11 - core/cb.project/scala/detector.sh | 25 - core/cb.project/scala/index.js | 9 - core/cb.project/scala/sample/main.scala | 7 - core/cb.project/static/detector.sh | 9 - core/cb.project/static/index.js | 15 - core/cb.project/static/run.sh | 11 - core/cb.project/static/sample/index.html | 13 - core/cb.rpc.addons/main.js | 21 - core/cb.rpc.addons/package.json | 15 - core/cb.rpc.addons/service.js | 45 - core/cb.rpc.auth/main.js | 23 - core/cb.rpc.auth/package.json | 16 - core/cb.rpc.auth/service.js | 47 - core/cb.rpc.box/main.js | 23 - core/cb.rpc.box/package.json | 15 - core/cb.rpc.box/service.js | 46 - core/cb.rpc.codecomplete/main.js | 20 - core/cb.rpc.codecomplete/package.json | 17 - core/cb.rpc.codecomplete/service.js | 17 - core/cb.rpc.debug/main.js | 23 - core/cb.rpc.debug/package.json | 16 - core/cb.rpc.debug/service.js | 218 - core/cb.rpc.deploy/main.js | 22 - core/cb.rpc.deploy/package.json | 16 - core/cb.rpc.deploy/service.js | 48 - core/cb.rpc.proc/main.js | 21 - core/cb.rpc.proc/package.json | 15 - core/cb.rpc.proc/service.js | 16 - core/cb.rpc.project/main.js | 22 - core/cb.rpc.project/package.json | 15 - core/cb.rpc.project/service.js | 39 - core/cb.rpc.run/main.js | 31 - core/cb.rpc.run/package.json | 20 - core/cb.rpc.run/service.js | 46 - core/cb.rpc.search/main.js | 21 - core/cb.rpc.search/package.json | 15 - core/cb.rpc.search/service.js | 24 - core/cb.rpc.shells/main.js | 23 - core/cb.rpc.shells/package.json | 17 - core/cb.rpc.shells/service.js | 46 - core/cb.rpc.users/main.js | 20 - core/cb.rpc.users/package.json | 15 - core/cb.rpc.users/service.js | 22 - core/cb.rpc/main.js | 27 - core/cb.rpc/manager.js | 117 - core/cb.rpc/package.json | 19 - core/cb.run.file/commands.json | 22 - core/cb.run.file/main.js | 68 - core/cb.run.file/package.json | 19 - core/cb.run.ports/main.js | 20 - core/cb.run.ports/package.json | 14 - core/cb.run.project/main.js | 22 - core/cb.run.project/package.json | 22 - core/cb.run.project/project.js | 172 - core/cb.search/code.js | 152 - core/cb.search/files.js | 39 - core/cb.search/main.js | 21 - core/cb.search/package.json | 17 - core/cb.search/types.js | 120 - core/cb.server/main.js | 151 - core/cb.server/package.json | 16 - core/cb.settings/main.js | 59 - core/cb.settings/package.json | 18 - core/cb.shells.stream/main.js | 123 - core/cb.shells.stream/package.json | 17 - core/cb.shells/main.js | 107 - core/cb.shells/package.json | 17 - core/cb.socket.io/main.js | 24 - core/cb.socket.io/package.json | 16 - core/cb.vfs.http/main.js | 16 - core/cb.vfs.http/package.json | 14 - core/cb.vfs/main.js | 20 - core/cb.vfs/package.json | 16 - core/cb.watch/init.js | 129 - core/cb.watch/main.js | 19 - core/cb.watch/package.json | 16 - core/codebox.js | 293 - core/utils.js | 189 - editor/collections/commands.js | 32 + editor/collections/packages.js | 28 + editor/core/application.js | 38 + editor/core/commands.js | 7 + editor/core/packages.js | 7 + {client/core/backends => editor/core}/rpc.js | 12 +- editor/core/statusbar.js | 12 + editor/main.js | 20 + editor/models/command.js | 50 + editor/models/package.js | 70 + editor/resources/init.js | 12 + editor/resources/stylesheets/main.less | 0 editor/resources/stylesheets/variables.less | 0 editor/utils/dialogs.js | 6 + {client => editor}/utils/dragdrop.js | 18 +- {client => editor}/views/grid.js | 4 +- index.js | 1 - init.sh | 215 - lib/index.js | 28 + lib/packages.js | 22 + lib/rpc.js | 49 + lib/services/fs.js | 6 + lib/services/index.js | 4 + lib/services/packages.js | 13 + package.json | 85 +- screenshot.png | Bin 331938 -> 0 bytes tasks/grunt-build-addons.js | 41 - 581 files changed, 467 insertions(+), 55563 deletions(-) delete mode 100644 addons/cb.debug/client.js delete mode 100644 addons/cb.debug/package.json delete mode 100644 addons/cb.debug/settings.js delete mode 100644 addons/cb.debug/stylesheets/tab.less delete mode 100644 addons/cb.debug/views/backtrace.js delete mode 100644 addons/cb.debug/views/breakpoints.js delete mode 100644 addons/cb.debug/views/console.js delete mode 100644 addons/cb.debug/views/locals.js delete mode 100644 addons/cb.debug/views/section.js delete mode 100644 addons/cb.debug/views/tab.js delete mode 100644 addons/cb.deploy/client.js delete mode 100644 addons/cb.deploy/package.json delete mode 100644 addons/cb.files.editor/ace.js delete mode 100755 addons/cb.files.editor/build.sh delete mode 100644 addons/cb.files.editor/client.js delete mode 100755 addons/cb.files.editor/download_ace.sh delete mode 100644 addons/cb.files.editor/editor/breakpoints.js delete mode 100644 addons/cb.files.editor/editor/codecomplete.js delete mode 100644 addons/cb.files.editor/editor/jshint.js delete mode 100644 addons/cb.files.editor/editor/settings.js delete mode 100644 addons/cb.files.editor/editor/view.js delete mode 100644 addons/cb.files.editor/package.json delete mode 100644 addons/cb.files.editor/stylesheets/file.less delete mode 100644 addons/cb.files.editor/templates/file.html delete mode 100644 addons/cb.files.editor/theme/textmate.js delete mode 100644 addons/cb.files.editor/theme/textmate.less delete mode 100644 addons/cb.files.image/client.js delete mode 100644 addons/cb.files.image/package.json delete mode 100644 addons/cb.files.image/stylesheets/image.less delete mode 100644 addons/cb.files.image/templates/image.html delete mode 100644 addons/cb.files.image/views/image.js delete mode 100644 addons/cb.files.preview/client.js delete mode 100644 addons/cb.files.preview/package.json delete mode 100644 addons/cb.files.preview/settings.js delete mode 100644 addons/cb.files.preview/stylesheets/preview.less delete mode 100644 addons/cb.files.preview/templates/preview_html.html delete mode 100644 addons/cb.files.preview/templates/preview_markdown.html delete mode 100644 addons/cb.files.preview/views/preview_html.js delete mode 100644 addons/cb.files.preview/views/preview_markdown.js delete mode 100644 addons/cb.git/client.js delete mode 100644 addons/cb.git/node/main.js delete mode 100644 addons/cb.git/node/service.js delete mode 100644 addons/cb.git/package.json delete mode 100644 addons/cb.git/stylesheets/git.less delete mode 100644 addons/cb.git/templates/dialog.html delete mode 100644 addons/cb.git/views/dialog.js delete mode 100644 addons/cb.help/client.js delete mode 100644 addons/cb.help/package.json delete mode 100644 addons/cb.help/welcome.md delete mode 100644 addons/cb.offline/client.js delete mode 100644 addons/cb.offline/menus.js delete mode 100644 addons/cb.offline/package.json delete mode 100644 addons/cb.offline/settings.js delete mode 100644 addons/cb.panel.files/client.js delete mode 100644 addons/cb.panel.files/package.json delete mode 100644 addons/cb.panel.files/settings.js delete mode 100644 addons/cb.panel.files/stylesheets/files.less delete mode 100644 addons/cb.panel.files/stylesheets/panel.less delete mode 100644 addons/cb.panel.files/templates/item.html delete mode 100644 addons/cb.panel.files/views/panel.js delete mode 100644 addons/cb.panel.files/views/tree.js delete mode 100644 addons/cb.panel.outline/client.js delete mode 100644 addons/cb.panel.outline/package.json delete mode 100644 addons/cb.panel.outline/settings.js delete mode 100644 addons/cb.panel.outline/stylesheets/panel.less delete mode 100644 addons/cb.panel.outline/views/panel.js delete mode 100644 addons/cb.panel.outline/views/tags.js delete mode 100644 addons/cb.project/autorun.js delete mode 100644 addons/cb.project/client.js delete mode 100644 addons/cb.project/package.json delete mode 100644 addons/cb.project/ports.js delete mode 100644 addons/cb.project/runner.js delete mode 100644 addons/cb.project/samples.js delete mode 100644 addons/cb.project/settings.js delete mode 100644 addons/cb.settings/client.js delete mode 100644 addons/cb.settings/package.json delete mode 100644 addons/cb.settings/stylesheets/dialog.less delete mode 100644 addons/cb.settings/templates/dialog.html delete mode 100644 addons/cb.settings/views/dialog.js delete mode 100644 addons/cb.terminal/client.js delete mode 100644 addons/cb.terminal/package.json delete mode 100644 addons/cb.terminal/stylesheets/tab.less delete mode 100644 addons/cb.terminal/views/tab.js delete mode 100644 addons/cb.theme.dark/ace/theme.js delete mode 100644 addons/cb.theme.dark/ace/theme.less delete mode 100644 addons/cb.theme.dark/main.js delete mode 100644 addons/cb.theme.dark/package.json delete mode 100644 client/collections/addons.js delete mode 100644 client/collections/changes.js delete mode 100644 client/collections/commands.js delete mode 100644 client/collections/files.js delete mode 100644 client/collections/operations.js delete mode 100644 client/collections/tabs.js delete mode 100644 client/collections/users.js delete mode 100644 client/core/addons.js delete mode 100644 client/core/app.js delete mode 100644 client/core/backends/vfs.js delete mode 100644 client/core/box.js delete mode 100644 client/core/collaborators.js delete mode 100644 client/core/commands/menu.js delete mode 100644 client/core/commands/palette.js delete mode 100644 client/core/commands/statusbar.js delete mode 100644 client/core/commands/toolbar.js delete mode 100644 client/core/debug/breakpoints.js delete mode 100644 client/core/debug/manager.js delete mode 100644 client/core/debug/session.js delete mode 100644 client/core/files.js delete mode 100644 client/core/globals.js delete mode 100644 client/core/localfs.js delete mode 100644 client/core/operations.js delete mode 100644 client/core/panels.js delete mode 100644 client/core/search.js delete mode 100644 client/core/search/addons.js delete mode 100644 client/core/search/code.js delete mode 100644 client/core/search/commands.js delete mode 100644 client/core/search/files.js delete mode 100644 client/core/search/tags.js delete mode 100644 client/core/session.js delete mode 100644 client/core/settings.js delete mode 100644 client/core/tabs.js delete mode 100644 client/core/themes.js delete mode 100644 client/core/user.js delete mode 100644 client/index.html delete mode 100644 client/main.js delete mode 100644 client/models/addon.js delete mode 100644 client/models/box.js delete mode 100644 client/models/change.js delete mode 100644 client/models/command.js delete mode 100644 client/models/file.js delete mode 100644 client/models/operation.js delete mode 100644 client/models/shell.js delete mode 100644 client/models/tab.js delete mode 100644 client/models/user.js delete mode 100644 client/resources/fonts/fontawesome/FontAwesome.otf delete mode 100755 client/resources/fonts/fontawesome/fontawesome-webfont.eot delete mode 100755 client/resources/fonts/fontawesome/fontawesome-webfont.svg delete mode 100755 client/resources/fonts/fontawesome/fontawesome-webfont.ttf delete mode 100755 client/resources/fonts/fontawesome/fontawesome-webfont.woff delete mode 100644 client/resources/fonts/helvetica/normal.eot delete mode 100644 client/resources/fonts/helvetica/normal.svg delete mode 100644 client/resources/fonts/helvetica/normal.ttf delete mode 100644 client/resources/fonts/helvetica/normal.woff delete mode 100644 client/resources/fonts/helvetica/ultralight.eot delete mode 100644 client/resources/fonts/helvetica/ultralight.svg delete mode 100644 client/resources/fonts/helvetica/ultralight.ttf delete mode 100644 client/resources/fonts/helvetica/ultralight.woff delete mode 100644 client/resources/images/icons/128.png delete mode 100644 client/resources/images/icons/32.png delete mode 100644 client/resources/images/icons/48.png delete mode 100644 client/resources/images/icons/512.png delete mode 100644 client/resources/images/icons/72.png delete mode 100644 client/resources/images/icons/ios.png delete mode 100644 client/resources/resources.js delete mode 100755 client/resources/stylesheets/bootstrap/alerts.less delete mode 100755 client/resources/stylesheets/bootstrap/badges.less delete mode 100755 client/resources/stylesheets/bootstrap/bootstrap.less delete mode 100755 client/resources/stylesheets/bootstrap/breadcrumbs.less delete mode 100755 client/resources/stylesheets/bootstrap/button-groups.less delete mode 100755 client/resources/stylesheets/bootstrap/buttons.less delete mode 100755 client/resources/stylesheets/bootstrap/carousel.less delete mode 100755 client/resources/stylesheets/bootstrap/close.less delete mode 100755 client/resources/stylesheets/bootstrap/code.less delete mode 100755 client/resources/stylesheets/bootstrap/component-animations.less delete mode 100755 client/resources/stylesheets/bootstrap/dropdowns.less delete mode 100755 client/resources/stylesheets/bootstrap/forms.less delete mode 100755 client/resources/stylesheets/bootstrap/glyphicons.less delete mode 100755 client/resources/stylesheets/bootstrap/grid.less delete mode 100755 client/resources/stylesheets/bootstrap/input-groups.less delete mode 100755 client/resources/stylesheets/bootstrap/jumbotron.less delete mode 100755 client/resources/stylesheets/bootstrap/labels.less delete mode 100755 client/resources/stylesheets/bootstrap/list-group.less delete mode 100755 client/resources/stylesheets/bootstrap/media.less delete mode 100755 client/resources/stylesheets/bootstrap/mixins.less delete mode 100755 client/resources/stylesheets/bootstrap/modals.less delete mode 100755 client/resources/stylesheets/bootstrap/navbar.less delete mode 100755 client/resources/stylesheets/bootstrap/navs.less delete mode 100755 client/resources/stylesheets/bootstrap/normalize.less delete mode 100755 client/resources/stylesheets/bootstrap/pager.less delete mode 100755 client/resources/stylesheets/bootstrap/pagination.less delete mode 100755 client/resources/stylesheets/bootstrap/panels.less delete mode 100755 client/resources/stylesheets/bootstrap/popovers.less delete mode 100755 client/resources/stylesheets/bootstrap/print.less delete mode 100755 client/resources/stylesheets/bootstrap/progress-bars.less delete mode 100755 client/resources/stylesheets/bootstrap/responsive-utilities.less delete mode 100755 client/resources/stylesheets/bootstrap/scaffolding.less delete mode 100755 client/resources/stylesheets/bootstrap/tables.less delete mode 100755 client/resources/stylesheets/bootstrap/theme.less delete mode 100755 client/resources/stylesheets/bootstrap/thumbnails.less delete mode 100755 client/resources/stylesheets/bootstrap/tooltip.less delete mode 100755 client/resources/stylesheets/bootstrap/type.less delete mode 100755 client/resources/stylesheets/bootstrap/utilities.less delete mode 100755 client/resources/stylesheets/bootstrap/variables.less delete mode 100755 client/resources/stylesheets/bootstrap/wells.less delete mode 100644 client/resources/stylesheets/fontawesome/bordered-pulled.less delete mode 100644 client/resources/stylesheets/fontawesome/core.less delete mode 100644 client/resources/stylesheets/fontawesome/fixed-width.less delete mode 100644 client/resources/stylesheets/fontawesome/font-awesome.less delete mode 100644 client/resources/stylesheets/fontawesome/icons.less delete mode 100644 client/resources/stylesheets/fontawesome/larger.less delete mode 100644 client/resources/stylesheets/fontawesome/list.less delete mode 100644 client/resources/stylesheets/fontawesome/mixins.less delete mode 100644 client/resources/stylesheets/fontawesome/path.less delete mode 100644 client/resources/stylesheets/fontawesome/rotated-flipped.less delete mode 100644 client/resources/stylesheets/fontawesome/spinning.less delete mode 100644 client/resources/stylesheets/fontawesome/stacked.less delete mode 100644 client/resources/stylesheets/fontawesome/variables.less delete mode 100644 client/resources/stylesheets/fonts.less delete mode 100644 client/resources/stylesheets/main.less delete mode 100644 client/resources/stylesheets/tabs/base.less delete mode 100644 client/resources/stylesheets/tabs/manager.less delete mode 100644 client/resources/stylesheets/tabs/section.less delete mode 100644 client/resources/stylesheets/tabs/tab.less delete mode 100644 client/resources/stylesheets/ui/alert.less delete mode 100644 client/resources/stylesheets/ui/body.less delete mode 100644 client/resources/stylesheets/ui/grid.less delete mode 100644 client/resources/stylesheets/ui/lateralbar.less delete mode 100644 client/resources/stylesheets/ui/loading.less delete mode 100644 client/resources/stylesheets/ui/login.less delete mode 100644 client/resources/stylesheets/ui/menu.less delete mode 100644 client/resources/stylesheets/ui/menubar.less delete mode 100644 client/resources/stylesheets/ui/operations.less delete mode 100644 client/resources/stylesheets/ui/palette.less delete mode 100644 client/resources/stylesheets/ui/panels.less delete mode 100644 client/resources/stylesheets/ui/statusbar.less delete mode 100644 client/resources/stylesheets/ui/toolbar.less delete mode 100644 client/resources/stylesheets/variables.less delete mode 100644 client/resources/templates/commands/command.html delete mode 100644 client/resources/templates/commands/palette/command.html delete mode 100644 client/resources/templates/commands/palette/input.html delete mode 100644 client/resources/templates/dialogs/alert.html delete mode 100644 client/resources/templates/dialogs/confirm.html delete mode 100644 client/resources/templates/dialogs/fields.html delete mode 100644 client/resources/templates/dialogs/prompt.html delete mode 100644 client/resources/templates/dialogs/select.html delete mode 100644 client/resources/templates/main.html delete mode 100644 client/resources/templates/operations/operation.html delete mode 100644 client/resources/templates/settings/base.html delete mode 100644 client/utils/alerts.js delete mode 100644 client/utils/clipboard.js delete mode 100644 client/utils/contextmenu.js delete mode 100644 client/utils/css.js delete mode 100644 client/utils/dialogs.js delete mode 100644 client/utils/filesync.js delete mode 100644 client/utils/gravatar.js delete mode 100644 client/utils/hash.js delete mode 100644 client/utils/keyboard.js delete mode 100644 client/utils/languages.js delete mode 100644 client/utils/loading.js delete mode 100644 client/utils/string.js delete mode 100644 client/utils/uploader.js delete mode 100644 client/utils/url.js delete mode 100755 client/vendors/bootstrap/affix.js delete mode 100755 client/vendors/bootstrap/alert.js delete mode 100755 client/vendors/bootstrap/button.js delete mode 100755 client/vendors/bootstrap/carousel.js delete mode 100755 client/vendors/bootstrap/collapse.js delete mode 100755 client/vendors/bootstrap/dropdown.js delete mode 100755 client/vendors/bootstrap/modal.js delete mode 100755 client/vendors/bootstrap/popover.js delete mode 100755 client/vendors/bootstrap/scrollspy.js delete mode 100755 client/vendors/bootstrap/tab.js delete mode 100755 client/vendors/bootstrap/tooltip.js delete mode 100755 client/vendors/bootstrap/transition.js delete mode 100644 client/vendors/crypto.js delete mode 100644 client/vendors/diff_match_patch.js delete mode 100644 client/vendors/filer.js delete mode 100644 client/vendors/idb.filesystem.js delete mode 100644 client/vendors/moment.js delete mode 100644 client/vendors/mousetrap.js delete mode 100644 client/vendors/socket.io.js delete mode 100644 client/vendors/taphold.js delete mode 100644 client/views/commands/manager.js delete mode 100644 client/views/commands/menu.js delete mode 100644 client/views/commands/menubar.js delete mode 100644 client/views/commands/palette.js delete mode 100644 client/views/commands/statusbar.js delete mode 100644 client/views/commands/toolbar.js delete mode 100644 client/views/dialogs/base.js delete mode 100644 client/views/files/base.js delete mode 100644 client/views/files/tab.js delete mode 100644 client/views/operations/manager.js delete mode 100644 client/views/panels/base.js delete mode 100644 client/views/panels/file.js delete mode 100644 client/views/panels/manager.js delete mode 100644 client/views/settings/base.js delete mode 100644 client/views/tabs/base.js delete mode 100644 client/views/tabs/file.js delete mode 100644 client/views/tabs/manager.js delete mode 100644 client/views/tabs/section.js delete mode 100644 client/views/tabs/tab.js delete mode 100644 core/cb.addons/addon.js delete mode 100644 core/cb.addons/main.js delete mode 100644 core/cb.addons/manager.js delete mode 100644 core/cb.addons/package.json delete mode 100644 core/cb.addons/registry.js delete mode 100755 core/cb.addons/require-tools/css/css-builder.js delete mode 100755 core/cb.addons/require-tools/css/css.js delete mode 100755 core/cb.addons/require-tools/css/normalize.js delete mode 100755 core/cb.addons/require-tools/less/less-builder.js delete mode 100755 core/cb.addons/require-tools/less/less.js delete mode 100755 core/cb.addons/require-tools/less/lessc.js delete mode 100755 core/cb.addons/require-tools/less/normalize.js delete mode 100644 core/cb.addons/require-tools/text/text.js delete mode 100644 core/cb.codecomplete.ctags/main.js delete mode 100644 core/cb.codecomplete.ctags/package.json delete mode 100644 core/cb.codecomplete.ctags/tags.js delete mode 100644 core/cb.codecomplete/codecomplete.js delete mode 100644 core/cb.codecomplete/main.js delete mode 100644 core/cb.codecomplete/package.json delete mode 100644 core/cb.core/main.js delete mode 100644 core/cb.core/package.json delete mode 100644 core/cb.core/user.js delete mode 100644 core/cb.core/workspace.js delete mode 100644 core/cb.deploy.appengine/main.js delete mode 100644 core/cb.deploy.appengine/package.json delete mode 100644 core/cb.deploy.ftp/main.js delete mode 100644 core/cb.deploy.ftp/package.json delete mode 100755 core/cb.deploy.ftp/upload.sh delete mode 100644 core/cb.deploy.ghpages/main.js delete mode 100644 core/cb.deploy.ghpages/package.json delete mode 100644 core/cb.deploy.heroku/api.js delete mode 100644 core/cb.deploy.heroku/main.js delete mode 100644 core/cb.deploy.heroku/package.json delete mode 100644 core/cb.deploy.parse/main.js delete mode 100644 core/cb.deploy.parse/package.json delete mode 100644 core/cb.deploy/main.js delete mode 100644 core/cb.deploy/package.json delete mode 100644 core/cb.deploy/solution.js delete mode 100644 core/cb.events.log/main.js delete mode 100644 core/cb.events.log/package.json delete mode 100644 core/cb.events.socketio/main.js delete mode 100644 core/cb.events.socketio/package.json delete mode 100644 core/cb.events.webhook/main.js delete mode 100644 core/cb.events.webhook/package.json delete mode 100644 core/cb.events/main.js delete mode 100644 core/cb.events/package.json delete mode 100644 core/cb.export/main.js delete mode 100644 core/cb.export/package.json delete mode 100644 core/cb.files.service/main.js delete mode 100644 core/cb.files.service/package.json delete mode 100644 core/cb.files.service/service.js delete mode 100644 core/cb.files.sync/environment.js delete mode 100644 core/cb.files.sync/main.js delete mode 100644 core/cb.files.sync/manager.js delete mode 100644 core/cb.files.sync/models/cursor.js delete mode 100644 core/cb.files.sync/models/document.js delete mode 100644 core/cb.files.sync/models/selection.js delete mode 100644 core/cb.files.sync/models/user.js delete mode 100644 core/cb.files.sync/package.json delete mode 100644 core/cb.files.sync/utils.js delete mode 100644 core/cb.files.sync/validators.js delete mode 100644 core/cb.hooks/main.js delete mode 100644 core/cb.hooks/package.json delete mode 100644 core/cb.logger/main.js delete mode 100644 core/cb.logger/package.json delete mode 100644 core/cb.main/main.js delete mode 100644 core/cb.main/package.json delete mode 100644 core/cb.offline/main.js delete mode 100644 core/cb.offline/manifest.js delete mode 100644 core/cb.offline/package.json delete mode 100644 core/cb.proc/http.js delete mode 100644 core/cb.proc/main.js delete mode 100644 core/cb.proc/package.json delete mode 100755 core/cb.project/appengine/detector.sh delete mode 100644 core/cb.project/appengine/index.js delete mode 100755 core/cb.project/appengine/run.sh delete mode 100644 core/cb.project/appengine/sample/app.yaml delete mode 100644 core/cb.project/appengine/sample/helloworld.py delete mode 100755 core/cb.project/c/detector.sh delete mode 100644 core/cb.project/c/index.js delete mode 100644 core/cb.project/c/sample/Makefile delete mode 100644 core/cb.project/c/sample/main.c delete mode 100755 core/cb.project/clojure/detector.sh delete mode 100644 core/cb.project/clojure/index.js delete mode 100755 core/cb.project/clojure/run.sh delete mode 100644 core/cb.project/clojure/sample/.gitignore delete mode 100644 core/cb.project/clojure/sample/project.clj delete mode 100644 core/cb.project/clojure/sample/src/helloworld.clj delete mode 100755 core/cb.project/d/detector.sh delete mode 100644 core/cb.project/d/index.js delete mode 100755 core/cb.project/d/run.sh delete mode 100644 core/cb.project/d/sample/main.d delete mode 100755 core/cb.project/dart/detector.sh delete mode 100644 core/cb.project/dart/index.js delete mode 100755 core/cb.project/dart/run_build.sh delete mode 100755 core/cb.project/dart/run_clean.sh delete mode 100755 core/cb.project/dart/run_serve.sh delete mode 100644 core/cb.project/dart/sample/pubspec.lock delete mode 100644 core/cb.project/dart/sample/pubspec.yaml delete mode 100644 core/cb.project/dart/sample/web/helloworld.css delete mode 100644 core/cb.project/dart/sample/web/helloworld.dart delete mode 100644 core/cb.project/dart/sample/web/index.html delete mode 100755 core/cb.project/django/detector.sh delete mode 100644 core/cb.project/django/index.js delete mode 100755 core/cb.project/django/run.sh delete mode 100755 core/cb.project/go/detector.sh delete mode 100644 core/cb.project/go/index.js delete mode 100755 core/cb.project/go/run.sh delete mode 100644 core/cb.project/go/sample/main.go delete mode 100755 core/cb.project/gradle/detector.sh delete mode 100644 core/cb.project/gradle/index.js delete mode 100755 core/cb.project/gradle/run.sh delete mode 100644 core/cb.project/gradle/sample/build.gradle delete mode 100755 core/cb.project/grails/detector.sh delete mode 100644 core/cb.project/grails/index.js delete mode 100755 core/cb.project/grails/run.sh delete mode 100755 core/cb.project/java/detector.sh delete mode 100644 core/cb.project/java/index.js delete mode 100755 core/cb.project/java/run.sh delete mode 100644 core/cb.project/java/sample/HelloWorld.java delete mode 100755 core/cb.project/logo/detector.sh delete mode 100644 core/cb.project/logo/index.js delete mode 100755 core/cb.project/lua/detector.sh delete mode 100644 core/cb.project/lua/index.js delete mode 100755 core/cb.project/lua/run.sh delete mode 100644 core/cb.project/lua/sample/main.lua delete mode 100644 core/cb.project/main.js delete mode 100755 core/cb.project/makefile/detector.sh delete mode 100644 core/cb.project/makefile/index.js delete mode 100755 core/cb.project/makefile/run_all.sh delete mode 100755 core/cb.project/makefile/run_clean.sh delete mode 100755 core/cb.project/maven/detector.sh delete mode 100644 core/cb.project/maven/index.js delete mode 100755 core/cb.project/maven/install.sh delete mode 100755 core/cb.project/maven/run.sh delete mode 100755 core/cb.project/meteor/detector.sh delete mode 100644 core/cb.project/meteor/index.js delete mode 100755 core/cb.project/meteor/mrt_install.sh delete mode 100755 core/cb.project/meteor/mrt_update.sh delete mode 100755 core/cb.project/meteor/run.sh delete mode 100644 core/cb.project/meteor/sample/.meteor/.gitignore delete mode 100644 core/cb.project/meteor/sample/.meteor/packages delete mode 100644 core/cb.project/meteor/sample/.meteor/release delete mode 100644 core/cb.project/meteor/sample/hello.css delete mode 100644 core/cb.project/meteor/sample/hello.html delete mode 100644 core/cb.project/meteor/sample/hello.js delete mode 100755 core/cb.project/node/detector.sh delete mode 100644 core/cb.project/node/index.js delete mode 100755 core/cb.project/node/install.sh delete mode 100755 core/cb.project/node/run.sh delete mode 100644 core/cb.project/node/sample/package.json delete mode 100644 core/cb.project/node/sample/web.js delete mode 100644 core/cb.project/package.json delete mode 100755 core/cb.project/parse/detector.sh delete mode 100644 core/cb.project/parse/index.js delete mode 100755 core/cb.project/parse/run.sh delete mode 100644 core/cb.project/parse/sample/cloud/main.js delete mode 100644 core/cb.project/parse/sample/config/global.json delete mode 100644 core/cb.project/parse/sample/public/index.html delete mode 100755 core/cb.project/php/_waitfile.sh delete mode 100755 core/cb.project/php/detector.sh delete mode 100644 core/cb.project/php/index.js delete mode 100755 core/cb.project/php/run.sh delete mode 100755 core/cb.project/php/run_apache.sh delete mode 100644 core/cb.project/php/sample/index.php delete mode 100755 core/cb.project/play/detector.sh delete mode 100644 core/cb.project/play/index.js delete mode 100755 core/cb.project/play/run.sh delete mode 100755 core/cb.project/procfile/detector.sh delete mode 100644 core/cb.project/procfile/index.js delete mode 100755 core/cb.project/procfile/run.sh delete mode 100644 core/cb.project/project.js delete mode 100755 core/cb.project/python/detector.sh delete mode 100644 core/cb.project/python/index.js delete mode 100755 core/cb.project/python/run.sh delete mode 100644 core/cb.project/python/sample/app.py delete mode 100644 core/cb.project/python/sample/requirements.txt delete mode 100755 core/cb.project/ruby/detector.sh delete mode 100644 core/cb.project/ruby/index.js delete mode 100755 core/cb.project/ruby/run.sh delete mode 100644 core/cb.project/ruby/sample/Gemfile delete mode 100644 core/cb.project/ruby/sample/main.rb delete mode 100755 core/cb.project/scala/detector.sh delete mode 100644 core/cb.project/scala/index.js delete mode 100644 core/cb.project/scala/sample/main.scala delete mode 100755 core/cb.project/static/detector.sh delete mode 100644 core/cb.project/static/index.js delete mode 100755 core/cb.project/static/run.sh delete mode 100644 core/cb.project/static/sample/index.html delete mode 100644 core/cb.rpc.addons/main.js delete mode 100644 core/cb.rpc.addons/package.json delete mode 100644 core/cb.rpc.addons/service.js delete mode 100644 core/cb.rpc.auth/main.js delete mode 100644 core/cb.rpc.auth/package.json delete mode 100644 core/cb.rpc.auth/service.js delete mode 100644 core/cb.rpc.box/main.js delete mode 100644 core/cb.rpc.box/package.json delete mode 100644 core/cb.rpc.box/service.js delete mode 100644 core/cb.rpc.codecomplete/main.js delete mode 100644 core/cb.rpc.codecomplete/package.json delete mode 100644 core/cb.rpc.codecomplete/service.js delete mode 100644 core/cb.rpc.debug/main.js delete mode 100644 core/cb.rpc.debug/package.json delete mode 100644 core/cb.rpc.debug/service.js delete mode 100644 core/cb.rpc.deploy/main.js delete mode 100644 core/cb.rpc.deploy/package.json delete mode 100644 core/cb.rpc.deploy/service.js delete mode 100644 core/cb.rpc.proc/main.js delete mode 100644 core/cb.rpc.proc/package.json delete mode 100644 core/cb.rpc.proc/service.js delete mode 100644 core/cb.rpc.project/main.js delete mode 100644 core/cb.rpc.project/package.json delete mode 100644 core/cb.rpc.project/service.js delete mode 100644 core/cb.rpc.run/main.js delete mode 100644 core/cb.rpc.run/package.json delete mode 100644 core/cb.rpc.run/service.js delete mode 100644 core/cb.rpc.search/main.js delete mode 100644 core/cb.rpc.search/package.json delete mode 100644 core/cb.rpc.search/service.js delete mode 100644 core/cb.rpc.shells/main.js delete mode 100644 core/cb.rpc.shells/package.json delete mode 100644 core/cb.rpc.shells/service.js delete mode 100644 core/cb.rpc.users/main.js delete mode 100644 core/cb.rpc.users/package.json delete mode 100644 core/cb.rpc.users/service.js delete mode 100644 core/cb.rpc/main.js delete mode 100644 core/cb.rpc/manager.js delete mode 100644 core/cb.rpc/package.json delete mode 100644 core/cb.run.file/commands.json delete mode 100644 core/cb.run.file/main.js delete mode 100644 core/cb.run.file/package.json delete mode 100644 core/cb.run.ports/main.js delete mode 100644 core/cb.run.ports/package.json delete mode 100644 core/cb.run.project/main.js delete mode 100644 core/cb.run.project/package.json delete mode 100644 core/cb.run.project/project.js delete mode 100644 core/cb.search/code.js delete mode 100644 core/cb.search/files.js delete mode 100644 core/cb.search/main.js delete mode 100644 core/cb.search/package.json delete mode 100644 core/cb.search/types.js delete mode 100644 core/cb.server/main.js delete mode 100644 core/cb.server/package.json delete mode 100644 core/cb.settings/main.js delete mode 100644 core/cb.settings/package.json delete mode 100644 core/cb.shells.stream/main.js delete mode 100644 core/cb.shells.stream/package.json delete mode 100644 core/cb.shells/main.js delete mode 100644 core/cb.shells/package.json delete mode 100644 core/cb.socket.io/main.js delete mode 100644 core/cb.socket.io/package.json delete mode 100644 core/cb.vfs.http/main.js delete mode 100644 core/cb.vfs.http/package.json delete mode 100644 core/cb.vfs/main.js delete mode 100644 core/cb.vfs/package.json delete mode 100644 core/cb.watch/init.js delete mode 100644 core/cb.watch/main.js delete mode 100644 core/cb.watch/package.json delete mode 100644 core/codebox.js delete mode 100644 core/utils.js create mode 100644 editor/collections/commands.js create mode 100644 editor/collections/packages.js create mode 100644 editor/core/application.js create mode 100644 editor/core/commands.js create mode 100644 editor/core/packages.js rename {client/core/backends => editor/core}/rpc.js (73%) create mode 100644 editor/core/statusbar.js create mode 100644 editor/main.js create mode 100644 editor/models/command.js create mode 100644 editor/models/package.js create mode 100644 editor/resources/init.js create mode 100644 editor/resources/stylesheets/main.less create mode 100644 editor/resources/stylesheets/variables.less create mode 100644 editor/utils/dialogs.js rename {client => editor}/utils/dragdrop.js (94%) rename {client => editor}/views/grid.js (99%) delete mode 100644 index.js delete mode 100755 init.sh create mode 100644 lib/index.js create mode 100644 lib/packages.js create mode 100644 lib/rpc.js create mode 100644 lib/services/fs.js create mode 100644 lib/services/index.js create mode 100644 lib/services/packages.js delete mode 100644 screenshot.png delete mode 100644 tasks/grunt-build-addons.js diff --git a/.gitignore b/.gitignore index 8cf05519..f1960bc6 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,5 @@ settings.json */**/addon-built.js */**/node_modules/ /extras/ - +packages +build diff --git a/Gruntfile.js b/Gruntfile.js index e1270702..7dd69677 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,274 +1,51 @@ -module.exports = function (grunt) { - var fs = require('fs'); - var path = require("path"); - var pkg = require("./package.json"); - var _ = require('lodash'); +var path = require("path"); +var pkg = require("./package.json"); +module.exports = function (grunt) { // Path to the client src - var clientPath = path.resolve(__dirname, "client"); - - // Constants - var NW_VERSION = "0.8.4"; + var srcPath = path.resolve(__dirname, "editor"); + var buildPath = path.resolve(__dirname, "build"); // Load grunt modules - grunt.loadNpmTasks('hr.js'); - grunt.loadNpmTasks('grunt-exec'); - grunt.loadNpmTasks('grunt-contrib-compress'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-hr-builder'); // Init GRUNT configuraton grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - hr: { - build: { + "pkg": pkg, + "hr": { + "app": { + "source": path.resolve(__dirname, "node_modules/happyrhino"), + // Base directory for the application - "base": clientPath, + "base": srcPath, // Application name "name": "Codebox", // Mode debug - "debug": process.env.CLIENT_DEBUG != null, + "debug": true, // Main entry point for application "main": "main", - "index": grunt.file.read(path.resolve(clientPath, "index.html")), // Build output directory - "build": path.resolve(clientPath, "build"), + "build": buildPath, - // Static files mappage - "static": { - "images": path.resolve(clientPath, "resources", "images"), - "fonts": path.resolve(clientPath, "resources", "fonts") - }, + // Static files map + "static": {}, // Stylesheet entry point - "style": path.resolve(clientPath, "resources/stylesheets/main.less"), - - // Modules paths - 'paths': { - 'moment': 'vendors/moment' - }, - "shim": { - 'resources/resources': { - deps: [ - 'vendors/bootstrap/carousel', - 'vendors/bootstrap/dropdown', - 'vendors/bootstrap/button', - 'vendors/bootstrap/modal', - 'vendors/bootstrap/affix', - 'vendors/bootstrap/alert', - 'vendors/bootstrap/collapse', - 'vendors/bootstrap/tooltip', - 'vendors/bootstrap/popover', - 'vendors/bootstrap/scrollspy', - 'vendors/bootstrap/tab', - 'vendors/bootstrap/transition', - 'vendors/taphold' - ] - }, - 'vendors/socket.io': { - exports: 'io' - }, - 'vendors/crypto': { - exports: 'CryptoJS' - }, - 'vendors/diff_match_patch': { - exports: 'diff_match_patch' - }, - 'vendors/mousetrap': { - exports: 'Mousetrap' - }, - 'vendors/filer': { - exports: 'Filer', - deps: [ - 'vendors/idb.filesystem' - ] - } - }, - 'args': { - 'version': pkg.version, - 'debug': process.env.CLIENT_DEBUG != null - }, - 'options': { - - } - } - }, - exec: { - publish: { - command: "npm publish", - cwd: '.tmp/', - stdout: true, - stderr: true - }, - build_files_editor: { - command: "npm install", - cwd: './addons/cb.files.editor/', - stdout: true, - stderr: true - }, - clean_addons: { - command: "rm -rf */**/addon-built.js ./addons/**/node_modules", - cwd: '.', - stdout: true, - stderr: true - }, - clean_addons_tmp: { - command: "rm -rf */**/addon-built.js", - cwd: '.tmp/', - stdout: true, - stderr: true - } - }, - copy: { - // Copy most files over - tmp: { - expand: true, - dot: false, - cwd: './', - dest: '.tmp/', - src: [ - // Most files except the ones below - "./**", - - // Ignore gitignore - "!.gitignore", - - // Ignore dev related things - "!./tmp/**", - "!./.git/**", - "!./.addons/**", - "!./appBuilds/**", - - // grunt.file.copy duplicates symbolic and hard links - // so we need to copy it with the shell - "!./extras/**", - - // Only take "./client/build" - "!./client/**", - "./client/build/**", - - // Ignore some build time only modules - "./node_modules/.bin/**", - "!./node_modules/grunt/**", - "!./node_modules/grunt-*/**", - "!./node_modules/hr.js/**", - - // Exclude test directories from node modules - "!./node_modules/**/test/**", - ], - - // Preserve permissions - options: { - mode: true - } - } - }, - compress: { - tmp: { - options: { - mode: 'gzip', - pretty: true - }, - expand: true, - src: [ - // Codebox Built addons - '.tmp/addons/*/addon-built.js', - - // Ace source - '.tmp/addons/cb.files.editor/ace/**', - - // HR.js application - '.tmp/client/build/static/application.{js,css}' - ], - filter: function(src) { - // Compressable file formats - if(!_.contains([ - 'js', - 'css', - 'svg', - 'less', - 'html', - 'snippets' - ], - path.extname(src).slice(1) - )) return false; - try { - // We don't want to gzip tiny files - // Skip files < 10kb - return fs.statSync(src).size > 10*1024; - } catch(err) {} - return false; - } - } - }, - clean: { - tmp: ['.tmp/'] - }, - buildAddons: { - tmp: { - addonsFolder: ".tmp/addons/" - }, - dev: { - addonsFolder: "./addons/", - force: false + "style": path.resolve(srcPath, "resources/stylesheets/main.less") } } }); - // Load in any and all tasks in the `tasks` folder - grunt.loadTasks('tasks'); - - // Rebuild all addons - grunt.registerTask('rebuildAddons', [ - 'exec:clean_addons', - 'buildAddons:dev' - ]); - // Build grunt.registerTask('build', [ - 'hr', - 'exec:build_files_editor', - 'buildAddons:dev' + 'hr:app' ]); - // Build tmp directory - grunt.registerTask('tmp', [ - 'build', - 'clean:tmp', - 'copy:tmp', - 'exec:clean_addons_tmp', - 'buildAddons:tmp', - 'compress:tmp' - ]); - - // Publish to NPM - grunt.registerTask('publish', [ - 'tmp', - 'exec:publish', - 'clean:tmp' - ]); - - // Run - grunt.registerTask('run', function() { - var done = this.async(); - var options = this.options({}); - - grunt.util.spawn({ - cmd: "node", - opts: { - cwd: path.resolve(__dirname), - stdio: 'inherit' - }, - args: ["./bin/codebox.js", "run"] - }, done); - }); - grunt.registerTask('default', [ - 'build', - 'run' + 'build' ]); }; diff --git a/README.md b/README.md index 01266b44..51f6474c 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,3 @@ # Codebox -> "Open source cloud & desktop IDE." -Codebox is a complete and modular Cloud IDE. It can run on any unix-like machine (Linux, Mac OS X). It is an open source component of [codebox.io](https://www.codebox.io) (Cloud IDE as a Service). - -The IDE can run on your desktop (Linux or Mac), on your server or the cloud. You can use the [codebox.io](https://www.codebox.io) service to host and manage IDE instances. - -Codebox is built with web technologies: `node.js`, `javascript`, `html` and `less`. The IDE possesses a very modular and extensible architecture, that allows you to build your own features with through add-ons. Codebox is the first open and modular IDE capable of running both on the Desktop and in the cloud (with offline support). - -The project is open source under the [Apache 2.0](https://github.com/FriendCode/codebox/blob/master/LICENSE) license. -A screencast of the IDE is available on [Youtube](https://www.youtube.com/watch?v=xvPEngyXA2A). - -![Image](https://raw.github.com/FriendCode/codebox/master/screenshot.png) - -## How to install and run Codebox - -#### Desktop Applications - -Installers for the latest stable build for **Mac** and **Linux** can be downloaded on the [release page](https://github.com/FriendCode/codebox/releases). - -Instructions on how to install it can be found for each release. - -#### Install from NPM - -Codebox can be installed as a Node package and use programatically or from the command line. - -Install Codebox globally using NPM: -``` -$ npm install -g codebox -``` - -And start the IDE from the command line: -``` -$ codebox run ./myworkspace --open -``` - -Use this command to run and open Codebox IDE. By default, Codebox uses GIT to identify you, you can use the option ```--email=john.doe@gmail.com``` to define the email you want to use during GIT operations. - -Others comand line options are available and can be list with: ```codebox --help```. For deeper configuration, take a look at the documentation about [environment variables](http://help.codebox.io/ide/env.html). - -#### Need help? - -The IDE's documentation can be found at [help.codebox.io](http://help.codebox.io). Feel free to ask any questions or signal problems by adding issues. - -## Helping Codebox - -**I want to help with the code:** Codebox accepts pull-requests, please see the [Contributing to Codebox](https://github.com/FriendCode/codebox/blob/master/CONTRIBUTING.md) guide for information on contributing to this project. And don't forget to add your contact informations on the AUTHORS list. - -**I found a bug:** File it as an [issue](https://github.com/FriendCode/codebox/issues) and please describe as much as possible the bug and the context. - -**I have a new suggestion:** For feature requests please first check [the issues list](https://github.com/FriendCode/codebox/issues) to see if it's already there. If not, feel free to file it as an issue and to define the label **enhancement**. - -## Contact info - -* **Website:** [www.codebox.io](https://www.codebox.io) -* **Twitter:** [@CodeboxIO](https://twitter.com/CodeboxIO) -* **Blog:** [blog.codebox.io](http://blog.codebox.io) -* **Youtube:** [Codebox Channel](http://www.youtube.com/channel/UCWocQwS2VmDS3Ej0LQYWVIw) +This is an unstable version of the new codebox. diff --git a/addons/cb.debug/client.js b/addons/cb.debug/client.js deleted file mode 100644 index 54e005de..00000000 --- a/addons/cb.debug/client.js +++ /dev/null @@ -1,72 +0,0 @@ -define([ - "views/tab", - "settings" -], function(DebugTab, settings) { - var Q = codebox.require("hr/promise"); - var _ = codebox.require("hr/utils"); - var File = codebox.require("models/file"); - var toolbar = codebox.require("core/commands/toolbar"); - var dialogs = codebox.require("utils/dialogs"); - var files = codebox.require("core/files"); - var tabs = codebox.require("core/tabs"); - var box = codebox.require("core/box"); - var debugManager = codebox.require("core/debug/manager"); - - // Add files handler - var filesHandler = files.addHandler("debug", { - icon: "bug", - name: "Debug", - valid: function(file) { - return (!file.isDirectory()); - }, - open: function(file) { - if (file.path() != settings.user.get("path")) { - settings.user.set("path", file.path()); - settings.user.save(); - } - - return debugManager.open() - .then(function(dbg) { - return tabs.add(DebugTab, { - 'dbg': dbg, - 'path': file.path(), - 'tool': settings.user.get("tool") == "auto" ? null : settings.user.get("tool"), - 'argument': settings.user.get("argument") - }, { - 'type': "debug", - 'section': "debug" - }); - }); - } - }); - - // Debugging command - toolbar.register("debug.open", { - category: "Debug", - title: "Debugger", - description: "Open Debugger", - icons: { - 'default': "bug", - }, - offline: false, - shortcuts: [ - "alt+d" - ] - }, function(path) { - path = path || settings.user.get("path"); - - if (!path) { - dialogs.alert("No file specified", "Click left on a file and select 'Debug' to open it with the debugger, it'll be saved in your settings as last debugged file."); - return; - } - - var f = new File(); - - return f.getByPath(path) - .then(function() { - return filesHandler.open(f); - }, function() { - dialogs.alert("File not found", "File "+_.escape(path)+" doesn't exists. Click left on an another file and select 'Debug' to open it with the debugger."); - }); - }); -}); \ No newline at end of file diff --git a/addons/cb.debug/package.json b/addons/cb.debug/package.json deleted file mode 100644 index 040b64d1..00000000 --- a/addons/cb.debug/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.debug", - "version": "0.1.0", - "title": "Debug", - "description": "Debugger integration inside codebox", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.debug/settings.js b/addons/cb.debug/settings.js deleted file mode 100644 index 35657580..00000000 --- a/addons/cb.debug/settings.js +++ /dev/null @@ -1,42 +0,0 @@ -define([], function() { - var settings = codebox.require("core/settings"); - - // Add settings - return settings.add({ - 'namespace': "debug", - 'title': "Debug", - 'defaults': { - 'path': "", - 'argument': null, - 'tool': "auto" - }, - 'fields': { - 'path': { - 'label': 'File Path', - 'type': "text", - 'help': "Click left on a file and select 'debug' to update this file." - }, - 'argument': { - 'label': 'Arguments', - 'type': "text", - 'help': "Arguments to run the file with." - }, - 'tool': { - 'label': 'Debugger', - 'type': "select", - 'help': "Force the use of a specific debugger.", - 'options': { - 'auto': "Auto", - 'pdb': "Python Debugger", - 'gdb': "Native Debugger (GDB)", - - // Still unstable: - /* - 'jdb': "Java Debugger", - 'rdb': "Ruby Debugger" - */ - } - } - } - }); -}); \ No newline at end of file diff --git a/addons/cb.debug/stylesheets/tab.less b/addons/cb.debug/stylesheets/tab.less deleted file mode 100644 index f25aeb6b..00000000 --- a/addons/cb.debug/stylesheets/tab.less +++ /dev/null @@ -1,99 +0,0 @@ -.addon-debugger-tab { - .component-grid .grid-section { - .grid-resize-bar-h, .grid-resize-bar-v { - background: rgba(0,0,0, 0.1); - } - } - - .debug-section { - h4 { - display: block; - width: 100%; - background: rgba(0,0,0,.05); - font-size: 14px; - padding: 6px 8px; - margin: 0px; - } - - .table-container { - position: absolute; - top: 27px; - bottom: 0px; - left: 0px; - right: 0px; - display: block; - margin: 0px; - overflow: auto; - } - - .table { - margin: 0px; - - tr { - td, th { - border-top-color: rgba(0,0,0, 0.05); - - a { - color: inherit; - } - } - } - } - - &.debug-console { - .line { - padding-bottom: 3px; - border-bottom: 1px solid rgba(0,0,0, 0.05); - - * { - line-height: 1.4em; - font-size: 14px; - } - - i { - float: left; - width: 24px; - text-align: center; - } - - pre { - margin: 0px; - padding: 0px; - background: none; - color: inherit; - border: none; - display: block; - margin-left: 24px; - font-family: inherit; - } - - &.error { - color: #a94442; - } - &.input { - padding-top: 3px; - padding-bottom: 0px; - border-color: transparent; - } - - input, input:focus { - color: inherit; - background: transparent; - box-shadow: none; - font-size: 14px; - line-height: 1.4em; - padding: 0px; - margin: 0px; - height: 19px; - margin-right: 24px; - width: 90%; - border: none; - } - } - - .console-body { - - } - } - } -} \ No newline at end of file diff --git a/addons/cb.debug/views/backtrace.js b/addons/cb.debug/views/backtrace.js deleted file mode 100644 index 906dc216..00000000 --- a/addons/cb.debug/views/backtrace.js +++ /dev/null @@ -1,35 +0,0 @@ -define([ - "views/section" -], function(DebugSection) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var rpc = codebox.require("core/backends/rpc"); - - var BacktraceSection = DebugSection.extend({ - title: "Backtrace", - formats: [ - { - id: "filename", - title: "File", - type: "file" - }, - { - id: "line", - title: "Line" - } - ], - - update: function() { - var that = this; - - return this.dbg.backtrace() - .then(function(stack) { - that.clearLines(); - _.each(stack, that.addLine, that); - }); - } - }); - - return BacktraceSection; -}); diff --git a/addons/cb.debug/views/breakpoints.js b/addons/cb.debug/views/breakpoints.js deleted file mode 100644 index 15a16211..00000000 --- a/addons/cb.debug/views/breakpoints.js +++ /dev/null @@ -1,39 +0,0 @@ -define([ - "views/section" -], function(DebugSection) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var rpc = codebox.require("core/backends/rpc"); - - var BreakpointsSection = DebugSection.extend({ - title: "Breakpoints", - formats: [ - { - id: "num", - title: "#" - }, - { - id: "filename", - title: "File", - type: "file" - }, - { - id: "line", - title: "Line" - } - ], - - update: function() { - var that = this; - - return this.dbg.breakpoints() - .then(function(breakpoints) { - that.clearLines(); - _.each(breakpoints, that.addLine, that); - }); - } - }); - - return BreakpointsSection; -}); diff --git a/addons/cb.debug/views/console.js b/addons/cb.debug/views/console.js deleted file mode 100644 index 718740f5..00000000 --- a/addons/cb.debug/views/console.js +++ /dev/null @@ -1,107 +0,0 @@ -define([], function() { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - - var ConsoleSection = hr.View.extend({ - className: "debug-section debug-console", - title: "Console", - defaults: { - dbg: null - }, - events: { - "click": "focus" - }, - logIcons: { - 'log': "fa fa-blank", - 'input': "fa fa-angle-right", - 'error': "fa fa-times-circle" - }, - - initialize: function(options) { - var that = this; - ConsoleSection.__super__.initialize.apply(this, arguments); - - // Debugger client - this.dbg = this.options.dbg; - - this.$title = $("

", { - 'text': this.title - }); - - this.$container = $("
", { - 'class': "table-container" - }); - - this.$body = $("
", { - 'class': "console-body" - }); - - this.$input = $("", { - 'class': "form-control input-sm", - 'keyup': function(e) { - var key = e.which || e.keyCode; - var code = $(e.currentTarget).val(); - - if (key == 13) { - /* ENTER */ - e.preventDefault(); - - that.eval(code); - $(e.currentTarget).val(""); - } - } - }); - - - this.$body.appendTo(this.$container); - this.$input.appendTo($("
", { - 'class': "line input", - 'html': '' - }).appendTo(this.$container)); - - this.$title.appendTo(this.$el); - this.$container.appendTo(this.$el); - - return this; - }, - - addLine: function(output) { - var $line = $("
", { - 'class': "line "+output.type - }); - var $pre = $("
", {
-                'text': output.content
-            });
-            var $icon = $("", {
-                'class': this.logIcons[output.type]
-            });
-
-            $icon.appendTo($line);
-            $pre.appendTo($line);
-
-            $line.appendTo(this.$body);
-
-            // Scroll
-            this.$container.animate({ scrollTop: this.$container[0].scrollHeight}, 100);
-        },
-
-        // Eval some code
-        eval: function(code) {
-            this.addLine({
-                type: "input",
-                content: code
-            });
-            return this.dbg.eval(code)
-            .then(_.bind(this.addLine, this));
-        },
-
-        // Focus the console
-        focus: function(e) {
-            if (e) e.preventDefault();
-            this.$input.focus();
-        }
-    });
-
-    return ConsoleSection;
-});
diff --git a/addons/cb.debug/views/locals.js b/addons/cb.debug/views/locals.js
deleted file mode 100644
index 650bb79d..00000000
--- a/addons/cb.debug/views/locals.js
+++ /dev/null
@@ -1,39 +0,0 @@
-define([
-    "views/section"
-], function(DebugSection) {
-    var _ = codebox.require("hr/utils");
-    var $ = codebox.require("hr/dom");
-    var hr = codebox.require("hr/hr");
-    var rpc = codebox.require("core/backends/rpc");
-
-    var LocalsSection = DebugSection.extend({
-        title: "Locals",
-        formats: [
-            {
-                id: "name",
-                title: "Name"
-            },
-            {
-                id: "value",
-                title: "Value"
-            }
-        ],
-
-        update: function() {
-            var that = this;
-            
-            return this.dbg.locals()
-            .then(function(locals) {
-                that.clearLines();
-                _.each(locals, function(value, key) {
-                    that.addLine({
-                        'name': key,
-                        'value': value
-                    });
-                });
-            });
-        }
-    });
-
-    return LocalsSection;
-});
diff --git a/addons/cb.debug/views/section.js b/addons/cb.debug/views/section.js
deleted file mode 100644
index 55222b31..00000000
--- a/addons/cb.debug/views/section.js
+++ /dev/null
@@ -1,100 +0,0 @@
-define([], function() {
-    var _ = codebox.require("hr/utils");
-    var $ = codebox.require("hr/dom");
-    var hr = codebox.require("hr/hr");
-
-    var files = codebox.require("core/files");
-
-    var DebugSection = hr.View.extend({
-        className: "debug-section",
-        defaults: {
-            dbg: null
-        },
-        events: {},
-        formats: [],
-
-        initialize: function(options) {
-            DebugSection.__super__.initialize.apply(this, arguments);
-            
-            // Debugger client
-            this.dbg = this.options.dbg;
-
-            this.$title = $("

", { - 'text': this.title - }); - - this.$container = $("
", { - 'class': "table-container" - }); - - this.$table = $("", { - 'class': "table" - }); - - this.$title.appendTo(this.$el); - this.$container.appendTo(this.$el); - this.$table.appendTo(this.$container); - - this.clearLines(); - - return this; - }, - - // Render - render: function() { - return this.ready(); - }, - - // Clear items - clearLines: function() { - this.$table.empty(); - - // Initiliaze format - var $line = $(""); - - _.each(this.formats, function(key) { - $(""); - - _.each(this.formats, function(key) { - var $e; - var value = item[key.id]; - - if (key.type == "file") { - $e = $("", { - 'href': "#", - 'text': value, - 'click': function(e) { - e.preventDefault(); - files.open(value, { - line: item.line - }); - } - }) - } else { - $e = $("", { - 'text': value - }); - } - - $e.appendTo($("
", { - 'text': key.title - }).appendTo($line); - }); - $line.appendTo(this.$table); - }, - - // Add an item - addLine: function(item) { - var $line = $("
").appendTo($line)); - }); - $line.appendTo(this.$table); - }, - - // Update content - update: function() { - // to defined - } - }); - - return DebugSection; -}); diff --git a/addons/cb.debug/views/tab.js b/addons/cb.debug/views/tab.js deleted file mode 100644 index dcff112b..00000000 --- a/addons/cb.debug/views/tab.js +++ /dev/null @@ -1,201 +0,0 @@ -define([ - "views/section", - "views/locals", - "views/backtrace", - "views/breakpoints", - "views/console", - "less!stylesheets/tab.less" -], function( DebugSection, LocalsSection, BacktraceSection, BreakpointsSection, ConsoleSection) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var Command = codebox.require("models/command"); - var Tab = codebox.require("views/tabs/base"); - var box = codebox.require("core/box"); - var user = codebox.require("core/user"); - var dialogs = codebox.require("utils/dialogs"); - var debugManager = codebox.require("core/debug/manager"); - - var GridView = codebox.require("views/grid"); - - var DebugTab = Tab.extend({ - className: Tab.prototype.className+ " addon-debugger-tab", - defaults: { - - }, - menuTitle: "Debugger", - events: { - - }, - - initialize: function(options) { - var that = this; - DebugTab.__super__.initialize.apply(this, arguments); - - this.dbg = this.options.dbg; - - - // Create sections - this.console = new ConsoleSection({ - dbg: this.dbg - }); - this.locals = new LocalsSection({ - dbg: this.dbg - }); - this.backtrace = new BacktraceSection({ - dbg: this.dbg - }); - this.breakpoints = new BreakpointsSection({ - dbg: this.dbg - }); - - // Listen events - this.listenTo(this.dbg, "close", function() { - this.closeTab(); - }); - this.listenTo(this.dbg, "update", function() { - this.updateState(); - }); - this.listenTo(this.dbg, "error", function(err) { - this.console.addLine({ - type: "error", - content: err.message || err - }); - }); - this.listenTo(this.dbg, "log", function(message) { - this.console.addLine({ - type: "log", - content: message - }); - }); - - // Create grids for sections - this.gridV = new GridView({ - columns: 1 - }); - this.gridH = new GridView({ - columns: 1000 - }); - - this.gridH.addView(this.breakpoints); - this.gridH.addView(this.backtrace); - this.gridH.addView(this.locals); - - this.gridV.addView(this.gridH); - this.gridV.addView(this.console); - this.gridV.appendTo(this); - - - // Base commands: start, stop, next, continue, restart - this.commandStart = new Command({}, { - title: "Start", - action: function() { - that.dbg.start(that.options.argument); - } - }); - this.commandStop = new Command({}, { - title: "Stop", - action: function() { - that.dbg.stop(); - } - }); - this.commandNext = new Command({}, { - title: "Next", - action: function() { - that.dbg.next(); - } - }); - this.commandContinue = new Command({}, { - title: "Continue", - action: function() { - that.dbg.cont(); - } - }); - this.commandRestart = new Command({}, { - title: "Restart", - action: function() { - that.dbg.restart(); - } - }); - - // Describe debug tab - this.setTabTitle("Debugger "+this.options.path); - - // Tab menu - this.menu - .menuSection([ - this.commandStart, - this.commandStop, - this.commandRestart - ]) - .menuSection([ - this.commandNext, - this.commandContinue - ]) - .menuSection([ - { - 'type': "checkbox", - 'title': "Exit", - 'action': function(state) { - that.closeTab(); - } - } - ]); - - // Statusbar menu - this.statusbar.add([ - this.commandRestart, - this.commandContinue, - this.commandNext, - this.commandStop, - this.commandStart - ]); - - // Start debugger - this.dbg.init({ - 'tool': this.options.tool, - 'path': this.options.path, - 'breakpoints': debugManager.breakpoints.all() - }); - - // Bind event on breakponts changements - this.listenTo(debugManager.breakpoints, "change", function(e) { - if (e.change == "add") { - this.dbg.breakpointAdd({ - 'path': e.path, - 'line': e.line - }); - } else { - var point = this.dbg.getBreakpoint({ - 'path': e.path, - 'line': e.line - }); - - if (point) this.dbg.breakpointRemove(point.num); - } - }); - - // Bind close tab - this.on("tab:close", function() { - this.dbg.close(); - }, this); - - return this; - }, - - // Render - render: function() { - return this.ready(); - }, - - - // Update debugegr state: stack, locals - updateState: function() { - this.locals.update(); - this.backtrace.update(); - this.breakpoints.update(); - } - }); - - return DebugTab; -}); diff --git a/addons/cb.deploy/client.js b/addons/cb.deploy/client.js deleted file mode 100644 index 34de51eb..00000000 --- a/addons/cb.deploy/client.js +++ /dev/null @@ -1,240 +0,0 @@ -define([], function() { - var Q = codebox.require("hr/promise"); - var _ = codebox.require("hr/utils"); - var dialogs = codebox.require("utils/dialogs"); - var box = codebox.require("core/box"); - var rpc = codebox.require("core/backends/rpc"); - var Command = codebox.require("models/command"); - var menu = codebox.require("core/commands/menu"); - var user = codebox.require("core/user"); - - var CryptoJS = codebox.require("vendors/crypto"); - - // Settings for deployment - var settings = user.settings("deploymentSolutions"); - - // Return list of solutions - var getSolutionTypes = function() { - return rpc.execute("deploy/solutions"); - }; - - // Return infos for a specific solution type - var getSolutionType = function(id) { - return getSolutionTypes().then(function(_types) { - var s = _.find(_types, function(_type) { - return _type.id == id; - }); - if (!s) throw "Invalid solution type"; - return s; - }); - }; - - // Id for a solution name - var solutionId = function(name) { - return CryptoJS.MD5(name).toString(); - }; - - // Add a solution - var addSolution = function(name, solution) { - var solutions = settings.get("solutions", {}); - var id = solutionId(name); - if (solutions[id]) return Q.reject("Solution already exists"); - solutions[id] = { - 'name': name, - 'type': solution, - 'settings': {} - }; - settings.set("solutions", solutions); - return settings.save().then(function() { - return solutions[id]; - }); - }; - - // Remove a solution - var removeSolution = function(id) { - var solutions = settings.get("solutions", {}); - if (!solutions[id]) return Q.reject("Invalid solution"); - delete solutions[id]; - settings.set("solutions", solutions); - return settings.save(); - }; - - // Run a solution - var runSolution = function(solution, actionId) { - if (_.isString(solution)) solution = getSolution(solution); - - return rpc.execute("deploy/run", { - 'solution': solution.type, - 'action': actionId, - 'config': solution.settings - }) - .then(function(data) { - // Handle shells - if (data.shellId) { - box.openTerminal(data.shellId, { - id: "deploy."+solutionId(solution.name)+"."+actionId, - title: data.title || "Deployment to "+solution.name+" ("+actionId+")", - icons: { - 'default': "fa-cloud-upload", - } - }); - } - // Handle message - else if (data.message) { - dialogs.alert("Deployment to "+solution.name+" ("+actionId+")", data.message); - } - }, function(err) { - dialogs.alert("Error with "+solution.name, err.message || err); - }); - }; - - // Return solution informations by its id - var getSolution = function(id) { - var solutions = settings.get("solutions", {}); - return solutions[id]; - }; - - var setSolutionSettings = function(id, _settings) { - var solutions = settings.get("solutions", {}); - solutions[id].settings = _settings; - settings.set("solutions", solutions); - }; - - // Open settings for a solution - var openSettings = function(id) { - var solution = getSolution(id); - return getSolutionType(solution.type).then(function(_type) { - return dialogs.fields("Configuration for "+_.escape(solution.name), _type.settings, solution.settings); - }) - .then(function(newSettings) { - setSolutionSettings(id, newSettings); - return settings.save(); - }); - }; - - // Command to add a new deployment solution - var addCommand = Command.register("deploy.solutions.add", { - category: "Deployment", - title: "Add Solution", - description: "Add a solution", - offline: false, - action: function(page) { - getSolutionTypes().then(function(solutionTypes) { - return dialogs.fields("Add Deployment Solution", { - name: { - type: "text", - label: "Label" - }, - solution: { - type: "select", - label: "Type", - options: _.object(_.map(solutionTypes, function(solution) { - return [ - solution.id, - solution.name - ]; - })) - } - }); - }) - .then(function(data) { - if (!data.name || !data.solution) throw "Need 'name' and 'solution'"; - return addSolution(data.name, data.solution); - }) - .then(function(solution) { - return openSettings(solutionId(solution.name)); - }); - } - }); - - // Command to remove a solution - var removeCommand = Command.register("deploy.solutions.remove", { - category: "Deployment", - title: "Remove Solution", - description: "Remove a solution", - offline: false, - action: function() { - dialogs.select("Remove Deployment Solution", - "Select a solution, this solution and its configuration will be removed from your settings.", - _.chain(settings.get("solutions", {})) - .map(function(solution, id) { - return [id, solution.name] - }) - .object() - .value()).then(removeSolution); - } - }); - - // Deploy Menu - var deployMenu = menu.register("deploy", { - title: "Deploy", - position: 90, - offline: false - }); - - // Update list of solutions - var updateSolutions = function() { - return getSolutionTypes().then(function(_types) { - var solutions = settings.get("solutions", {}); - - deployMenu.clearMenu(); - - // Add command to create new solutions - deployMenu.menuSection(_.compact([ - addCommand, - _.size(solutions) > 0 ? removeCommand : null - ])); - - // Add all solutions - if (_.size(solutions) == 0) return; - deployMenu.menuSection( - _.chain(solutions) - .map(function(solution, solutionId) { - var solutionType = _.find(_types, function(_type) { - return _type.id == solution.type; - }); - if (!solutionType) return null; - - var command = Command.register({ - title: solution.name, - type: "menu", - offline: false, - action: function() { - openSettings(solutionId(solution.name)); - } - }); - - command.menuSection( - _.map(solutionType.actions, function(action) { - return { - title: action.name, - offline: false, - action: function() { - return runSolution(solution, action.id); - } - }; - }) - ); - - command.menuSection([ - { - title: "Configure", - offline: false, - action: function() { - openSettings(solutionId); - } - } - ]); - - return command; - }) - .compact() - .value() - ); - }); - - }; - - updateSolutions(); - settings.change(updateSolutions); -}); \ No newline at end of file diff --git a/addons/cb.deploy/package.json b/addons/cb.deploy/package.json deleted file mode 100644 index c341704f..00000000 --- a/addons/cb.deploy/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.deploy", - "version": "0.1.0", - "title": "Project", - "description": "Deployment menu for all solutions", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.files.editor/ace.js b/addons/cb.files.editor/ace.js deleted file mode 100644 index 7090ee09..00000000 --- a/addons/cb.files.editor/ace.js +++ /dev/null @@ -1,10 +0,0 @@ -define([ - "ace/ace", - - // All the ace extensions we used - "ace/ext-modelist", - "ace/ext-language_tools", - "ace/ext-whitespace" -], function() { - return window.ace; -}); \ No newline at end of file diff --git a/addons/cb.files.editor/build.sh b/addons/cb.files.editor/build.sh deleted file mode 100755 index e6b2524b..00000000 --- a/addons/cb.files.editor/build.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -# This script will prepare ace for running properly - -RM_EXTENSIONS=(elastic_tabstops_lite chromevox statusbar emmet error_marker keybinding_menu old_ie textarea themelist static_highlight split spellcheck settings_menu) -RM_LANG=(abap cobol forth mushcode vbscript tcl velocity pascal powershell asciidoc apache_conf ada soy_template verilog vhdl autohotkey batchfile c9search) - -# Sed like command using perl -# We need this because on OS X, sed does not support ignoring case -function PSED { - perl -C -e 'use utf8;' -i -pe $1 $2 -} - -# Remove useless extensions -for ext in ${RM_EXTENSIONS[*]} -do - echo "Remove extension $ext" - rm -f ace/ext-$ext.js -done - -# Remove languages -for lang in ${RM_LANG[*]} -do - echo "Remove language $lang" - - # Remove the files - rm -f "ace/mode-$lang.js" "ace/snippets/$lang.js" "ace/worker-$lang.js" - - # Remove any references in ext-modelist - - # Remove extension mapping - PSED "s/,?${lang}\:\[\"[^\"]+?\"\]//gi" ace/ext-modelist.js - - # Remove readable name mapping - PSED "s/,?${lang}\:\"\w+\"//gi" ace/ext-modelist.js -done - -# Cleanup our previous replaces -# Remove any bad comas left over from modelist -PSED "s/\{,/{/gi" ace/ext-modelist.js -PSED "s/,\}/{/gi" ace/ext-modelist.js - -# Detect empty snippets -# using the value of their 'snippetText' variable -SREGEX="snippetText=(\"\"|\'\')" - -# Remove empty snippet files -find ./ace/snippets -name "*.js" -print | \ -xargs grep -E ${SREGEX} -l | \ -xargs rm -f - - -# Remove useless themes -echo "Removes themes" -rm -rf ace/theme-*.js \ No newline at end of file diff --git a/addons/cb.files.editor/client.js b/addons/cb.files.editor/client.js deleted file mode 100644 index 9619f770..00000000 --- a/addons/cb.files.editor/client.js +++ /dev/null @@ -1,28 +0,0 @@ -define([ - "ace", - "editor/view" -], function(ace, FileEditorView) { - var $ = codebox.require("hr/dom"); - var commands = codebox.require("core/commands/toolbar"); - var files = codebox.require("core/files"); - - var aceconfig = ace.require("ace/config"); - aceconfig.set("basePath", "static/addons/cb.files.editor/ace"); - - // Add files handler - files.addHandler("ace", { - 'name': "Edit", - 'fallback': true, - 'setActive': true, - 'position': 5, - 'View': FileEditorView, - 'valid': function(file) { - return (!file.isDirectory()); - } - }); - - // Return globals - return { - 'ace': ace - }; -}); \ No newline at end of file diff --git a/addons/cb.files.editor/download_ace.sh b/addons/cb.files.editor/download_ace.sh deleted file mode 100755 index 02e24e97..00000000 --- a/addons/cb.files.editor/download_ace.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# Ace version to pull -ACE_VERSION="ec3677e978de275bbe1ff8f21f4a157bdb9b8f9e" -ACE_URL="https://github.com/FriendCode/ace-builds/archive/${ACE_VERSION}.tar.gz" - -# Ace build we want to keep -ACE_SUB="src-min-noconflict" - -# Current folder -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# Destination folder -DEST="${DIR}/ace" - -# Make sure $DEST exists -mkdir -p ${DEST} - -# Check if it's already downloaded -if [ -f "${DEST}/ace.js" ]; then - echo "Ace is already downloaded" - echo "'rm -rf ace' if you want to redownload" - exit 0 -fi - -# Download tar.gz and pipe to tar -# decompressing it to $DEST -wget -O - ${ACE_URL} | tar -xzv -C ${DEST} --strip-components=2 ace-builds-${ACE_VERSION}/${ACE_SUB} diff --git a/addons/cb.files.editor/editor/breakpoints.js b/addons/cb.files.editor/editor/breakpoints.js deleted file mode 100644 index 8bad72b9..00000000 --- a/addons/cb.files.editor/editor/breakpoints.js +++ /dev/null @@ -1,102 +0,0 @@ -define([], function() { - var hr = codebox.require("hr/hr"); - - var EditorBreakpoints = hr.Class.extend({ - initialize: function() { - var that = this; - EditorBreakpoints.__super__.initialize.apply(this, arguments); - - this.editor = this.options.editor; - this.$editor = this.editor.editor; - - // Breakpoints list change, it signals the change to the box - this.$editor.session.on("changeBreakpoint", function() { - that.signalBreakpoints(); - }); - - // Add remove breakpoints by clicking the gutter - this.$editor.on("guttermousedown", function(e) { - var target = e.domEvent.target; - if (target.className.indexOf("ace_gutter-cell") == -1) - return; - if (!e.editor.isFocused()) - return; - if (e.clientX > 25 + target.getBoundingClientRect().left) - return; - - var row = e.getDocumentPosition().row; - - if (that.hasBreakpoint(row)) { - e.editor.session.clearBreakpoint(row) - } else { - e.editor.session.setBreakpoint(row); - } - e.stop(); - }); - - // Document change -> update breakpoints list - this.$editor.session.doc.on("change", function(e) { - var delta = e.data; - var range = delta.range; - var changed = false; - - if (range.end.row == range.start.row) - return; - - var len, firstRow; - len = range.end.row - range.start.row; - if (delta.action == "insertText") { - firstRow = range.start.column ? range.start.row + 1 : range.start.row; - } - else { - firstRow = range.start.row; - } - - if (delta.action[0] == "i") { - var args = Array(len); - args.unshift(firstRow, 0); - changed = true; - that.$editor.session.$breakpoints.splice.apply(that.$editor.session.$breakpoints, args); - } - else { - var rem = that.$editor.session.$breakpoints.splice(firstRow + 1, len); - - if (!that.$editor.session.$breakpoints[firstRow]) { - for (var i = rem.length; i--; ) { - if (rem[i]) { - changed = true; - that.$editor.session.$breakpoints[firstRow] = rem[i]; - break; - } - } - } - } - - if (changed) that.signalBreakpoints(); - }); - }, - - // Return list of active breakpoints in ace - getBreakpoints: function() { - return _.chain(this.$editor.session.getBreakpoints() || {}) - .map(function(value, key) { - if (!value) return null; - return parseInt(key)+1; - }) - .compact() - .value(); - }, - - // Check if has breakpoint at a line - hasBreakpoint: function(row) { - return _.contains(this.getBreakpoints(), row+1) - }, - - // Signal breakpoints list - signalBreakpoints: function() { - this.editor.model.setBreakpoints(this.getBreakpoints()); - } - }); - - return EditorBreakpoints; -}); \ No newline at end of file diff --git a/addons/cb.files.editor/editor/codecomplete.js b/addons/cb.files.editor/editor/codecomplete.js deleted file mode 100644 index 8f2fe97a..00000000 --- a/addons/cb.files.editor/editor/codecomplete.js +++ /dev/null @@ -1,31 +0,0 @@ -define([ - "ace" -], function(ace) { - var rpc = codebox.require("core/backends/rpc"); - var langTools = ace.require("ace/ext/language_tools"); - - var normalizeTag = function(tag) { - return { - 'name': tag.name, - 'value': tag.name, - 'score': 0, - 'meta': tag.meta || "" - }; - }; - - langTools.addCompleter({ - getCompletions: function(editor, session, pos, prefix, callback) { - if (prefix.length === 0) { callback(null, []); return } - - rpc.execute("codecomplete/get", { - 'query': prefix - }).then(function(data) { - callback(null, _.map(data.results, normalizeTag)); - }, function(err) { - callback(err); - }); - } - }); - - return {}; -}); \ No newline at end of file diff --git a/addons/cb.files.editor/editor/jshint.js b/addons/cb.files.editor/editor/jshint.js deleted file mode 100644 index 194bd2fe..00000000 --- a/addons/cb.files.editor/editor/jshint.js +++ /dev/null @@ -1,48 +0,0 @@ -define([], function() { - var File = codebox.require("models/file"); - var box = codebox.require("core/box"); - var Q = codebox.require("hr/promise"); - var _ = codebox.require("hr/utils"); - - var jshintFile = new File(); - - // Read the JSHint configuration from a file - var readJshintSettings = _.memoize(function() { - // Get file - return jshintFile.getByPath("/.jshintrc") - .then(function() { - //Read file - return jshintFile.read(); - }) - .then(function(content) { - // Parse JSON - return JSON.parse(content); - }); - }); - - // Apply JSHint config from a file to an editor - var applyJshintSettings = function(editor) { - var session = editor.session; - if (session.getMode().$id != "ace/mode/javascript") return Q.reject(new Error("Not a javascript editor")); - if (!session.$worker) return Q.reject(new Error("No JSHint worker")); - - return readJshintSettings() - .then(function(options) { - if (session.$worker) { - //session.$worker.send("changeOptions",[ {undef: true}]) - // or - session.$worker.send("setOptions",[options]) - } - return options; - }); - }; - - // Clear memoize cache when file change - jshintFile.on("file:change", function(e) { - readJshintSettings.cache = {}; - }); - - return { - 'applySettings': applyJshintSettings - }; -}); \ No newline at end of file diff --git a/addons/cb.files.editor/editor/settings.js b/addons/cb.files.editor/editor/settings.js deleted file mode 100644 index 61e696dd..00000000 --- a/addons/cb.files.editor/editor/settings.js +++ /dev/null @@ -1,93 +0,0 @@ -define([], function() { - var settings = codebox.require("core/settings"); - - // Add settings - var userSettings = settings.add({ - 'namespace': "editor", - 'title': "Code Editor", - 'defaults': { - 'theme': "github", - 'fontsize': "12", - 'printmargincolumn': 80, - 'showinvisibles': false, - 'showprintmargin': false, - 'highlightactiveline': false, - 'wraplimitrange': 80, - 'enablesoftwrap': false, - 'enablesofttabs': true, - 'stripspaces': false, - 'autocollaboration': true, - 'tabsize': 4, - 'keyboard': "textinput" - }, - 'fields': { - 'keyboard': { - 'label': "Keyboard mode", - 'type': "select", - 'options': { - "vim": "Vim", - "emacs": "Emacs", - "textinput": "Default" - } - }, - 'fontsize': { - 'label': "Font Size", - 'type': "number", - 'min': 10, - 'max': 30, - 'step': 1 - }, - 'printmargincolumn': { - 'label': "Print Margin Column", - 'type': "number", - 'min': 0, - 'max': 1000, - 'step': 1 - }, - 'wraplimitrange': { - 'label': "Wrap Limit Range", - 'type': "number", - 'min': 0, - 'max': 1000, - 'step': 1 - }, - 'autocollaboration': { - 'label': "Auto enable realtime collaboration", - 'type': "checkbox" - }, - 'showprintmargin': { - 'label': "Show Print Margin", - 'type': "checkbox" - }, - 'showinvisibles': { - 'label': "Show Invisibles", - 'type': "checkbox" - }, - 'highlightactiveline': { - 'label': "Highlight Active Line", - 'type': "checkbox" - }, - 'enablesoftwrap': { - 'label': "Enable Soft Wrap", - 'type': "checkbox" - }, - 'enablesofttabs': { - 'label': "Use Soft Tabs", - 'type': "checkbox" - }, - 'stripspaces': { - 'label': "Strip Whitespaces", - 'type': "checkbox" - }, - 'tabsize': { - 'label': "Tab Size", - 'type': "number", - 'min': 0, - 'max': 1000, - 'step': 1 - } - } - }); - - return userSettings; -}); \ No newline at end of file diff --git a/addons/cb.files.editor/editor/view.js b/addons/cb.files.editor/editor/view.js deleted file mode 100644 index fd723f82..00000000 --- a/addons/cb.files.editor/editor/view.js +++ /dev/null @@ -1,583 +0,0 @@ -define([ - "ace", - "editor/breakpoints", - "editor/codecomplete", - "editor/jshint", - "editor/settings", - "theme/textmate", - "text!templates/file.html", - "less!stylesheets/file.less", -], function(ace, Breakpoints, codecomplete, jshint, editorSettings, aceDefaultTheme, templateFile) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var alerts = codebox.require("utils/alerts"); - var FilesTabView = codebox.require("views/files/tab"); - var FileSync = codebox.require("utils/filesync"); - var user = codebox.require("core/user"); - var menu = codebox.require("core/commands/menu"); - var settings = codebox.require("core/settings"); - var Command = codebox.require("models/command"); - var themes = codebox.require("core/themes"); - var box = codebox.require("core/box"); - var collaborators = codebox.require("core/collaborators"); - var keyboard = codebox.require("utils/keyboard"); - var debugManager = codebox.require("core/debug/manager"); - - var logging = hr.Logger.addNamespace("editor"); - - // Import ace - var aceRange = ace.require("ace/range"); - var aceModes = ace.require("ace/ext/modelist"); - var aceLangs = ace.require("ace/ext/language_tools"); - var aceWhitespace = ace.require("ace/ext/whitespace"); - - - var FileEditorView = FilesTabView.extend({ - className: "addon-files-aceeditor", - templateLoader: "text", - template: templateFile, - defaults: {}, - events: {}, - shortcuts: { - "mod+s": "saveFile", - "mod+r": "runFile", - "mod+f": "searchInFile" - }, - - // Constructor - initialize: function() { - var that = this; - FileEditorView.__super__.initialize.apply(this, arguments); - - this.markersS = {}; - this.markersC = {}; - this._op_set = false; - - // Syntax menu command - var syntaxMenu = new Command({}, { - 'title': "Syntax", - 'type': "menu" - }); - syntaxMenu.menu.add(_.map(aceModes.modesByName, function(mode, name) { - return { - 'title': mode.caption, - 'action': function() { - that.setMode(name); - } - } - })); - - // Toggle collaboration - this.collaborationToggle = new Command({}, { - 'type': "checkbox", - 'title': "Toggle Collaboration Mode", - 'flags': this.model.isNewfile() ? "hidden": "", - 'offline': false, - 'action': function(state) { - that.editor - that.sync.updateEnv({ - 'sync': state - }); - } - }); - - // Collaborators - this.collaboratorsMenu = new Command({}, { - 'title': "Collaborators", - 'type': "menu", - 'flags': "disabled" - }); - - // Statusbar - this.editorStatusCommand = new Command({}, { - 'title': "Line 1, Column 1", - 'type': "label" - }); - this.tab.statusbar.add(this.editorStatusCommand); - this.tab.statusbar.add(this.collaboratorsMenu); - this.tab.statusbar.add(syntaxMenu); - - // Tab menu - this.tab.menu.menuSection([ - { - 'type': "action", - 'title': "Save", - 'shortcuts': [ - "mod+s" - ], - 'bindKeyboard': false, - 'action': function() { - that.sync.save(); - } - }, - { - 'type': "action", - 'title': "Run File", - 'shortcuts': [ - "mod+r" - ], - 'flags': this.model.isNewfile() ? "disabled": "", - 'bindKeyboard': false, - 'action': function() { - that.model.run(); - } - } - ]).menuSection([ - this.collaborationToggle, - syntaxMenu - ]).menuSection([ - { - 'title': "Convert Indentation to Spaces", - 'action': function() { - aceWhitespace.convertIndentation(that.editor.session, " ", editorSettings.user.get("tabsize", 4)); - } - }, - { - 'title': "Convert Indentation to Tabs", - 'action': function() { - aceWhitespace.convertIndentation(that.editor.session, "\t", 1); - } - }, - { - 'title':"Strip Whitespaces", - 'action': function() { - that.stripspaces(); - } - } - ]).menuSection([ - this.collaboratorsMenu - ]).menuSection([{ - 'type': "action", - 'title': "Settings", - 'offline': false, - 'action': function() { - settings.open("editor"); - } - }]); - - // Create sync - this.sync = new FileSync(); - this.sync.on("update:env", function(options) { - if (options.reset) { - this._op_set = true; - this.editor.setValue(""); - this._op_set = false; - } - this.collaborationToggle.toggleFlag("active", options.sync); - this.collaboratorsMenu.toggleFlag("disabled", !options.sync); - }, this); - - // Create base ace editor instance and configure it - this.$editor = $("
", { - 'class': "editor-ace" - }); - this.editor = ace.edit(this.$editor.get(0)); - var $doc = this.editor.session.doc; - - // Set base options - this.editor.session.setUseWorker(true); - this.editor.setOptions({ - enableBasicAutocompletion: true, - enableSnippets: true - }); - - // Force unix newline mode (for cursor position calcul) - $doc.setNewLineMode("unix"); - this.setOptions(); - - // Debug and Breakpoints - this.breakpoints = new Breakpoints({ - editor: this - }); - - // Read-only when debugger is active - this.listenTo(debugManager, "state", function(state) { - this.editor.setReadOnly(state); - }); - this.editor.setReadOnly(debugManager.isActive()); - - // Show active debug line - this.listenTo(debugManager, "position", this.updateDebugLine); - this.updateDebugLine(); - - // Bind settings changement - var update = function() { - var ops = _.extend({}, { - "mode": this.options.mode, - "readonly": this.options.readonly - }); - this.setOptions(ops); - }; - editorSettings.user.change(update, this); - user.settings("themes").change(update, this); - - // Bind editor changement -> sync - this.editor.getSession().selection.on('changeSelection', function(){ - var selection = that.editor.getSelectionRange(); - that.sync.updateUserSelection(selection.start.column, selection.start.row, selection.end.column, selection.end.row); - }); - this.editor.getSession().selection.on('changeCursor', function(){ - var cursor = that.editor.getSession().getSelection().getCursor(); - that.sync.updateUserCursor(cursor.column, cursor.row); - that.editorStatusCommand.set("title", "Line "+(cursor.row+1)+", Column "+(cursor.column+1)); - }); - this.editor.getSession().on("changeMode", function() { - jshint.applySettings(that.editor); - }); - - - // Clear command on Windows/ChromeOS Ctrl-Shift-P - this.editor.commands.addCommands([{ - name: "commandpalette", - bindKey: { - win: "Ctrl-Shift-P", - mac: "Command-Shift-P" - }, - exec: function(editor, line) { - return false; - }, - readOnly: true - }]); - - // Send change - $doc.on('change', function(d) { - if (that._op_set) return; - that.sync.updateContent(that.editor.session.getValue()); - }); - - // Bind sync -> editor - this.sync.on("file:mode", function(mode) { - this.setMode(mode) - }, this); - this.sync.on("content", function(content, oldcontent, patches) { - var selection, cursor_lead, cursor_anchor, scroll_y, operations; - - // if resync patches is null - patches = patches || []; - - // Calcul operaitons from patch - operations = this.sync.patchesToOps(patches); - - // Do some operations on selection to preserve selection - selection = this.editor.getSession().getSelection(); - - scroll_y = this.editor.getSession().getScrollTop(); - - cursor_lead = selection.getSelectionLead(); - cursor_lead = this.sync.cursorApplyOps({ - x: cursor_lead.column, - y: cursor_lead.row - }, operations, oldcontent); - - cursor_anchor = selection.getSelectionAnchor(); - cursor_anchor = this.sync.cursorApplyOps({ - x: cursor_anchor.column, - y: cursor_anchor.row - }, operations, oldcontent); - - // Set editor content - this._op_set = true; - - // Apply ace delta all in once - $doc.applyDeltas( - _.map(operations, function(op) { - return { - action: op.type+"Text", - range: { - start: that.posFromIndex(op.index), - end: that.posFromIndex(op.index + op.content.length) - }, - text: op.content - } - }) - ); - - // Check document content is as expected - if ($doc.getValue() != content) { - logging.error("Invalid operation ", content, $doc.getValue()); - $doc.setValue(content); - this.sync.sendSync(); - } - this._op_set = false; - - // Move cursors - this.editor.getSession().setScrollTop(scroll_y); - - cursor_anchor = this.sync.cursorPosByindex(cursor_anchor, content); - this.editor.getSession().getSelection().setSelectionAnchor(cursor_anchor.y, cursor_anchor.x); - - cursor_lead = this.sync.cursorPosByindex(cursor_lead, content); - this.editor.getSession().getSelection().selectTo(cursor_lead.y, cursor_lead.x); - }, this); - - // Participant cursor moves - this.sync.on("cursor:move", function(cId, c) { - var name, range = new aceRange.Range(c.y, c.x, c.y, c.x+1); - - // Remove old cursor - if (this.markersC[cId]) this.editor.getSession().removeMarker(this.markersC[cId]); - - // Calcul name - name = cId - var participant = collaborators.getById(cId); - if (participant) name = participant.get("name"); - - // Add new cursor - this.markersC[cId] = this.editor.getSession().addMarker(range, "marker-cursor marker-"+c.color.replace("#", ""), function(html, range, left, top, config){ - html.push("
" - + "
 "+name+" 
" - + "
 
"); - }, true); - }, this); - - // Participant selection - this.sync.on("selection:move", function(cId, c) { - var range = new aceRange.Range(c.start.y, c.start.x, c.end.y, c.end.x); - if (this.markersS[cId]) this.editor.getSession().removeMarker(this.markersS[cId]); - this.markersS[cId] = this.editor.getSession().addMarker(range, "marker-selection marker-"+c.color.replace("#", ""), "line", false); - }, this); - - // Remove a cursor/selection - this.sync.on("cursor:remove selection:remove", function(cId) { - if (this.markersC[cId]) this.editor.getSession().removeMarker(this.markersC[cId]); - if (this.markersS[cId]) this.editor.getSession().removeMarker(this.markersS[cId]); - delete this.markersC[cId]; - delete this.markersS[cId] - }, this); - - // Participants list change - this.sync.on("participants", function() { - this.collaboratorsMenu.set("label", _.size(this.sync.participants)); - this.collaboratorsMenu.menu.reset(_.map(this.sync.participants, function(participant) { - return { - 'type': "action", - 'title': participant.user.get("name"), - 'action': function() { - that.editor.getSession().getSelection().setSelectionAnchor(participant.cursor.y, participant.cursor.x); - that.editor.getSession().getSelection().selectTo(participant.cursor.y, participant.cursor.x); - that.editor.focus(); - } - } - })); - }, this); - - // Parent tab - this.tab.on("tab:layout", function() { - this.editor.resize(); - this.editor.renderer.updateFull(); - }, this); - this.tab.on("tab:state", function(state) { - if (state) this.focus(); - }, this); - this.tab.on("tab:close", function() { - // Clear breakpoints - this.model.clearBreakpoints(); - - // Finish sync - this.sync.close(); - - // Destroy the editor - this.editor.destroy(); - - // Destroy events and instance - this.off(); - this.stopListening(); - }, this); - - // Bind editor sync state changements - this.sync.on("sync:state", function(state) { - this.editor.setReadOnly(!state); - if (!state) { - this.tab.setTabState("warning", true); - } else { - this.tab.setTabState("warning", false); - } - }, this); - this.sync.on("mode", function(mode) { - this.tab.setTabState("sync", mode == this.sync.modes.SYNC); - }, this); - this.sync.on("close", function(mode) { - this.tab.closeTab(); - }, this); - this.sync.on("error", function(err) { - alerts.show("Error: "+(err.message || err), 3000); - }, this); - - this.sync.on("sync:modified", function(state) { - this.tab.setTabState("modified", state); - }, this); - - this.sync.on("sync:loading", function(state) { - this.tab.setTabState("loading", state); - }, this); - - this.sync.once("content", function() { - this.adaptOptions(); - }, this); - - // Define file for code editor - this.sync.setFile(this.model, { - 'sync': editorSettings.user.get("autocollaboration") ? collaborators.size() > 1 : false - }); - - // Options chnagements - this.on("file:options", this.adaptOptions, this); - - this.focus(); - - var $input = this.editor.textInput.getElement(); - var handleKeyEvent = function(e) { - if (!e.altKey && !e.ctrlKey && !e.metaKey) return; - keyboard.enableKeyEvent(e); - }; - $input.addEventListener('keypress', handleKeyEvent, false); - $input.addEventListener('keydown', handleKeyEvent, false); - $input.addEventListener('keyup', handleKeyEvent, false); - }, - - // Finish rendering - finish: function() { - this.$editor.appendTo(this.$(".editor-inner")); - this.editor.resize(); - this.editor.renderer.updateFull(); - - return FileEditorView.__super__.finish.apply(this, arguments); - }, - - // Focus editor - focus: function() { - this.editor.resize(); - this.editor.renderer.updateFull(); - this.editor.focus(); - return this; - }, - - // Define editor options - setOptions: function(opts) { - var that = this; - this.options = _.defaults(opts || {}, editorSettings.user.all({}), { - mode: "text", - fontsize: "12", - printmargincolumn: 80, - showprintmargin: false, - showinvisibles: false, - highlightactiveline: false, - wraplimitrange: 80, - enablesoftwrap: false, - keyboard: "textinput", - enablesofttabs: true, - tabsize: 4 - }); - - // Ste mode - this.setMode(this.options.mode); - - // Det keyboard mode - ace.config.loadModule(["keybinding", "ace/keyboard/"+this.options.keyboard], function(binding) { - if (binding && binding.handler) that.editor.setKeyboardHandler(binding.handler); - }); - - this.editor.setTheme(themes.current().editor.theme || aceDefaultTheme); - this.$editor.css("font-size", this.options.fontsize+"px"); - this.editor.setPrintMarginColumn(this.options.printmargincolumn); - this.editor.setShowPrintMargin(this.options.showprintmargin); - this.editor.setShowInvisibles(this.options.showinvisibles); - this.editor.setHighlightActiveLine(this.options.highlightactiveline); - this.editor.getSession().setUseWrapMode(this.options.enablesoftwrap); - this.editor.getSession().setWrapLimitRange(this.options.wraplimitrange, this.options.wraplimitrange); - this.editor.getSession().setUseSoftTabs(this.options.enablesofttabs); - this.editor.getSession().setTabSize(this.options.tabsize); - return this; - }, - - // Define mdoe option - setMode: function(lang) { - this.options.mode = lang; - this.editor.getSession().setMode("ace/mode/"+lang); - }, - - // Get position (row, column) from index in file - posFromIndex: function(index) { - var row, lines; - lines = this.editor.session.doc.getAllLines(); - for (row = 0; row < lines.length; row++) { - var line = lines[row]; - if (index <= (line.length)) break; - index = index - (line.length + 1); - } - - return { - 'row': row, - 'column': index - }; - }, - - // (action) Save file - saveFile: function(e) { - if (e) e.preventDefault(); - - if (editorSettings.user.get("stripspaces")) { - this.stripspaces(); - } - - this.sync.save(); - }, - - stripspaces: function(e) { - if (e) e.preventDefault(); - - // strip all whitespaces from the current document - var doc = this.editor.session.doc; - var lines = doc.getAllLines(); - - for (var i = 0; i < lines.length; ++i) { - var index = lines[i].search(/\s+$/); - if (index !== -1 && index != 0) - doc.removeInLine(i, index, lines[i].length); - } - }, - - // (action) Run this file - runFile: function(e) { - if (e) e.preventDefault(); - this.model.run(); - }, - - // (action) Open search box - searchInFile: function(e) { - if (e) e.preventDefault(); - this.editor.execCommand("find"); - }, - - // Show active line in debug - updateDebugLine: function() { - var position = debugManager.getPosition(); - - // Clear previous marker - if (this.debugMarker != null) { - this.editor.session.removeMarker(this.debugMarker); - this.debugMarker = null; - } - if (position && position.filename == this.model.path()) { - this.debugMarker = this.editor.session.addMarker(new aceRange.Range(parseInt(position.line) - 1, 0, parseInt(position.line) - 1, 2000), "marker-debug", "line", false); - console.log(this.debugMarker); - } - }, - - // Update current line according to options - adaptOptions: function() { - if (this.fileOptions.line) { - this.editor.gotoLine(this.fileOptions.line); - } else if (this.fileOptions.pattern) { - this.editor.find(this.fileOptions.pattern,{ - regExp: false, - backwards: false, - wrap: true - }); - } - } - }); - - return FileEditorView; -}); diff --git a/addons/cb.files.editor/package.json b/addons/cb.files.editor/package.json deleted file mode 100644 index afa3e10d..00000000 --- a/addons/cb.files.editor/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "cb.files.editor", - "version": "0.1.1", - "title": "Code Editor", - "description": "Code Editor with ACE.", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client", - "provides": [ - "ace" - ], - "resources": [ - "ace/**" - ] - }, - "scripts": { - "postinstall": "./download_ace.sh && ./build.sh" - }, - "engines": { - "codebox": ">=0.7.0" - } -} diff --git a/addons/cb.files.editor/stylesheets/file.less b/addons/cb.files.editor/stylesheets/file.less deleted file mode 100644 index 528ada77..00000000 --- a/addons/cb.files.editor/stylesheets/file.less +++ /dev/null @@ -1,114 +0,0 @@ -.mixin-cursor-color(@color) { - @pseudo-selector: ~".marker-@{color}"; - @{pseudo-selector} { - &.marker-selection { - background: ~"#@{color}"; - } - } -} - -.addon-files-aceeditor { - .file-participants { - a { - position: relative; - overflow: hidden; - padding: 6px 10px; - border-left: 6px solid #eee; - } - } - - .editor-inner { - .editor-ace { - -webkit-font-smoothing: subpixel-antialiased; - font-smoothing: subpixel-antialiased; - - position: absolute !important; - top: 0px; - bottom: 0px; - left: 0px; - right: 0px; - border-radius: 0px; - padding: 0px; - - .marker-debug { - position: absolute; - background: #5e9ef3; - opacity: .5; - width: 100% !important; - } - - .marker-cursor { - position: absolute; - border-left: 2px solid red; - opacity: 1; - } - - .marker-selection { - position: absolute; - background: red; - opacity: 0.2; - } - .mixin-cursor-color("1abc9c"); - .mixin-cursor-color("9b59b6"); - .mixin-cursor-color("e67e22"); - .mixin-cursor-color("16a085"); - .mixin-cursor-color("c0392b"); - .mixin-cursor-color("2980b9"); - .mixin-cursor-color("f39c12"); - .mixin-cursor-color("8e44ad"); - - .marker-cursor { - position: absolute; - z-index: 5; - border-left: 2px solid #0ff; - margin-left: -1px; - right: 5px; - text-align: right; - color: #ff0; - border-bottom: 1px dotted rgba(0,255,255,0.30); - } - .marker-cursor-nametag { - position: absolute; - bottom: -1px; - right: 0px; - text-align: right; - color: #fff; - background: #0ff; - padding: 0px; - padding-left: 3px; - padding-right: 3px; - opacity: 1; - font-family: Arial, sans-serif; - font-weight: 600; - pointer-events: auto; - cursor: help; - } - .marker-cursor-nametag-flag { - position: absolute; - bottom: 0px; - left: -6px; - width: 0px; - height: 0px; - border: 3px solid rgba(0,255,255,0.00); - border-right: 3px solid #0ff; - border-bottom: 3px solid #0ff; - } - - .ace_gutter-cell.ace_breakpoint { - position: relative; - - &:before { - content: " "; - width: 10px; - height: 10px; - border-radius: 16px; - border: 2px solid #fff; - position: absolute; - left: 4px; - background: #5E9EF3; - top: 3px; - } - } - } - } -} diff --git a/addons/cb.files.editor/templates/file.html b/addons/cb.files.editor/templates/file.html deleted file mode 100644 index cbb2e425..00000000 --- a/addons/cb.files.editor/templates/file.html +++ /dev/null @@ -1,3 +0,0 @@ -
-
-
\ No newline at end of file diff --git a/addons/cb.files.editor/theme/textmate.js b/addons/cb.files.editor/theme/textmate.js deleted file mode 100644 index 1f0fa775..00000000 --- a/addons/cb.files.editor/theme/textmate.js +++ /dev/null @@ -1,10 +0,0 @@ -define([ - "less!theme/textmate.less" -], function(cssContent) { - - return { - 'isDark': false, - 'cssClass': "ace-tm", - 'cssText': cssContent - } -}); \ No newline at end of file diff --git a/addons/cb.files.editor/theme/textmate.less b/addons/cb.files.editor/theme/textmate.less deleted file mode 100644 index 269f85cf..00000000 --- a/addons/cb.files.editor/theme/textmate.less +++ /dev/null @@ -1,182 +0,0 @@ - - -.ace_editor { - /* Search dialog */ - .ace_search, .ace_search.right { - right: 0px; - left: 0px; - max-width: none; - bottom: 0px; - top: auto; - border: 1px solid; - border-radius: 0px; - padding: 0px; - box-shadow: 2px 3px 5px rgba(0,0,0,.2); - - font-smoothing: subpixel-antialiased; - -webkit-font-smoothing: subpixel-antialiased; - - .ace_searchbtn_close { - margin: 9px 5px 0px 5px; - } - - .ace_search_field { - } - - .ace_search_form, .ace_replace_form { - border-radius: 0px; - margin: 4px; - } - - .ace_search_options { - text-align: left; - display: inline-block; - float: right; - margin: 0px; - padding: 4px; - height: 24px; - } - - .ace_button { - border-radius: 0px; - padding: 2px 4px; - margin: 0 3px 0 0; - display: inline-block; - } - - .ace_searchbtn, .ace_replacebtn{ - padding: 0px 5px; - border-radius: 0px; - } - } - - &.ace-tm { - background-color: #FFFFFF; - color: #4D4D4C; - - .ace_gutter { - background: transparent; - color: #4D4D4C - } - - .ace_print-margin { - width: 1px; - background: #f6f6f6 - } - - .ace_cursor { - color: #AEAFAD - } - - .ace_marker-layer .ace_selection { - background: #eaeaea; - } - - &.ace_multiselect .ace_selection.ace_start { - box-shadow: 0 0 3px 0px #FFFFFF; - border-radius: 2px - } - - .ace_marker-layer .ace_step { - background: rgb(255, 255, 0) - } - - .ace_marker-layer .ace_bracket { - margin: -1px 0 0 -1px; - border: 1px solid #D1D1D1 - } - - .ace_marker-layer .ace_active-line { - background: #EFEFEF - } - - .ace_gutter-active-line { - background-color : transparent; - } - - .ace_marker-layer .ace_selected-word { - border: 1px solid #D6D6D6 - } - - .ace_invisible { - color: #D1D1D1 - } - - .ace_keyword, - .ace_meta, - .ace_storage, - .ace_storage.ace_type, - .ace_support.ace_type { - color: #8959A8 - } - - .ace_keyword.ace_operator { - color: #3E999F - } - - .ace_constant.ace_character, - .ace_constant.ace_language, - .ace_constant.ace_numeric, - .ace_keyword.ace_other.ace_unit, - .ace_support.ace_constant, - .ace_variable.ace_parameter { - color: #F5871F - } - - .ace_constant.ace_other { - color: #666969 - } - - .ace_invalid { - color: #FFFFFF; - background-color: #C82829 - } - - .ace_invalid.ace_deprecated { - color: #FFFFFF; - background-color: #8959A8 - } - - .ace_fold { - background-color: #4271AE; - border-color: #4D4D4C - } - - .ace_entity.ace_name.ace_function, - .ace_support.ace_function, - .ace_variable { - color: #4271AE - } - - .ace_support.ace_class, - .ace_support.ace_type { - color: #C99E00 - } - - .ace_heading, - .ace_string { - color: #718C00 - } - - .ace_entity.ace_name.ace_tag, - .ace_entity.ace_other.ace_attribute-name, - .ace_meta.ace_tag, - .ace_string.ace_regexp, - .ace_variable { - color: #C82829 - } - - .ace_comment { - color: #8E908C - } - - .ace_indent-guide { - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y - } - - .ace_search { - border-color: #cbcbcb; - background: #e5e5e5; - } - } -} \ No newline at end of file diff --git a/addons/cb.files.image/client.js b/addons/cb.files.image/client.js deleted file mode 100644 index 899274be..00000000 --- a/addons/cb.files.image/client.js +++ /dev/null @@ -1,19 +0,0 @@ -define([ - "views/image" -], function(FileImageView) { - var _ = codebox.require("hr/utils"); - var files = codebox.require("core/files"); - - var imageExts = [ - ".png", ".jpg", ".gif", ".tiff", ".jpeg", ".bmp", ".webp", ".svg" - ]; - - files.addHandler("imageviewer", { - name: "Image Viewer", - position: 1, - View: FileImageView, - valid: function(file) { - return (!file.isDirectory() && _.contains(imageExts, file.extension())); - } - }); -}); \ No newline at end of file diff --git a/addons/cb.files.image/package.json b/addons/cb.files.image/package.json deleted file mode 100644 index 5364b006..00000000 --- a/addons/cb.files.image/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.files.image", - "version": "0.0.1", - "title": "Image Viewer", - "description": "Images files viewer (png, jpeg, gif).", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} diff --git a/addons/cb.files.image/stylesheets/image.less b/addons/cb.files.image/stylesheets/image.less deleted file mode 100644 index 8e5abe6b..00000000 --- a/addons/cb.files.image/stylesheets/image.less +++ /dev/null @@ -1,5 +0,0 @@ -.addon-files-aceeditor { - .image { - - } -} \ No newline at end of file diff --git a/addons/cb.files.image/templates/image.html b/addons/cb.files.image/templates/image.html deleted file mode 100644 index 40e7dc5f..00000000 --- a/addons/cb.files.image/templates/image.html +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/addons/cb.files.image/views/image.js b/addons/cb.files.image/views/image.js deleted file mode 100644 index 9b0182ce..00000000 --- a/addons/cb.files.image/views/image.js +++ /dev/null @@ -1,19 +0,0 @@ -define([ - "text!templates/image.html", - "less!stylesheets/image.less" -], function(templateFile) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var Dialogs = codebox.require("utils/dialogs"); - var FilesBaseView = codebox.require("views/files/base"); - - var FileImageView = FilesBaseView.extend({ - className: "addon-files-imageviewer", - templateLoader: "text", - template: templateFile, - events: {} - }); - - return FileImageView; -}); \ No newline at end of file diff --git a/addons/cb.files.preview/client.js b/addons/cb.files.preview/client.js deleted file mode 100644 index d6c621ba..00000000 --- a/addons/cb.files.preview/client.js +++ /dev/null @@ -1,35 +0,0 @@ -define([ - "views/preview_html", - "views/preview_markdown" -], function(PreviewHtml, PreviewMarkdown) { - var _ = codebox.require("hr/utils"); - var files = codebox.require("core/files"); - - var htmlExts = [ - ".html", ".htm" - ]; - - files.addHandler("preview", { - name: "HTML Preview", - icon: "eye", - position: 10, - View: PreviewHtml, - valid: function(file) { - return (!file.isDirectory() && _.contains(htmlExts, file.extension())); - } - }); - - var markdownExts = [ - ".md", ".markdown", ".txt" - ]; - - files.addHandler("preview-markdown", { - name: "Markdown Preview", - icon: "eye", - position: 10, - View: PreviewMarkdown, - valid: function(file) { - return (!file.isDirectory() && _.contains(markdownExts, file.extension())); - } - }); -}); \ No newline at end of file diff --git a/addons/cb.files.preview/package.json b/addons/cb.files.preview/package.json deleted file mode 100644 index a9f506a6..00000000 --- a/addons/cb.files.preview/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "cb.files.preview", - "version": "0.0.1", - "title": "HTML / Markdown Preview", - "description": "Adds option to preview files in a new tab.", - "homepage": "https://github.com/invokr/codebox", - "license": "Apache", - "author": { - "name": "Robin Dietrich", - "email": "me@invokr.org", - "url": "https://github.com/invokr" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - }, - "dependencies": { - "markdown": "0.5.0" - } -} diff --git a/addons/cb.files.preview/settings.js b/addons/cb.files.preview/settings.js deleted file mode 100644 index d1b4a1fa..00000000 --- a/addons/cb.files.preview/settings.js +++ /dev/null @@ -1,17 +0,0 @@ -define([], function() { - var settings = codebox.require("core/settings"); - - return settings.add({ - 'namespace': "preview", - 'title': "Preview", - 'defaults': { - 'refresh': true - }, - 'fields': { - 'refresh': { - 'label': "Reload on Save", - 'type': "checkbox" - } - } - }); -}); \ No newline at end of file diff --git a/addons/cb.files.preview/stylesheets/preview.less b/addons/cb.files.preview/stylesheets/preview.less deleted file mode 100644 index bc878aa7..00000000 --- a/addons/cb.files.preview/stylesheets/preview.less +++ /dev/null @@ -1,19 +0,0 @@ -.addon-files-previewviewer { - height: 100%; - - iframe { - border: 0px; - width: 100%; - height: 100%; - background-color: #fff; - } - - .markdown { - border: 0px; - width: 100%; - height: 100%; - background-color: #fff; - margin-top: 1px; - padding: 3px; - } -} \ No newline at end of file diff --git a/addons/cb.files.preview/templates/preview_html.html b/addons/cb.files.preview/templates/preview_html.html deleted file mode 100644 index bcc3b8c9..00000000 --- a/addons/cb.files.preview/templates/preview_html.html +++ /dev/null @@ -1,3 +0,0 @@ -
- -
\ No newline at end of file diff --git a/addons/cb.files.preview/templates/preview_markdown.html b/addons/cb.files.preview/templates/preview_markdown.html deleted file mode 100644 index 6595a5bb..00000000 --- a/addons/cb.files.preview/templates/preview_markdown.html +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/addons/cb.files.preview/views/preview_html.js b/addons/cb.files.preview/views/preview_html.js deleted file mode 100644 index 9fc20ef9..00000000 --- a/addons/cb.files.preview/views/preview_html.js +++ /dev/null @@ -1,52 +0,0 @@ -define([ - "settings", - "text!templates/preview_html.html", - "less!stylesheets/preview.less" -], function(settings, templateFile) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var box = codebox.require("core/box"); - var FilesTabView = codebox.require("views/files/tab"); - - var PreviewView = FilesTabView.extend({ - className: "addon-files-previewviewer", - templateLoader: "text", - template: templateFile, - events: {}, - - initialize: function() { - PreviewView.__super__.initialize.apply(this, arguments); - var that = this; - - // add refresh menu option - this.tab.menu.menuSection([ - { - 'type': "action", - 'title': "Refresh", - 'shortcuts': [ - "mod+r" - ], - 'bindKeyboard': true, - 'action': function() { - that.refresh(); - } - } - ]); - - // bind save event - box.on("box:watch:change:update", function() { - if (settings.user.get("refresh")) { - that.refresh(); - } - }, this); - - return this; - }, - - refresh: function() { - $(this.$el).find("iframe").attr('src', function ( i, val ) { return val; }); - } - }); - - return PreviewView; -}); diff --git a/addons/cb.files.preview/views/preview_markdown.js b/addons/cb.files.preview/views/preview_markdown.js deleted file mode 100644 index 7fe530f5..00000000 --- a/addons/cb.files.preview/views/preview_markdown.js +++ /dev/null @@ -1,58 +0,0 @@ -define([ - "settings", - "node_modules/markdown/lib/markdown", - "text!templates/preview_markdown.html", - "less!stylesheets/preview.less" -], function(settings, _markdown, templateFile) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var box = codebox.require("core/box"); - var FilesTabView = codebox.require("views/files/tab"); - - var markdown = window.markdown; - - var MarkdownView = FilesTabView.extend({ - className: "addon-files-previewviewer", - templateLoader: "text", - template: templateFile, - events: {}, - - initialize: function() { - MarkdownView.__super__.initialize.apply(this, arguments); - var that = this; - - // add refresh menu option - this.tab.menu.menuSection([ - { - 'type': "action", - 'title': "Refresh", - 'shortcuts': [ - "mod+r" - ], - 'bindKeyboard': true, - 'action': function() { - that.refresh(); - } - } - ]); - - this.model.on("file:change:update", function() { - if (settings.user.get("refresh")) { - that.refresh(); - } - }, this); - - this.refresh(); - return this; - }, - - refresh: function() { - var that = this; - this.model.download().then(function (content) { - that.$el.html("
"+markdown.toHTML(content)+"
"); - }); - } - }); - - return MarkdownView; -}); diff --git a/addons/cb.git/client.js b/addons/cb.git/client.js deleted file mode 100644 index 15277921..00000000 --- a/addons/cb.git/client.js +++ /dev/null @@ -1,251 +0,0 @@ -define(["views/dialog"], function(GitDialog) { - var Q = codebox.require("hr/promise"); - var commands = codebox.require("core/commands/toolbar"); - var app = codebox.require("core/app"); - var box = codebox.require("core/box"); - var dialogs = codebox.require("utils/dialogs"); - var menu = codebox.require("core/commands/menu"); - var box = codebox.require("core/box"); - var Command = codebox.require("models/command"); - var rpc = codebox.require("core/backends/rpc"); - var operations = codebox.require("core/operations"); - - // Check git status - var updateStatus = function() { - return rpc.execute("git/status") - .then(function() { - updateMenu(true); - return updateBranchesMenu(false); - }, function(err) { - updateMenu(false); - }) - }; - - // Branches menu - var branchesMenu = Command.register({ - 'title': "Switch To Branch", - 'type': "menu", - 'offline': false - }); - var updateBranchesMenu = function(doUpdateStatus) { - return rpc.execute("git/branches") - .then(function(branches) { - branchesMenu.menu.reset(_.map(branches, function(branch) { - return { - 'title': branch.name, - 'flags': branch.active ? "active" : "", - 'action': function() { - var ref = branch.name; - return operations.start("git.checkout", function(op) { - return rpc.execute("git/checkout", { - 'ref': ref - }) - }, { - title: "Checkout '"+ref+"'" - }) - .then(updateBranchesMenu); - } - } - })); - }, function(err) { - if (doUpdateStatus !== false) updateStatus(); - return Q.reject(err); - }); - }; - - // Handle http auth - var handleHttpAuth = function(method) { - return Q(method()) - .fail(function(err) { - if (err.code == 401) { - // Fields for https auth - var fields = { - username: { - type: "text", - label: "Username" - }, - password: { - type: "password", - label: "Password" - } - }; - - // Passphrase for ssh - if (err.message.toLowerCase().indexOf("authentication") < 0) { - fields = { - passphrase: { - type: "text", - label: "Passphrase" - } - }; - } - - return dialogs.fields("Need authentication:", fields) - .then(method); - } else { - return Q.reject(err); - } - }) - }; - - // Add menu - var gitMenu = menu.register("git", { - title: "Repository", - offline: false - }); - - var updateMenu = function(state) { - // Clear menu - gitMenu.clearMenu(); - - // Invalid repository - if (!state) { - gitMenu.menuSection([ - { - 'title': "No GIT Repository detected", - 'type': "label", - 'icons': { - 'menu': "warning", - } - }, - { - 'title': "Initialize Local Repository", - 'offline': false, - 'action': function() { - return operations.start("git.init", function(op) { - return rpc.execute("git/init") - }, { - title: "Initializing GIT repository" - }); - } - }, - { - 'title': "Clone Remote Repository", - 'offline': false, - 'action': function() { - return operations.start("git.clone", function(op) { - return dialogs.prompt("Clone Remote Repository", "Remote repository URI:") - .then(function(url) { - if (!url) return; - return handleHttpAuth(function(creds) { - return rpc.execute("git/clone", { - 'url': url, - 'auth': creds || {} - }); - }); - }); - }, { - title: "Cloning GIT repository" - }); - } - } - ]); - } else { - gitMenu.menuSection([ - { - 'title': "Commit", - 'shortcuts': ["mod+shift+C"], - 'offline': false, - 'action': function() { - dialogs.open(GitDialog); - } - } - ]).menuSection([ - { - 'title': "Synchronize", - 'shortcuts': ["mod+S"], - 'offline': false, - 'action': function() { - return operations.start("git.sync", function(op) { - return handleHttpAuth(function(creds) { - return rpc.execute("git/sync", { - 'auth': creds || {} - }); - }); - }, { - title: "Pushing & Pulling" - }); - } - }, - { - 'title': "Push", - 'shortcuts': ["mod+P"], - 'offline': false, - 'action': function() { - return operations.start("git.push", function(op) { - return handleHttpAuth(function(creds) { - return rpc.execute("git/push", { - 'auth': creds || {} - }); - }); - }, { - title: "Pushing" - }); - } - }, - { - 'title': "Pull", - 'shortcuts': ["shift+mod+P"], - 'offline': false, - 'action': function() { - return operations.start("git.pull", function(op) { - return handleHttpAuth(function(creds) { - return rpc.execute("git/pull", { - 'auth': creds || {} - }); - }); - }, { - title: "Pulling" - }); - } - } - ]).menuSection([ - branchesMenu, - { - 'title': "Refresh branches", - 'offline': false, - 'action': updateBranchesMenu, - } - ]).menuSection([ - { - 'title': "Create a branch", - 'offline': false, - 'action': function() { - dialogs.prompt("Create a branch", "Enter the name for the new branch:").then(function(name) { - if (!name) return; - operations.start("git.branch.create", function(op) { - return rpc.execute("git/branch/create", { - 'name': name - }) - }, { - title: "Creating branch '"+name+"'" - }); - }); - } - }, - { - 'title': "Delete a branch", - 'offline': false, - 'action': function() { - dialogs.prompt("Delete a branch", "Enter the name of the branch you want to delete:").then(function(name) { - if (!name) return; - operations.start("git.branch.delete", function(op) { - return rpc.execute("git/branch/delete", { - 'name': name - }) - }, { - title: "Deleting branch '"+name+"'" - }).then(updateBranchesMenu); - }); - } - } - ]); - } - }; - - box.on("box:git", function() { - updateStatus(); - }); - updateStatus(); -}); - diff --git a/addons/cb.git/node/main.js b/addons/cb.git/node/main.js deleted file mode 100644 index f23406be..00000000 --- a/addons/cb.git/node/main.js +++ /dev/null @@ -1,29 +0,0 @@ -// Requires -var _ = require('lodash'); -var Gittle = require('gittle'); -var GitRPCService = require('./service').GitRPCService; - - -function setup(options, imports, register) { - // Import - var rpc = imports.rpc; - var events = imports.events; - var workspace = imports.workspace; - - // Service - var service = new GitRPCService(workspace, events); - - // Register RPC - rpc.register('git', service); - - // Register - register(null, { - "git": { - repo: service.repo, - }, - "git_rpc": service - }); -} - -// Exports -module.exports = setup; diff --git a/addons/cb.git/node/service.js b/addons/cb.git/node/service.js deleted file mode 100644 index 0404ae7d..00000000 --- a/addons/cb.git/node/service.js +++ /dev/null @@ -1,150 +0,0 @@ -// Requires -var Q = require('q'); -var _ = require('lodash'); -var Gittle = require('gittle'); - -function GitRPCService(workspace, events) { - this.workspace = workspace; - this.events = events; - - this.repo = new Gittle(workspace.root); - - _.bindAll(this); -} - -GitRPCService.prototype.init = function(args, meta) { - var that = this; - return Gittle.init(this.workspace.root).then(function(repo) { - that.events.emit('git.init', { - userId: meta.user.userId - }); - - that.repo = repo; - return that.repo.status(); - }); -}; - -GitRPCService.prototype.clone = function(args, meta) { - var that = this; - if (!args.url) throw "Need an url for cloning a repository"; - return Gittle.clone(args.url, this.workspace.root, args.auth || {}).then(function(repo) { - that.events.emit('git.clone', { - userId: meta.user.userId, - url: args.url - }); - - that.repo = repo; - return that.repo.status(); - }); -}; - -GitRPCService.prototype.status = function() { - return this.repo.status(); -}; - -GitRPCService.prototype.sync = function(args, meta) { - var that = this; - return this.repo.sync(null, null, args.auth || {}) - .then(function() { - that.events.emit('git.sync', { - userId: meta.user.userId - }); - }); -}; - -GitRPCService.prototype.push = function(args, meta) { - var that = this; - return this.repo.push(null, null, args.auth || {}) - .then(function() { - that.events.emit('git.push', { - userId: meta.user.userId - }); - }); -}; - -GitRPCService.prototype.pull = function(args, meta) { - var that = this; - return this.repo.pull(null, null, args.auth || {}) - .then(function() { - that.events.emit('git.pull', { - userId: meta.user.userId - }); - }); -}; - -GitRPCService.prototype.commit = function(args, meta) { - var msg = args.message; - var files = args.files || []; - var name = meta.user.name; - var email = meta.user.email; - - if(!_.all([msg, files, name, email])) { - return Q.reject(new Error("Could not commit because arguments are missing and/or invalid")); - } - - var that = this; - return this.repo.commitWith(name, email, msg, files) - .then(function() { - that.events.emit('git.commit', { - userId: meta.user.userId, - - message: msg, - name: name, - email: email, - files: files - }); - }); -}; - -GitRPCService.prototype.commits = function(args) { - return this.repo.commits(args.ref, args.limit, args.skip); -}; - -GitRPCService.prototype.branches = function(args) { - var activeBranch, that = this; - - // Get current active branch - return this.repo.branch().then(function(branch) { - activeBranch = branch; - - // Get all local branches - return that.repo.branches(); - }).then(function(branches) { - return _.map(branches, function(branch) { - return { - 'name': branch.name, - 'active': branch.name == activeBranch.name - } - }); - }) -}; - -GitRPCService.prototype.branch_create = function(args) { - if (!args.name) return Q.reject(new Error("Need a name to create a branch")); - return this.repo.create_branch(args.name); -}; - -GitRPCService.prototype.checkout = function(args) { - if (!args.ref) return Q.reject(new Error("Need a referance (ref) to checkout")); - return this.repo.checkout(args.ref); -}; - -GitRPCService.prototype.branch_delete = function(args) { - if (!args.name) return Q.reject(new Error("Need a name to delete a branch")); - return this.repo.delete_branch(args.name); -}; - -GitRPCService.prototype.commits_pending = function() { - return this.repo.commits_pending(); -}; - -GitRPCService.prototype.diff = function(args) { - return this.repo.diff(args.new, args.old).then(function(diffs) { - return _.map(diffs, function(diff) { - return diff.normalize(); - }) - }); -}; - -// Exports -exports.GitRPCService = GitRPCService; diff --git a/addons/cb.git/package.json b/addons/cb.git/package.json deleted file mode 100644 index 0650cd0d..00000000 --- a/addons/cb.git/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "cb.git", - "version": "0.0.3", - "title": "GIT", - "description": "Integration of Git into your workspace.", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "main": "./node/main", - "plugin": { - "provides": [ - "git", - "git_rpc" - ], - "consumes": [ - "rpc", - "events", - "workspace" - ] - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.git/stylesheets/git.less b/addons/cb.git/stylesheets/git.less deleted file mode 100644 index 6ee1e81e..00000000 --- a/addons/cb.git/stylesheets/git.less +++ /dev/null @@ -1,64 +0,0 @@ -.addon-git-dialog { - .modal-body { - padding: 0px; - } - .modal-footer { - margin: 0px; - } - - .navbar { - margin: 0px; - } - - .git-changes { - .git-commit { - padding: 15px 10px; - margin: 0px; - background: #f8f8f8; - - textarea { - resize: none; - } - } - - .git-changes-files { - list-style: none; - margin: 0px; - padding: 0px; - - .file { - background: #fdfdfd; - box-shadow: 0px 1px 0px #fff inset; - border-top: 1px solid #ddd; - padding: 6px; - padding-left: 55px; - position: relative; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - - .file-type { - position: absolute; - display: block; - top: 0px; - left: 0px; - width: 45px; - bottom: 0px; - padding: 6px; - text-align: center; - color: #fff; - - &.type-M { - background: #3498db; - } - &.type-A { - background: #2ecc71; - } - &.type-D { - background: #e74c3c; - } - } - } - } - } -} \ No newline at end of file diff --git a/addons/cb.git/templates/dialog.html b/addons/cb.git/templates/dialog.html deleted file mode 100644 index 299a6aef..00000000 --- a/addons/cb.git/templates/dialog.html +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/addons/cb.git/views/dialog.js b/addons/cb.git/views/dialog.js deleted file mode 100644 index 139a7fa4..00000000 --- a/addons/cb.git/views/dialog.js +++ /dev/null @@ -1,75 +0,0 @@ -define([ - "text!templates/dialog.html", - "less!stylesheets/git.less" -], function(templateFile) { - var DialogView = codebox.require("views/dialogs/base"); - var box = codebox.require("core/box"); - var rpc = codebox.require("core/backends/rpc"); - var operations = codebox.require("core/operations"); - - var GitDialog = DialogView.extend({ - className: "addon-git-dialog modal fade", - templateLoader: "text", - template: templateFile, - events: _.extend({}, DialogView.prototype.events,{ - "submit form": "submit" - }), - - // Constructor - initialize: function(options) { - var that = this; - GitDialog.__super__.initialize.apply(this, arguments); - - that.git = null; - - rpc.execute("git/status").then(function(status) { - that.git = status; - that.render(); - }); - return this; - }, - - // Template Context - templateContext: function() { - return { - git: this.git - }; - }, - - // Render - render: function() { - if (!this.git) return this; - return GitDialog.__super__.render.apply(this, arguments); - }, - - // Finish rendering - finish: function() { - return GitDialog.__super__.finish.apply(this, arguments); - }, - - // Commit (and sync) - submit: function(e) { - if (e) e.preventDefault(); - - var that = this; - var sync = this.$(".git-commit .btn-git-sync").hasClass("active"); - var message = this.$(".git-commit textarea").val(); - - if (message.length == 0) { - return; - } - - operations.start("git.commit", function(op) { - return rpc.execute("git/commit", { - 'message': message - }); - }, { - title: "Commiting" - }).then(function() { - that.close(); - }) - } - }); - - return GitDialog; -}); \ No newline at end of file diff --git a/addons/cb.help/client.js b/addons/cb.help/client.js deleted file mode 100644 index 62cb0ae1..00000000 --- a/addons/cb.help/client.js +++ /dev/null @@ -1,80 +0,0 @@ -define([ - "text!welcome.md" -], function(welcomeText) { - var hr = codebox.require("hr/hr"); - var app = codebox.require("core/app"); - var menu = codebox.require("core/commands/menu"); - var files = codebox.require("core/files"); - var rpc = codebox.require("core/backends/rpc"); - var Command = codebox.require("models/command"); - - // Help url - var helpUrl = "http://help.codebox.io/"; - - // Command to open changelog - var commandChanges = Command.register("help.changes", { - 'category': "Help", - 'title': "Open Release Notes", - 'action': function(title) { - return rpc.execute("box/changes").then(function(changes) { - return files.openNew(title || "Release Notes", changes.content); - }); - } - }); - - // Command to open welcome - var commandWelcome = Command.register("help.welcome", { - 'category': "Help", - 'title': "Welcome", - 'action': function(title) { - return files.openNew(title || "Welcome.md", welcomeText); - } - }); - - - // Add menu - menu.register("help", { - title: "Help", - position: 100 - }).menuSection([ - commandChanges, - { - 'id': "help.documentation", - 'category': "Help", - 'title': "Documentation", - 'description': "Open Documentation", - 'shortcuts': ['?'], - 'offline': false, - 'action': function() { - window.open(helpUrl); - } - } - ]).menuSection([ - { - 'id': "help.feedback", - 'category': "Help", - 'title': "Submit Feedback", - 'offline': false, - 'action': function() { - window.open("https://github.com/FriendCode/codebox/issues"); - } - } - ]); - - // Open changes if version changes - app.once("ready", function() { - // Show release not if version increased - // If first time show welcome message - - var currentVersion = hr.configs.args.version; - var lastVersion = hr.Storage.get("codeboxVersion"); - - if (lastVersion == null) { - commandWelcome.run(); - } else if (currentVersion != lastVersion) { - commandChanges.run(); - } - hr.Storage.set("codeboxVersion", currentVersion); - }); -}); - diff --git a/addons/cb.help/package.json b/addons/cb.help/package.json deleted file mode 100644 index fe5d8e8d..00000000 --- a/addons/cb.help/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.help", - "version": "0.0.1", - "title": "Help", - "description": "Documentation for Codebox", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.help/welcome.md b/addons/cb.help/welcome.md deleted file mode 100644 index c4e4c9d0..00000000 --- a/addons/cb.help/welcome.md +++ /dev/null @@ -1,22 +0,0 @@ -# Welcome to Codebox! - -Here is what you need to know. - -1. This IDE is open source, you can contribute to it on [GitHub](https://github.com/FriendCode/codebox). - -2. If you only remember one thing make it `cmd-shift-P` (or `ctrl-shift-P` on Windows and Linux). This keystroke toggles - the command palette, which lists every command. - -3. We want your feedback! If you have anything positive or negative to say click - on the `Send Feedback` button at the bottom right of this window. - -4. Here is where you can get more help with Codebox - - * The [Codebox docs](http://help.codebox.io/) contain Guides on how to use the IDE. - * Post issues on [GitHub](https://github.com/FriendCode/codebox/issues). - -5. If you ever want to see this buffer again use the command palette - (`cmd-shift-P`) and search for `Welcome`. - -6. If you want to read ChangeLog, use the command palette - (`cmd-shift-P`) and search for `Release Notes`. \ No newline at end of file diff --git a/addons/cb.offline/client.js b/addons/cb.offline/client.js deleted file mode 100644 index 574295f7..00000000 --- a/addons/cb.offline/client.js +++ /dev/null @@ -1,80 +0,0 @@ -define([ - "settings", - "menus" -], function(settings, menus) { - var $ = codebox.require("hr/dom"); - var Q = codebox.require("hr/promise"); - var app = codebox.require("core/app"); - var box = codebox.require("core/box"); - var menu = codebox.require("core/commands/menu"); - var commands = codebox.require("core/commands/toolbar"); - var operations = codebox.require("core/operations"); - var hr = codebox.require("hr/hr"); - var Command = codebox.require("models/command"); - var localfs = codebox.require("core/localfs"); - - var _syncInterval = null; - - - // Run offline cache update operation - var op = operations.start("offline.update", null, { - 'title': "Updating", - 'icons': { - 'default': "fa-cog fa-spin", - }, - 'state': window.applicationCache.status == window.applicationCache.IDLE ? "idle" : "running", - 'progress': 0 - }); - - // Application manifest - $(window.applicationCache).bind('downloading progress', function(e) { - var progress = 0; - if (e && e.originalEvent && e.originalEvent.lengthComputable) { - progress = Math.round(100*e.originalEvent.loaded/e.originalEvent.total); - } - op.state("running"); - op.progress(progress); - }); - $(window.applicationCache).bind('checking', function(e) { - op.state("running"); - op.progress(0); - }); - $(window.applicationCache).bind('noupdate cached obsolete error', function(e) { - op.state("idle"); - }); - - - // Update settings - var updateSettings = function() { - var enabled = settings.user.get("enabled", true); - if (_syncInterval) clearInterval(_syncInterval); - - // Enable sync - localfs.enableSync(settings.user.get("enabled", true)); - - // Set ignored files - localfs.setIgnoredFiles(settings.user.get("syncIgnore", "").split("\n")); - - // Toggle menu - menus.sync.toggleFlag("hidden", !enabled); - - // Run sync every 10min - _syncInterval = setInterval(function() { - localfs.autoSync(); - }, settings.user.get("syncInterval", 10)*60*1000); - }; - - setTimeout(function() { - localfs.sync(); - }, 5*1000); - - // Run sync everytime there is a modification - box.on("box:watch", function() { - localfs.autoSync(); - }); - - // Change settings - settings.user.change(updateSettings); - updateSettings(); -}); - diff --git a/addons/cb.offline/menus.js b/addons/cb.offline/menus.js deleted file mode 100644 index eafdf3a4..00000000 --- a/addons/cb.offline/menus.js +++ /dev/null @@ -1,87 +0,0 @@ -define([], function() { - var box = codebox.require("core/box"); - var menu = codebox.require("core/commands/menu"); - var commands = codebox.require("core/commands/toolbar"); - var operations = codebox.require("core/operations"); - var hr = codebox.require("hr/hr"); - var Command = codebox.require("models/command"); - var localfs = codebox.require("core/localfs"); - var dialogs = codebox.require("utils/dialogs"); - - // Command to check connection - var checkConnection = commands.register("offline.check", { - 'category': "Offline", - 'title': "Check Connection", - 'offline': true, - 'icons': { - 'default': "bolt", - } - }, function() { - hr.Offline.check(); - }); - - // Changes list - var menuListChanges = new Command({}, { - 'title': "Changes", - 'type': "menu", - 'flags': "disabled" - }); - - // Menu Synchronize - var menuSync = menu.register("offline.synchronize", { - title: "Synchronize", - position: 95, - offline: false - }).menuSection([ - checkConnection - ]).menuSection([ - { - 'id': "offline.changes.calcul", - 'category': "Offline", - 'title': "Calcul Changes", - 'offline': false, - 'action': function() { - return localfs.sync(); - } - } - ]).menuSection([ - { - 'id': "offline.changes.reset", - 'category': "Offline", - 'title': "Reset All Changes", - 'offline': false, - 'action': function() { - return localfs.reset(); - } - }, - { - 'id': "offline.changes.apply", - 'category': "Offline", - 'title': "Apply All Changes", - 'offline': false, - 'action': function() { - var n = localfs.changes.size(); - if (n == 0) return; - - dialogs.confirm("Do you really want to apply "+n+" changes?").then(function(yes) { - if (!yes) return; - return localfs.changes.applyAll(); - }); - } - } - ]).menuSection([ - menuListChanges - ]); - - // Changes update - localfs.changes.on("add remove reset", function() { - menuListChanges.toggleFlag("disabled", localfs.changes.size() == 0); - menuListChanges.menu.reset(localfs.changes.map(function(change) { - return change.command(); - })); - }); - - return { - 'sync': menuSync - } -}); \ No newline at end of file diff --git a/addons/cb.offline/package.json b/addons/cb.offline/package.json deleted file mode 100644 index 5fbb6402..00000000 --- a/addons/cb.offline/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.offline", - "version": "0.0.1", - "title": "Help", - "description": "Menu for managing offline sync", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.offline/settings.js b/addons/cb.offline/settings.js deleted file mode 100644 index b77d222c..00000000 --- a/addons/cb.offline/settings.js +++ /dev/null @@ -1,30 +0,0 @@ -define([], function() { - var settings = codebox.require("core/settings"); - - // Add settings - return settings.add({ - 'namespace': "offline", - 'title': "Offline", - 'defaults': { - 'enabled': false, - 'syncInterval': 10 - }, - 'fields': { - 'enabled': { - 'label': 'Enable Files Synchronization', - 'type': "checkbox" - }, - 'syncInterval': { - 'label': "Synchronization (minutes)", - 'type': "number", - 'min': 1, - 'max': 1000, - 'step': 1 - }, - 'syncIgnore': { - 'label': "Ignored files (one by line)", - 'type': "textarea" - } - } - }); -}); \ No newline at end of file diff --git a/addons/cb.panel.files/client.js b/addons/cb.panel.files/client.js deleted file mode 100644 index 699a64b4..00000000 --- a/addons/cb.panel.files/client.js +++ /dev/null @@ -1,85 +0,0 @@ -define([ - "views/panel" -], function(PanelFilesView) { - var Command = codebox.require("models/command"); - var commands = codebox.require("core/commands/toolbar"); - var app = codebox.require("core/app"); - var panels = codebox.require("core/panels"); - var files = codebox.require("core/files"); - var menu = codebox.require("core/commands/menu"); - var box = codebox.require("core/box"); - - // Add files panels - var panel = panels.register("files", PanelFilesView, { - title: "Folders" - }); - - // Open files panel - panel.connectCommand(commands.register("files.tree.open", { - category: "Panels", - title: "Files", - description: "Open Files Panel", - icons: { - 'default': "folder-o", - }, - position: 2, - shortcuts: [ - "alt+f" - ] - })); - - // Recents files - var recentFiles = Command.register({ - 'type': "menu", - 'title': "Open Recent" - }); - files.recent.on("add remove reset", function() { - recentFiles.menu.reset(files.recent.map(function(file) { - var path = file.path(); - return { - 'title': file.get("name"), - 'action': function() { - files.open(path); - } - }; - }).reverse()); - }); - - - // Command new file - menu.getById("file").menuSection([ - { - 'id': "files.file.new", - 'category': "Files", - 'title': "New File", - 'shortcuts': ["alt+shift+n"], - 'action': function() { - files.openNew() - } - }, { - 'id': "files.folder.create", - 'category': "Files", - 'title': "New Folder", - 'shortcuts': ["alt+shift+f"], - 'action': function() { - box.root.actionMkdir(); - } - }, - recentFiles - ], { - position: 0 - }).menuSection([ - { - 'id': "workspace.save.zip", - 'category': "Files", - 'title': "Save Project As TAR.GZ", - 'offline': false, - 'action': function() { - window.open("/export/targz"); - } - } - ]); - - // Open panel - panel.open(); -}); \ No newline at end of file diff --git a/addons/cb.panel.files/package.json b/addons/cb.panel.files/package.json deleted file mode 100644 index 069fe5e0..00000000 --- a/addons/cb.panel.files/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.panel.files", - "version": "0.1.0", - "title": "Files Panel", - "description": "Files Tree Panel for exploring and managing the filesystem", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.panel.files/settings.js b/addons/cb.panel.files/settings.js deleted file mode 100644 index 95326ed3..00000000 --- a/addons/cb.panel.files/settings.js +++ /dev/null @@ -1,25 +0,0 @@ -define([], function() { - var $ = codebox.require("hr/dom"); - var settings = codebox.require("core/settings"); - - // Add settings - return settings.add({ - 'namespace': "files-panel", - 'title': "Files Explorer Panel", - 'defaults': { - 'openfiles': true, - 'hiddenfiles': true, - 'gitfolder': false - }, - 'fields': { - 'hiddenfiles': { - 'label': "Show Hidden Files", - 'type': "checkbox" - }, - 'gitfolder': { - 'label': "Show GIT Folder", - 'type': "checkbox" - } - } - }); -}); \ No newline at end of file diff --git a/addons/cb.panel.files/stylesheets/files.less b/addons/cb.panel.files/stylesheets/files.less deleted file mode 100644 index 288c2f67..00000000 --- a/addons/cb.panel.files/stylesheets/files.less +++ /dev/null @@ -1,97 +0,0 @@ -.cb-files-tree { - margin: 0px; - padding: 0px; - list-style: none; - - &.root { - - } - - .file-item { - cursor: default; - line-height: 24px; - font-size: 14px; - - &.hr-list-fiter-on { - display: none; - } - - >.files { - display: none; - } - - &.active, &.active:hover { - >.name { - background: rgba(0,0,0, 0.08); - color: inherit; - } - } - - &.disabled { - >.name { - color: #999; - } - } - - &.ui-context-menu { - >.name { - background: rgba(0, 0, 0, 0.15); - } - } - - >.name { - color: inherit; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - display: block; - z-index: 1; - position: relative; - - &:hover { - background: #5E9EF3; - color: #fff; - } - - >i { - width: 11px; - text-align: center; - - &.file-icon { - margin-right: 3px; - } - - &.invisibile { - color: transparent; - text-shadow: none; - } - } - >.fa-angle-right { - display: inline-block; - } - >.fa-angle-down { - display: none; - } - } - - &.type-directory { - >.name { - /*color: inherit;*/ - } - } - - &.open { - >.files { - display: block; - } - >.name { - >.fa-angle-right { - display: none; - } - >.fa-angle-down { - display: inline-block; - } - } - } - } -} \ No newline at end of file diff --git a/addons/cb.panel.files/stylesheets/panel.less b/addons/cb.panel.files/stylesheets/panel.less deleted file mode 100644 index 6091a148..00000000 --- a/addons/cb.panel.files/stylesheets/panel.less +++ /dev/null @@ -1,9 +0,0 @@ -.cb-panel-files { - position: absolute; - top: 0px; - bottom: 0px; - left: 0px; - width: 100%; - z-index: 10; - overflow-y: auto; -} \ No newline at end of file diff --git a/addons/cb.panel.files/templates/item.html b/addons/cb.panel.files/templates/item.html deleted file mode 100644 index 583ff42e..00000000 --- a/addons/cb.panel.files/templates/item.html +++ /dev/null @@ -1,14 +0,0 @@ - - <% if (file.isDirectory()) { %> - - - - <% } else { %> - - - <% } %> - <%- file.get("name") %> - -<% if (file.isDirectory()) { %> -
-<% } %> \ No newline at end of file diff --git a/addons/cb.panel.files/views/panel.js b/addons/cb.panel.files/views/panel.js deleted file mode 100644 index c4886193..00000000 --- a/addons/cb.panel.files/views/panel.js +++ /dev/null @@ -1,58 +0,0 @@ -define([ - "settings", - "views/tree", - "less!stylesheets/panel.less" -], function(panelSettings, FilesTreeView) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var box = codebox.require("core/box"); - var files = codebox.require("core/files"); - var search = codebox.require("core/search"); - var ContextMenu = codebox.require("utils/contextmenu"); - var PanelBaseView = codebox.require("views/panels/base"); - - var PanelFilesView = PanelBaseView.extend({ - className: "cb-panel-files", - - initialize: function() { - PanelFilesView.__super__.initialize.apply(this, arguments); - - this.tree = new FilesTreeView.Item({ - model: box.root - }, this); - this.tree.update(); - this.tree.select(); - - - var $rootTree = $("
    ", { - "class": "root-tree cb-files-tree" - }); - $rootTree.appendTo(this.$el); - this.tree.$el.appendTo($rootTree); - - // Offline - hr.Offline.on("state", function() { - this.update(); - }, this); - - // Settings update - panelSettings.user.change(function() { - this.update(); - }, this); - - this.on("tab:layout", function() { - //this.render(); - }, this); - - // Context menu - ContextMenu.add(this.$el, box.root.contextMenu()); - }, - - render: function() { - return this.ready(); - } - }); - - return PanelFilesView; -}); \ No newline at end of file diff --git a/addons/cb.panel.files/views/tree.js b/addons/cb.panel.files/views/tree.js deleted file mode 100644 index 5e782d4d..00000000 --- a/addons/cb.panel.files/views/tree.js +++ /dev/null @@ -1,168 +0,0 @@ -define([ - "settings", - "text!templates/item.html", - "less!stylesheets/files.less" -], function(panelSettings, templateFile) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var box = codebox.require("core/box"); - var ContextMenu = codebox.require("utils/contextmenu"); - var FilesBaseView = codebox.require("views/files/base"); - - // File item in the tree - var FilesTreeViewItem = FilesBaseView.extend({ - tagName: "li", - className: "file-item", - templateLoader: "text", - template: templateFile, - events: { - "click .name": "select", - "dblclick .name": "open" - }, - - // Constructor - initialize: function(options) { - FilesTreeViewItem.__super__.initialize.apply(this, arguments); - var that = this; - - // View for subfiles - this.subFiles = null; - this.paddingLeft = this.options.paddingLeft || 0; - - // Context menu - ContextMenu.add(this.$el, this.model.contextMenu()); - - box.on("file.active", function(path) { - this.$el.toggleClass("active", this.model.path() == path); - }, this); - - return this; - }, - - render: function() { - if (this.subFiles) this.subFiles.detach(); - return FilesTreeViewItem.__super__.render.apply(this, arguments); - }, - - // Finish rendering - finish: function() { - this.$el.toggleClass("disabled", !this.model.canOpen()); - this.$(">.name").css("padding-left", this.paddingLeft); - this.$el.toggleClass("type-directory", this.model.isDirectory()); - - if (this.subFiles) { - this.subFiles.$el.appendTo(this.$(".files")); - } - return FilesTreeViewItem.__super__.finish.apply(this, arguments); - }, - - // (event) select the file : extend tree - select: function(e) { - if (e != null) { - e.preventDefault(); - e.stopPropagation(); - } - - if (!this.model.canOpen()) { - return; - } - - if (this.model.isDirectory()) { - if (this.subFiles == null) { - this.subFiles = new FilesTreeView({ - "codebox": this.codebox, - "model": this.model, - "paddingLeft": this.paddingLeft+15 - }, this); - this.subFiles.$el.appendTo(this.$(".files")); - this.subFiles.update(); - } - this.$el.toggleClass("open"); - } else { - this.open(); - } - }, - - // (event) open the file or directory - open: function(e) { - if (e != null) { - e.preventDefault(); - e.stopPropagation(); - } - - if (!this.model.canOpen()) { - return; - } - - if (!this.model.isDirectory()) { - this.model.open({ - 'userChoice': false - }); - } else { - this.select(); - } - } - }); - - // Complete files tree - var FilesTreeView = FilesBaseView.extend({ - tagName: "ul", - className: "cb-files-tree", - - // Constructor - initialize: function(options) { - FilesTreeView.__super__.initialize.apply(this, arguments); - var that = this; - - this.countFiles = 0; - this.paddingLeft = this.options.paddingLeft || 10; - - panelSettings.user.change(function() { - this.update(); - }, this); - - return this; - }, - - // Render the files tree - render: function() { - var that = this; - this.$el.toggleClass("root", this.model.isRoot()); - - // Context menu - ContextMenu.add(this.$el, this.model.contextMenu()); - - this.model.listdir().then(function(files) { - that.clearComponents(); - that.empty(); - that.countFiles = 0; - - _.each(files, function(file) { - if ((file.isGit() && !panelSettings.user.get("gitfolder")) - || (file.isHidden() && !panelSettings.user.get("hiddenfiles"))) { - return; - } - - var v = new FilesTreeViewItem({ - "codebox": that.codebox, - "model": file, - "paddingLeft": that.paddingLeft - }); - v.update(); - v.$el.appendTo(that.$el); - that.addComponent("file", v); - - that.countFiles = that.countFiles + 1; - }); - that.trigger("count", that.countFiles); - }); - - return that.ready(); - }, - }, { - 'Item': FilesTreeViewItem - }); - - return FilesTreeView; -}); \ No newline at end of file diff --git a/addons/cb.panel.outline/client.js b/addons/cb.panel.outline/client.js deleted file mode 100644 index ec27fe23..00000000 --- a/addons/cb.panel.outline/client.js +++ /dev/null @@ -1,30 +0,0 @@ -define([ - "settings", - "views/panel" -], function(settings, PanelOutlineView) { - var commands = codebox.require("core/commands/toolbar"); - var app = codebox.require("core/app"); - var panels = codebox.require("core/panels"); - var menu = codebox.require("core/commands/menu"); - var box = codebox.require("core/box"); - - // Add outline panel - var panel = panels.register("outline", PanelOutlineView, { - title: "Outline" - }); - - // Add command to open outline panel - panel.connectCommand(commands.register("outline.open", { - category: "Panels", - title: "Outline", - description: "Open Outline Panel", - icons: { - 'default': "code", - }, - position: 2, - shortcuts: [] - })); - - // Open panel during startup - if (settings.user.get("startup")) panel.open(); -}); \ No newline at end of file diff --git a/addons/cb.panel.outline/package.json b/addons/cb.panel.outline/package.json deleted file mode 100644 index 553911ee..00000000 --- a/addons/cb.panel.outline/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.panel.outline", - "version": "0.1.0", - "title": "Outline Panel", - "description": "Panel for exploring tags in current file", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.panel.outline/settings.js b/addons/cb.panel.outline/settings.js deleted file mode 100644 index 078ede4a..00000000 --- a/addons/cb.panel.outline/settings.js +++ /dev/null @@ -1,23 +0,0 @@ -define([], function() { - var settings = codebox.require("core/settings"); - - // Add settings - return settings.add({ - 'namespace': "outline", - 'title': "Outline", - 'defaults': { - 'separator': ".", - 'startup': false - }, - 'fields': { - 'separator': { - 'label': 'Tag Parts Separator', - 'type': "text" - }, - 'startup': { - 'label': 'Show Outline Panel at Startup', - 'type': "checkbox" - } - } - }); -}); \ No newline at end of file diff --git a/addons/cb.panel.outline/stylesheets/panel.less b/addons/cb.panel.outline/stylesheets/panel.less deleted file mode 100644 index 4ac541f2..00000000 --- a/addons/cb.panel.outline/stylesheets/panel.less +++ /dev/null @@ -1,107 +0,0 @@ -.cb-panel-outline { - position: absolute; - top: 0px; - bottom: 0px; - left: 0px; - width: 100%; - z-index: 10; - - .tags-tree { - margin: 0px; - padding: 0px; - list-style: none; - - li { - span { - display: block; - padding: 2px 8px; - cursor: default; - position: relative; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - - &:hover { - background: rgba(0, 0, 0, 0.05); - } - - &:before { - content: " "; - background: #b55761; - width: 8px; - height: 8px; - position: absolute; - border-radius: 16px; - top: 8px; - left: 19px; - border: 1px solid #000; - } - } - - &.type-v { - span:before { - background: #81a2be; - } - } - &.type-f { - span:before { - background: #9dbe8c; - } - } - - i { - width: 24px; - } - - .tags-tree { - padding-left: 15px; - display: none; - } - - .tag-icon-close { - display: inline-block; - } - .tag-icon-open { - display: none; - } - - &.open { - > .tag-icon-open { - display: inline-block; - } - > .tag-icon-close { - display: none; - } - - > .tags-tree { - display: block; - } - } - } - } - - .outline-file { - > .tags-tree { - position: absolute; - top: 0px; - bottom: 40px; - left: 5px; - right: 5px; - z-index: 10; - overflow-y: auto; - - .alert { - text-align: center; - } - } - - input, input:focus { - position: absolute; - bottom: 6px; - left: 4px; - right: 4px; - width: calc(~"100% - 8px"); - box-shadow: none; - } - } -} \ No newline at end of file diff --git a/addons/cb.panel.outline/views/panel.js b/addons/cb.panel.outline/views/panel.js deleted file mode 100644 index 8db0acee..00000000 --- a/addons/cb.panel.outline/views/panel.js +++ /dev/null @@ -1,13 +0,0 @@ -define([ - "settings", - "views/tags" -], function(panelSettings, TagsView) { - var PanelFileView = codebox.require("views/panels/file"); - - var PanelOutlineView = PanelFileView.extend({ - className: "cb-panel-outline", - FileView: TagsView - }); - - return PanelOutlineView; -}); \ No newline at end of file diff --git a/addons/cb.panel.outline/views/tags.js b/addons/cb.panel.outline/views/tags.js deleted file mode 100644 index 93ddf941..00000000 --- a/addons/cb.panel.outline/views/tags.js +++ /dev/null @@ -1,182 +0,0 @@ -define([ - "settings", - "less!stylesheets/panel.less" -], function(panelSettings) { - var _ = codebox.require("hr/utils"); - var Q = codebox.require("hr/promise"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var ContextMenu = codebox.require("utils/contextmenu"); - var rpc = codebox.require("core/backends/rpc"); - var box = codebox.require("core/box"); - var files = codebox.require("core/files"); - - var TagsView = hr.View.extend({ - className: "outline-file", - events: { - "click": "onClick", - "keyup input": "onKeyup" - }, - - initialize: function() { - TagsView.__super__.initialize.apply(this, arguments); - - this.$filterInput = $("", { - 'type': "text", - 'class': "form-control input-sm", - "placeholder": "Filter Tags" - }); - this.$tree = $("
      ", { - 'class': "tags-tree" - }); - - this.$filterInput.appendTo(this.$el); - this.$tree.appendTo(this.$el); - }, - - render: function() { - var that = this; - - return this.updateTags() - .fail(function(err) { - that.$tree.html("
      "+(err.message || err)+"
      "); - }) - .fin(function() { - that.ready(); - }); - }, - - // Add tag - addTag: function(tag, $parent, hasChildren) { - var $tags, that = this; - - var open = function() { - files.open(that.options.path, { - // Open content "/^ foo $/"" _> "foo" in editor - pattern: tag.pattern.slice(2, -2) - }); - }; - - var $tag = $("
    • ", { - 'data-tag': tag.name, - 'class': "type-"+(tag.kind || "v"), - 'click': function(e) { - e.stopPropagation(); - - $tag.toggleClass("open"); - if (!hasChildren) open(); - }, - 'dblclick': open - }); - - var $span = $("", { - 'text': tag.showName - }); - $span.appendTo($tag); - - if (hasChildren) { - $tags = $("
        ", { - 'class': "tags-tree" - }).appendTo($tag); - $("", { - 'class': "fa fa-angle-right tag-icon-close" - }).prependTo($span); - $("", { - 'class': "fa fa-angle-down tag-icon-open" - }).prependTo($span); - } else { - $("", { - 'class': "fa fa-blank" - }).prependTo($span); - } - - $tag.appendTo($parent); - - return { - '$tag': $tag, - '$children': $tags - }; - }, - - // Get tag view - getTag: function(name) { - var $tag = this.$("li[data-tag='"+name+"']"); - if ($tag.length == 0) return null; - return $($tag.get(0)); - }, - - // Convert tags as a tree - convertTagsToTree: function(tags) { - var that = this, tree = {}; - var tagSeparator = panelSettings.user.get("separator"); - - _.chain(tags) - .sortBy(function(tag) { - return tag.name.length; - }) - .each(function(tag) { - var parent = tree; - var parts = tag.name.split(tagSeparator); - var _name = _.last(parts); - - _.each(parts, function(part, i) { - if (parent[part]) { - parent = parent[part].children; - } else { - _name = parts.slice(i, parts.length).join(tagSeparator); - return false; - } - }); - - parent[_name] = tag; - parent[_name].showName = _name; - parent[_name].children = {}; - }); - - return tree; - }, - - // Update complete tree - updateTags: function() { - var message = "No outline available for the current file."; - var that = this, tree, path = this.options.path; - - // Clear tree - this.$tree.empty(); - - // No current file - if (!path || path == "/") { - return Q.reject(message); - } - - return rpc.execute("codecomplete/get", { - 'file': path - }) - .then(function(tags) { - if (tags.results.length == 0) return Q.reject(message); - tree = that.convertTagsToTree(tags.results); - - var addChildren = function($parent, tags) { - _.each(tags, function(tag, name) { - var vTag = that.addTag(tag, $parent, _.size(tag.children) > 0); - - addChildren(vTag.$children, tag.children); - }); - } - addChildren(that.$tree, tree); - }); - }, - - onClick: function() { - this.$filterInput.focus(); - }, - onKeyup: function(e) { - var query = this.$filterInput.val().toLowerCase(); - this.$("li").each(function() { - $(this).toggle(!query || $(this).text().toLowerCase().indexOf(query) !== -1); - }); - } - }); - - return TagsView; -}); \ No newline at end of file diff --git a/addons/cb.project/autorun.js b/addons/cb.project/autorun.js deleted file mode 100644 index 2d627f1b..00000000 --- a/addons/cb.project/autorun.js +++ /dev/null @@ -1,146 +0,0 @@ -define([ - 'settings', - 'ports' -], function(settings, ports) { - var _ = codebox.require("hr/utils"); - var commands = codebox.require("core/commands/toolbar"); - var operations = codebox.require("core/operations"); - var box = codebox.require("core/box"); - var dialogs = codebox.require("utils/dialogs"); - var alerts = codebox.require("utils/alerts"); - var Command = codebox.require("models/command"); - - // Currently running terminal - // undefined -> nothing is running - // null -> preparing the run - // {...} _> running - var runningTerm = undefined; - - // Map type -> icon - var typeIcons = { - 'run': "fa-play", - 'build': "fa-cog fa-spin", - 'clean': "fa-eraser" - }; - - // Run command - var runCommand = commands.register("project.run", { - category: "Project", - title: "Run", - icons: { - 'default': "play", - }, - offline: false, - position: 1, - shortcuts: [ - "alt+r" - ] - }, function(options) { - options = _.defaults(options || {}, { - 'ignoreErrors': false - }); - - if (runningTerm !== undefined) { - // For stopping: Close terminal - if (runningTerm != null) { - runningTerm.terminal.closeTab(); - } - - return; - } - - setRunTerminal(null); - - // Run - return box.run({ - 'id': options.id, - 'type': options.type - }) - .then(function(runInfo) { - var op = operations.start("project.run."+runInfo.shellId, null, { - 'title': runInfo.name+" running on port "+runInfo.port, - 'icons': { - 'default': typeIcons[runInfo.type] || "play", - }, - 'action': function() { - // Open the url - window.open(runInfo.url); - - // Check that port is still active - ports.update().then(function(ports) { - var _port = _.find(ports, function(proc) { - return proc.port == runInfo.port; - }); - if (!_port) { - op.destroy(); - } - }); - } - }); - - // Terminal is close: finish the operation - runInfo.terminal.on("tab:close", function() { - op.destroy(); - setRunTerminal(undefined); - }); - - // Set active runningterminal - setRunTerminal(runInfo); - - // Update list of ports - ports.update(); - - // Open url if settings is set for - if (settings.user.get("openrundialog", true)) { - dialogs.confirm("Application is now running on port "+runInfo.port, "Open "+_.escape(runInfo.url)+" in a new window? (This dialog can be disabled in the settings).") - .progress(function(diag) { - diag.once("close", function(result, e) { - if (result) window.open(runInfo.url); - }) - }); - } - }, function(err) { - setRunTerminal(undefined); - - if (!options.ignoreErrors) dialogs.alert("Error running this project", "An error occurred when trying to run this project: "+(err.message || err)); - }); - }); - - var setRunTerminal = function(st) { - var previous = runningTerm; - runningTerm = st; - - // Change command state - if (runningTerm != null) { - runCommand.set({ - 'title': "Stop", - 'icons': { - 'default': "stop" - } - }); - } else { - runCommand.set({ - 'title': "Run", - 'icons': { - 'default': "play" - } - }); - } - - if (previous - && previous.type == "run" - && runningTerm === undefined) { - // Run stop command - return runCommand.run({ - 'type': "stop", - 'ignoreErrors': true - }); - } - }; - - setRunTerminal(undefined); - - return { - 'command': runCommand - } -}); \ No newline at end of file diff --git a/addons/cb.project/client.js b/addons/cb.project/client.js deleted file mode 100644 index 83eff385..00000000 --- a/addons/cb.project/client.js +++ /dev/null @@ -1,77 +0,0 @@ -define([ - 'runner', - 'ports', - 'autorun', - 'samples' -], function(runner, ports, autorun, samples) { - var _ = codebox.require("hr/utils"); - var operations = codebox.require("core/operations"); - var app = codebox.require("core/app"); - var box = codebox.require("core/box"); - var menu = codebox.require("core/commands/menu"); - var dialogs = codebox.require("utils/dialogs"); - var alerts = codebox.require("utils/alerts"); - - // Add samples submenu - menu.getById("file").menuSection([ - samples.command - ]) - - // Add menu - menu.register("project", { - title: "Project", - offline: false - }).menuSection([ - autorun.command, - runner.command - ]).menuSection([ - { - 'id': "project.build", - 'category': "Project", - 'title': "Build", - 'offline': false, - 'action': function() { - return autorun.command.run({ - 'type': "build" - }); - }, - 'shortcuts': [ - "mod+b" - ] - }, - { - 'id': "project.clean", - 'category': "Project", - 'title': "Clean", - 'offline': false, - 'action': function() { - return autorun.command.run({ - 'type': "clean" - }); - }, - 'shortcuts': [ - "mod+shift+k" - ] - } - ]).menuSection([ - { - - 'id': "project.ports.refresh", - 'category': "Project", - 'title': "Refresh Ports", - 'offline': false, - 'action': ports.update - }, - ports.command - ]); - - // Auto-updates - box.on("box:project:define", function() { - runner.update(); - }); - - // Updates list - runner.update(); - ports.update(); - samples.update(); -}); \ No newline at end of file diff --git a/addons/cb.project/package.json b/addons/cb.project/package.json deleted file mode 100644 index 05329674..00000000 --- a/addons/cb.project/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.project", - "version": "0.1.0", - "title": "Project", - "description": "Project types manager: autorun, sample", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.project/ports.js b/addons/cb.project/ports.js deleted file mode 100644 index 810b5f71..00000000 --- a/addons/cb.project/ports.js +++ /dev/null @@ -1,43 +0,0 @@ -define([], function() { - var _ = codebox.require("hr/utils"); - var operations = codebox.require("core/operations"); - var box = codebox.require("core/box"); - var dialogs = codebox.require("utils/dialogs"); - var alerts = codebox.require("utils/alerts"); - var Command = codebox.require("models/command"); - - // HTTP Ports - var httpPorts = Command.register("project.ports", { - 'category': "Project", - 'title': "Running Ports", - 'type': "menu", - 'offline': false, - 'search': false - }); - - // Update running ports list - var updatePorts = function() { - return box.procHttp().then(function(ports) { - httpPorts.menu.reset(_.map(ports, function(proc) { - return { - 'title': proc.port, - 'flags': proc.reachable ? "" : "disabled", - 'action': function() { - if (proc.reachable) { - window.open(proc.url); - } else { - dialogs.alert("Your server is not accessible ", "Your server is not accessible externally because it is bound to 'localhost', please bind it to '0.0.0.0' instead"); - } - } - }; - })); - - return ports; - }); - }; - - return { - 'command': httpPorts, - 'update': updatePorts - } -}); \ No newline at end of file diff --git a/addons/cb.project/runner.js b/addons/cb.project/runner.js deleted file mode 100644 index 75b2018f..00000000 --- a/addons/cb.project/runner.js +++ /dev/null @@ -1,42 +0,0 @@ -define([ - 'autorun' -], function(autorun) { - var _ = codebox.require("hr/utils"); - var operations = codebox.require("core/operations"); - var box = codebox.require("core/box"); - var dialogs = codebox.require("utils/dialogs"); - var alerts = codebox.require("utils/alerts"); - var Command = codebox.require("models/command"); - - // Run commands - var runCommands = Command.register("project.run.action", { - 'category': "Project", - 'title': "Perform Action", - 'type': "menu", - 'offline': false, - 'search': false - }); - - // Update runner list - var updateList = function() { - return box.runner().then(function(runner) { - runCommands.menu.reset(_.map(runner, function(_runner) { - return { - 'title': _runner.name, - 'action': function() { - autorun.command.run({ - 'id': _runner.id - }); - } - }; - })); - - return ports; - }); - }; - - return { - 'command': runCommands, - 'update': updateList - } -}); \ No newline at end of file diff --git a/addons/cb.project/samples.js b/addons/cb.project/samples.js deleted file mode 100644 index 052ac478..00000000 --- a/addons/cb.project/samples.js +++ /dev/null @@ -1,49 +0,0 @@ -define([], function() { - var _ = codebox.require("hr/utils"); - var dialogs = codebox.require("utils/dialogs"); - var box = codebox.require("core/box"); - var rpc = codebox.require("core/backends/rpc"); - var Command = codebox.require("models/command"); - - // HTTP Ports - var samplesMenu = Command.register("project.samples", { - 'category': "Project", - 'title': "Use Sample Project", - 'type': "menu", - 'offline': false, - 'search': false - }); - - // Update samples list - var updateSamples = function() { - return rpc.execute("project/supported").then(function(projectTypes) { - samplesMenu.menu.reset( - _.chain(projectTypes) - .map(function(projectType) { - if (!projectType.sample) return null; - - return { - 'title': projectType.name, - 'action': function() { - dialogs.confirm("Replace workspace contents with "+projectType.name+" sample?", - "WARNING: Using a sample will erase the current contents of your workspace. Use only if your workspace is empty or if you want to wipe it").then(function() { - return rpc.execute("project/useSample", { - 'sample': projectType.id - }); - }); - } - }; - }) - .compact() - .value() - ); - - return projectTypes; - }); - }; - - return { - 'command': samplesMenu, - 'update': updateSamples - } -}); \ No newline at end of file diff --git a/addons/cb.project/settings.js b/addons/cb.project/settings.js deleted file mode 100644 index 83df4a46..00000000 --- a/addons/cb.project/settings.js +++ /dev/null @@ -1,19 +0,0 @@ -define([], function() { - var settings = codebox.require("core/settings"); - - // Add settings - return settings.add({ - 'namespace': "project", - 'title': "Project", - 'defaults': { - 'openrundialog': true - }, - 'fields': { - 'openrundialog': { - 'label': "Open Run Dialog", - 'type': "checkbox", - 'help': "Open new window when running application." - }, - } - }); -}); \ No newline at end of file diff --git a/addons/cb.settings/client.js b/addons/cb.settings/client.js deleted file mode 100644 index 570b2122..00000000 --- a/addons/cb.settings/client.js +++ /dev/null @@ -1,29 +0,0 @@ -define(["views/dialog"], function(SettingsDialog) { - var Command = codebox.require("models/command"); - var app = codebox.require("core/app"); - var dialogs = codebox.require("utils/dialogs"); - var menu = codebox.require("core/commands/menu"); - - // Add opening command - var command = Command.register("settings", { - category: "Application", - title: "Settings", - icons: { - 'default': "cog", - }, - shortcuts: [ - "mod+," - ], - position: 100, - offline: false, - action: function(page) { - dialogs.open(SettingsDialog, { - 'page': page, - 'keyboardEnter': false - }); - } - }); - - menu.getById("file").menu.add(command); -}); - diff --git a/addons/cb.settings/package.json b/addons/cb.settings/package.json deleted file mode 100644 index e8283180..00000000 --- a/addons/cb.settings/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.settings", - "version": "0.1.2", - "title": "Settings", - "description": "Configuration interface for your workspace.", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/addons/cb.settings/stylesheets/dialog.less b/addons/cb.settings/stylesheets/dialog.less deleted file mode 100644 index 49e53302..00000000 --- a/addons/cb.settings/stylesheets/dialog.less +++ /dev/null @@ -1,57 +0,0 @@ -.addon-settings-dialog { - .modal-dialog { - @media screen and (min-width: 768px) { - width: 760px; - } - } - - .modal-body { - padding: 0px; - position: relative; - width: 100%; - height: 100%; - - .settings-title { - opacity: 0.6; - } - - .settings-menu { - position: absolute; - top: 51px; - left: 0px; - width: 200px; - bottom: 0px; - overflow-y: auto; - background: #f8f8f8; - border-right: 1px solid #ddd; - - .nav-pills>li { - >a { - border-radius: 0px; - color: inherit; - border-left: 3px solid transparent; - } - - &.active { - >a { - border-left-color: #5E9EF3; - background: transparent; - } - } - } - } - - .settings-content { - margin-left: 200px; - min-height: 300px; - } - } - - .modal-footer { - margin-top: 0px; - } - - .settings-basepane { - margin: 20px; - } -} diff --git a/addons/cb.settings/templates/dialog.html b/addons/cb.settings/templates/dialog.html deleted file mode 100644 index 4a6fbc66..00000000 --- a/addons/cb.settings/templates/dialog.html +++ /dev/null @@ -1,34 +0,0 @@ -
        - -
        \ No newline at end of file diff --git a/addons/cb.settings/views/dialog.js b/addons/cb.settings/views/dialog.js deleted file mode 100644 index 147fe33e..00000000 --- a/addons/cb.settings/views/dialog.js +++ /dev/null @@ -1,66 +0,0 @@ -define([ - "text!templates/dialog.html", - "less!stylesheets/dialog.less" -], function(templateFile) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var DialogView = codebox.require("views/dialogs/base"); - var settings = codebox.require("core/settings"); - - var SettingsDialog = DialogView.extend({ - className: "addon-settings-dialog modal fade", - templateLoader: "text", - template: templateFile, - events: _.extend({}, DialogView.prototype.events,{ - "submit form": "submit", - "shown.bs.tab a[data-toggle='tab']": "changeTab" - }), - - // Template settings - templateContext: function() { - return { - 'settings': settings, - 'tabs': _.pairs(settings.sections), - 'limit': 3 - } - }, - - // Finish rendering - finish: function() { - var that = this; - settings.each(function(tab) { - tab.render(); - tab.$el.appendTo(this.$("#settings-tab-"+tab.namespace)); - }, this); - setTimeout(function() { - if (that.options.page) { - that.$(".settings-menu a[href='#settings-tab-"+that.options.page+"']").tab('show'); - } else { - that.$(".settings-menu a:first").tab('show'); - } - }, 200); - return SettingsDialog.__super__.finish.apply(this, arguments); - }, - - // Update settings - submit: function(e) { - var that = this; - - if (e != null) { - e.preventDefault(); - e.stopPropagation(); - } - - settings.save().fin(function() { - that.close(); - }); - }, - - // Change tab - changeTab: function(e) { - this.$(".settings-title").text($(e.target).text()); - } - }); - - return SettingsDialog; -}); \ No newline at end of file diff --git a/addons/cb.terminal/client.js b/addons/cb.terminal/client.js deleted file mode 100644 index d701295c..00000000 --- a/addons/cb.terminal/client.js +++ /dev/null @@ -1,137 +0,0 @@ -define([ - "node_modules/sh.js/build/sh", - "views/tab" -], function(Terminal, TerminalTab) { - var Command = codebox.require("models/command"); - var commands = codebox.require("core/commands/toolbar"); - var box = codebox.require("core/box"); - var tabs = codebox.require("core/tabs"); - var settings = codebox.require("core/settings"); - var menu = codebox.require("core/commands/menu"); - - // Add settings - settings.add({ - 'namespace': "terminal", - 'title': "Terminal", - 'defaults': { - 'font': "monospace", - 'size': 13, - 'line-height': 1.3, - 'theme': 'monokai_soda' - }, - 'fields': { - 'font': { - 'label': "Font", - 'type': "select", - 'options': { - 'monospace': "Monospace", - 'arial': "Arial", - 'Courier New': "Courier New", - "'MS Sans Serif', Geneva, sans-serif;": "MS Sans Serif", - "'Lucida Sans Unicode', 'Lucida Grande', sans-serif": "Lucida Sans Unicode", - 'monaco': "Monaco (Mac OS)", - 'menlo': "Menlo (Mac OS)", - 'Ubuntu Mono': "Ubuntu Mono (Ubuntu)", - 'Consolas': "Consolas (Windows)", - 'Lucida Console': "Lucida Console (Windows)" - }, - }, - 'size': { - 'label': 'Font size', - 'type': 'number', - 'min': 8, - 'max': 20, - 'step': 1 - }, - 'line-height': { - 'label': 'Line height', - 'type': 'number', - 'min': 1, - 'max': 1.9, - 'step': 0.1 - }, - 'theme': { - 'label': 'Theme', - 'type': 'select', - 'options': _.chain(Terminal.themes.defaults) - .clone() - .map(function(theme, name) { - return [name, name]; - }) - .object() - .value() - } - } - }); - - // Add opening command - var command = commands.register("terminal.open", { - category: "Terminal", - title: "New Terminal", - description: "New Tab Terminal", - icons: { - 'default': "terminal", - }, - offline: false, - shortcuts: [ - "alt+t" - ] - }, function(shellId, options) { - options = _.defaults(options || {}, { - cwd: null - }); - - // Create trminal tab - var tab = tabs.add(TerminalTab, { - 'shellId': shellId, - 'cwd': options.cwd - }, { - 'type': "terminal", - 'section': "terminals" - }); - - // Return the tab - return tab; - }); - - // Restorer for tabs - tabs.addRestorer("terminal", function(tabInfos) { - var tab = tabs.add(TerminalTab, {}, { - 'type': "terminal", - 'section': "terminals" - }); - - return tab; - }); - - // List terminals menu - var terminalsList = Command.register("terminal.list", { - category: "Terminal", - title: "Open Terminals", - type: "menu", - offline: false, - search: false - }); - - var refreshList = function() { - return box.listShells().then(function(shellIds) { - terminalsList.menu.reset(_.map(shellIds, function(shellId) { - return { - title: shellId, - action: function() { - command.run(shellId) - } - } - })); - }); - }; - - // Reset list when events from shells: - box.on("box:shell:open box:shell:exit", refreshList); - - // Add the command to file/tools menu - menu.getById("file").menuSection([ - command, - terminalsList - ]); -}); \ No newline at end of file diff --git a/addons/cb.terminal/package.json b/addons/cb.terminal/package.json deleted file mode 100644 index edcc0d49..00000000 --- a/addons/cb.terminal/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "cb.terminal", - "version": "0.0.5", - "title": "Terminal", - "description": "Terminal tab integration into your workspace.", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "client" - }, - "engines": { - "codebox": ">=0.7.0" - }, - "dependencies": { - "sh.js": "git+https://github.com/FriendCode/sh.js#1.1.1" - } -} diff --git a/addons/cb.terminal/stylesheets/tab.less b/addons/cb.terminal/stylesheets/tab.less deleted file mode 100644 index 576007d3..00000000 --- a/addons/cb.terminal/stylesheets/tab.less +++ /dev/null @@ -1,76 +0,0 @@ -.addon-terminal-tab { - position: absolute; - width: 100%; - height: 100%; - background: transparent; - - .tab-panel-body .tab-panel-inner.terminal-body { - background: #000; - border-color: #000; - overflow: auto; - cursor: text; - padding: 0px; - font-weight: bold; - padding: 3px; - overflow: hidden; - - * { - user-select: initial; - -webkit-user-select: initial; - } - - .terminal-container { - position: relative; - width: 100%; - height: 100%; - font-family: Menlo,Monaco,"DejaVu Sans Mono",Consolas,"Andale Mono",monospace; - } - .terminal-container div { - margin: 0px; - padding: 0px; - } - .terminal-container .terminal { - width: 100%; - height: 100%; - font-size: 13px; - line-height: 18px; - } - .terminal-container .terminal-input { - position: absolute; - top: 0; - left: -1000%; - background: rgba(255,255,255,0.75); - color: black; - border: 0; - outline: 0; - width: 100%; - } - .terminal-container .terminal-screen-keys { - position: absolute; - top: 0; - right: 0; - } - .terminal-container .terminal-screen-keys button { - background: -webkit-linear-gradient(top, #eeeef0, #d3d3d9); - border: 1px solid #58575e; - box-shadow: 0 2px 2px rgba(0,0,0,0.25), inset 0 -2px 0 rgba(0,0,0,0.25), inset 0 1px 0 #fff; - border: 1px solid #000; - border-radius: 2px; - padding: 8px; - font-size: 14px; - text-shadow: 0 1px 0 #fff; - } - .terminal-container .terminal-screen-keys button:focus, .terminal-container .terminal-screen-keys button.active { - outline: 0px; - background: -webkit-linear-gradient(top, #ccccd0, #a3a3a9); - } - .terminal-container .terminal-size-indicator { - position: absolute; - bottom: 0; - left: 0; - background-color: rgba(255,255,255,0.75); - color: black; - padding: 0 3px; - } - }; -} \ No newline at end of file diff --git a/addons/cb.terminal/views/tab.js b/addons/cb.terminal/views/tab.js deleted file mode 100644 index 2d4c2193..00000000 --- a/addons/cb.terminal/views/tab.js +++ /dev/null @@ -1,177 +0,0 @@ -define([ - "node_modules/sh.js/build/sh", - "less!stylesheets/tab.less" -], function(Terminal) { - var _ = codebox.require("hr/utils"); - var $ = codebox.require("hr/dom"); - var hr = codebox.require("hr/hr"); - var Tab = codebox.require("views/tabs/base"); - var box = codebox.require("core/box"); - var user = codebox.require("core/user"); - - var settings = user.settings("terminal"); - - var TerminalTab = Tab.extend({ - className: Tab.prototype.className+ " addon-terminal-tab", - defaults: { - shellId: null, - resize: true, - cwd: null - }, - menuTitle: "Terminal", - events: { - 'contextmenu': "clickTerm", - 'click': "clickTerm", - 'touchstart': "clickTerm" - }, - - initialize: function(options) { - var that = this; - TerminalTab.__super__.initialize.apply(this, arguments); - this.connected = false; - this.setTabState("loading", true); - - // Init menu - this.menu.menuSection([ - { - 'type': "checkbox", - 'title': "Exit", - 'action': function(state) { - that.closeTab(); - } - } - ]); - - // Init rendering - this.term_el = $("
        ", { - 'class': "tab-panel-inner terminal-body" - }).appendTo($("
        ", {"class": "tab-panel-body"}).appendTo(this.$el)).get(0); - - // New terminal - this.term = new Terminal({ - cols: 80, - rows: 24, - theme: settings.get("theme", 'default') - }); - this.term.open(this.term_el); - - this.interval = setInterval(_.bind(this.resize, this), 2000); - - // Init codebox stream - this.sessionId = this.options.shellId || _.uniqueId("term"); - this.shell = box.openShell({ - 'shellId': this.options.shellId ? this.sessionId : this.sessionId+"-"+(new Date()).getSeconds(), - 'cwd': this.options.cwd - }); - - this.on("tab:close", function() { - clearInterval(this.interval); - this.shell.disconnect(); - this.term.destroy(); - }, this); - - this.on("tab:state", function(state) { - if (state) { - this.focus(); - } - }, this); - this.on("tab:layout", function() { - that.resize(); - }, this); - - this.setTabTitle("Terminal - "+this.sessionId); - - - this.shell.once('data', function() { - that.setTabState("loading", false); - that.resize(); - }); - - this.shell.on('data', function(chunk) { - that.write(chunk); - }); - - this.shell.on("connect", function() { - that.connected = true; - that.trigger("terminal:ready"); - }, this); - - this.shell.on('disconnect', function() { - that.writeln("Connection closed"); - that.closeTab(); - }); - - // Connect term - this.term.on('data', function(data) { - that.shell.write(data); - }); - this.term.on("resize", function(w, h) { - that.shell.resize(w, h); - }); - - this.shell.connect(); - - setTimeout(function() { - that.focus(); - }, 300); - return this; - }, - - // Render - render: function() { - this.$el.css({ - "font-family": settings.get("font", "monospace"), - "font-size": settings.get("size", 13)+'px', - "line-height": settings.get("line-height", 1.3) - }); - $(this.term_el).css({ - 'background': this.term.colors[256], - 'border-color': this.term.colors[256] - }); - - return this.ready(); - }, - - // Resize the terminal - resize: function() { - if (!this.options.resize) { return false; } - - var w = this.$el.width(); - var h = this.$el.height(); - - if (w != this._width || h != this._height) { - this._width = w; - this._height = h; - this.term.sizeToFit(); - } - - return this; - }, - - // Focus - focus: function() { - this.term.focus(); - }, - - // Write - write: function(content) { - this.term.write(content); - return this; - }, - - // Write a line - writeln: function(line) { - return this.write(line+"\r\n"); - }, - - // Block propagation of clicks to sublevel - clickTerm: function(e) { - e.stopPropagation(); - - // We stop propagation so we need to active the tab manually - this.openTab(); - } - }); - - return TerminalTab; -}); diff --git a/addons/cb.theme.dark/ace/theme.js b/addons/cb.theme.dark/ace/theme.js deleted file mode 100644 index 4c4c049f..00000000 --- a/addons/cb.theme.dark/ace/theme.js +++ /dev/null @@ -1,10 +0,0 @@ -define([ - "less!ace/theme.less" -], function(cssContent) { - - return { - 'isDark': true, - 'cssClass': "ace-codebox-dark", - 'cssText': cssContent - } -}); \ No newline at end of file diff --git a/addons/cb.theme.dark/ace/theme.less b/addons/cb.theme.dark/ace/theme.less deleted file mode 100644 index c824a690..00000000 --- a/addons/cb.theme.dark/ace/theme.less +++ /dev/null @@ -1,206 +0,0 @@ -.ace_editor.ace-codebox-dark { - background-color: #2b303b; - color: #C5C8C6; - - .ace_gutter { - background: #2b303b; - color: #757a84 - } - - .ace_print-margin { - width: 1px; - background: #333d46 - } - - .ace_cursor { - color: #AEAFAD - } - - .ace_marker-layer .ace_selection { - background: #3d4550; - } - - &.ace_multiselect .ace_selection.ace_start { - box-shadow: 0 0 3px 0px #1D1F21; - border-radius: 2px - } - - .ace_marker-layer .ace_step { - background: rgb(102, 82, 0) - } - - .ace_marker-layer .ace_bracket { - margin: -1px 0 0 -1px; - border: 1px solid #4B4E55 - } - - .ace_marker-layer .ace_active-line { - background: #333d46 - } - - .ace_gutter-active-line { - background-color: #333d46; - } - - .ace_marker-layer .ace_selected-word { - border: 1px solid #373B41 - } - - .ace_invisible { - color: #4B4E55 - } - - .ace_keyword, - .ace_meta, - .ace_storage, - .ace_storage.ace_type, - .ace_support.ace_type { - color: #B294BB - } - - .ace_keyword.ace_operator { - color: #8ABEB7 - } - - .ace_constant.ace_character, - .ace_constant.ace_language, - .ace_constant.ace_numeric, - .ace_keyword.ace_other.ace_unit, - .ace_support.ace_constant, - .ace_variable.ace_parameter { - color: #cc856c - } - - .ace_constant.ace_other { - color: #CED1CF - } - - .ace_invalid { - color: #CED2CF; - background-color: #DF5F5F - } - - .ace_invalid.ace_deprecated { - color: #CED2CF; - background-color: #B798BF - } - - .ace_fold { - background-color: #81A2BE; - border-color: #757a84 - } - - .ace_entity.ace_name.ace_function, - .ace_support.ace_function, - .ace_variable { - color: #81A2BE - } - - .ace_support.ace_class, - .ace_support.ace_type { - color: #F0C674 - } - - .ace_heading, - .ace_string { - color: #9dbe8c - } - - .ace_entity.ace_name.ace_tag, - .ace_entity.ace_other.ace_attribute-name, - .ace_meta.ace_tag, - .ace_string.ace_regexp, - .ace_variable { - color: #b55761 - } - - .ace_comment { - color: #969896 - } - - .ace_indent-guide { - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y; - } - - /* Autocomplete dialog */ - &.ace_autocomplete { - width: 280px; - z-index: 200000; - background: #323d46; - color: #65737e; - border: none; - position: fixed; - box-shadow: 2px 3px 5px rgba(0,0,0,.2); - line-height: 2; - - font-smoothing: subpixel-antialiased; - -webkit-font-smoothing: subpixel-antialiased; - - .ace_marker-layer .ace_active-line { - background-color: #4f5b67; - z-index: 1; - } - .ace_text-layer .ace_selected, - .ace_text-layer .ace_selected .ace_rightAlignedText{ - color: #a1adba; - } - .ace_line-hover { - border: none; - margin-top: -1px; - background: none; - } - .ace_line-hover { - position: absolute; - z-index: 2; - } - .ace_rightAlignedText { - color: #65737e; - font-style: italic; - display: inline-block; - position: absolute; - right: 4px; - text-align: right; - z-index: -1; - } - .ace_completion-highlight{ - color: #c0c5ce; - } - } - - /* Search dialog */ - .ace_search { - border-color: transparent; - background: #1c1f25; - color: #65737e; - - .ace_searchbtn_close { - &:hover { - background-color: #323d46; - color: #65737e; - } - } - - .ace_search_field { - background: #323d46; - color: #65737e; - border-color: transparent; - } - - .ace_search_form, .ace_replace_form { - background-color: #323d46; - color: #65737e; - border-color: transparent; - } - - .ace_button { - background-color: #323d46; - color: #65737e; - } - - .ace_searchbtn, .ace_replacebtn{ - background-color: #323d46; - color: #65737e; - border-color: transparent; - } - } -} diff --git a/addons/cb.theme.dark/main.js b/addons/cb.theme.dark/main.js deleted file mode 100644 index a8e988b9..00000000 --- a/addons/cb.theme.dark/main.js +++ /dev/null @@ -1,128 +0,0 @@ -define([ - 'ace/theme' -], function(aceTheme) { - var themes = codebox.require("core/themes"); - - var bgDarker = "#1a1d24"; - var colorDarker = "#505c66"; - - var bgDark = "#222830"; - var colorDark = "#64737e"; - - var bgNormal = "#1c1f25"; - var colorNormal = "#dfe0e6"; - - var bgLight = "#2b303b"; - var colorLight = "#dadfe6"; - - themes.add({ - id: "dark", - title: "Dark", - - editor: { - 'theme': aceTheme - }, - styles: { - // Top menubar - menubar: { - 'background': bgDarker, - 'color': colorDark, - 'border-color': "#111", - - button: { - 'border-color': bgNormal - } - }, - - // Statusbar - statusbar: { - 'background': bgDarker, - 'color': colorDark, - 'border-color': "#111", - - button: { - 'border-color': bgNormal - } - }, - - // Lateral bar panels - lateralbar: { - 'background': bgDark, - - commands: { - 'background': bgDark, - 'color': colorLight - }, - body: { - 'color': colorDark - } - }, - - // Body - body: { - 'background': bgDark, - 'color': colorDark - }, - - // Tabs - tabs: { - section: { - 'border-color': bgDark - }, - header: { - 'background': bgDark, - 'color': colorDark - }, - content: { - 'background': bgLight - }, - tab: { - '&.active': { - 'background': bgLight, - 'color': colorLight - } - } - }, - - // Operations - operations: { - operation: { - 'background': bgLight, - 'color': "#fff", - 'border-color': "transparent" - } - }, - - // Alerts - alerts: { - alert: { - 'background': bgLight, - 'color': colorLight, - 'border-color': "transparent" - } - }, - - // Palette - palette: { - 'background': bgDark, - 'border-color': bgDarker, - - input: { - 'background': bgLight, - 'border-color': bgDarker, - 'color': colorLight - }, - - results: { - 'background': bgLight, - 'border-color': bgDarker, - 'color': colorLight, - - command: { - 'border-color': bgDarker - } - } - } - } - }); -}); \ No newline at end of file diff --git a/addons/cb.theme.dark/package.json b/addons/cb.theme.dark/package.json deleted file mode 100644 index e5d40d00..00000000 --- a/addons/cb.theme.dark/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "cb.theme.dark", - "version": "0.0.1", - "title": "Dark Theme", - "description": "Dark and gray theme.", - "homepage": "https://github.com/FriendCode/codebox", - "license": "Apache", - "author": { - "name": "Codebox", - "email": "contact@friendco.de", - "url": "https://www.codebox.io" - }, - "client": { - "main": "main" - }, - "engines": { - "codebox": ">=0.7.0" - } -} \ No newline at end of file diff --git a/bin/codebox.js b/bin/codebox.js index 5051d6e6..ceb0a5d9 100755 --- a/bin/codebox.js +++ b/bin/codebox.js @@ -1,155 +1,12 @@ -#!/usr/bin/env node +#! /usr/bin/env node -var Q = require('q'); -var _ = require('lodash'); -var cli = require('commander'); -var path = require('path'); -var open = require("open"); -var Gittle = require('gittle'); +var codebox = require("../lib"); -var pkg = require('../package.json'); -var codebox = require("../index.js"); - -// Codebox git repo: use to identify the user -var codeboxGitRepo = new Gittle(path.resolve(__dirname, "..")); - -// Options -cli.option('-p, --port [http port]', 'Port to run the IDE'); -cli.option('-n, --hostname [http hostname]', 'Hostname to run the IDE'); -cli.option('-t, --title [project title]', 'Title for the project.'); -cli.option('-s, --sample [project type]', 'Replace directory content by a sample (warning: erase content).'); -cli.option('-o, --open', 'Open the IDE in your favorite browser'); -cli.option('-e, --email [email address]', 'Email address to use as a default authentication'); -cli.option('-u, --users [list users]', 'List of coma seperated users and password (formatted as "username:password")'); - - -// An authentication hook that uses a dictionary of users -function usersAuthHook(users) { - return function(data) { - if (!data.email || !data.token) { - return Q.reject(new Error("Need 'token' and 'email' for auth hook")); - } - - var userId = data.email; - - if (!users[userId] || data.token != users[userId]) { - return Q.reject(new Error("Invalid user !")); - } - - return { - 'userId': userId, - 'name': userId, - 'token': data.token, - 'email': data.email - }; - }; -} - -// Command 'run' -cli.command('run [folder]') -.description('Run a Codebox into a specific folder.') -.action(function(projectDirectory) { - var that = this; - var prepare = Q(); - - // Codebox.io settings - that.box = process.env.CODEBOXIO_BOXID; - that.key = process.env.CODEBOXIO_TOKEN; - that.codeboxio = process.env.CODEBOXIO_HOST || "https://api.codebox.io"; - - // Default options - that.directory = projectDirectory || process.env.WORKSPACE_DIR || "./"; - that.title = that.title || process.env.WORKSPACE_NAME; - that.port = that.port || process.env.PORT || 8000; - that.hostname = that.hostname || "0.0.0.0"; - - var users = !that.users ? {} : _.object(_.map(that.users.split(','), function(x) { - // x === 'username:password' - return x.split(':', 2); - })); - - - var config = { - 'root': that.directory, - 'title': that.title, - 'server': { - 'port': parseInt(that.port), - 'hostname': that.hostname - }, - 'users': { - 'defaultEmail': that.email - }, - 'project': { - 'forceSample': that.sample - } - }; - - // Use Codebox.io - if (that.box && that.codeboxio && that.key) { - _.extend(config, { - 'workspace': { - 'id': that.box - }, - 'hooks': { - 'auth': that.codeboxio+"/api/box/"+that.box+"/auth", - 'events': that.codeboxio+"/api/box/"+that.box+"/events", - 'settings': that.codeboxio+"/api/account/settings", - 'addons': that.codeboxio+"/api/addons/valid" - }, - 'webhook': { - 'authToken': that.key - }, - 'proc': { - 'urlPattern': 'http://web-%d.' + that.box + '.vm1.dynobox.io' - }, - 'users': { - // Don't use default git user - 'gitDefault': false - } - }); - } else if(!_.isEmpty(users)) { - _.extend(config, { - 'public': false, - 'hooks': { - 'auth': usersAuthHook(users) - } - }); - } - - // Auth user using git - prepare.fin(function() { - // Start Codebox - return codebox.start(config).then(function() { - var url = "http://localhost:"+that.port; - - console.log("\nCodebox is running at",url); - - if (that.open) { - open(url); - } - }, function(err) { - console.error('Error initializing CodeBox'); - console.error(err); - console.error(err.stack); - - // Kill process - process.exit(1); - }); - }) +codebox.start({ + port: 3000 +}) +.then(function() { + console.log("Codebox is running"); +}, function(err) { + console.log(err.stack || err.message || err); }); - -cli.on('--help', function(){ - console.log(' Version: %s', pkg.version); - console.log(''); - console.log(' Examples:'); - console.log(''); - console.log(' $ codebox run'); - console.log(' $ codebox run ./myProject'); - console.log(''); - console.log(' Use option --open to directly open the IDE in your browser:'); - console.log(' $ codebox run ./myProject --open'); - console.log(''); -}); - -cli.version(pkg.version).parse(process.argv); -if (!cli.args.length) cli.help(); diff --git a/client/collections/addons.js b/client/collections/addons.js deleted file mode 100644 index b4b4bca6..00000000 --- a/client/collections/addons.js +++ /dev/null @@ -1,233 +0,0 @@ -define([ - "hr/promise", - "hr/utils", - "hr/hr", - "core/backends/rpc", - "models/addon", - "utils/dialogs" -], function(Q, _, hr, rpc, Addon, dialogs) { - var Addons = hr.Collection.extend({ - model: Addon, - defaults: _.defaults({ - loader: "getInstalled", - loaderArgs: [], - }, hr.Collection.prototype.defaults), - - // Constructor - initialize: function() { - Addons.__super__.initialize.apply(this, arguments); - - this.resolved = {}; - this.provides = {}; - - return this; - }, - - // Get installed addons - getInstalled: function(options) { - var that = this; - - options = _.defaults(options || {}, {}); - - return rpc.execute("addons/list").then(function(data) { - that.add(_.values(data)); - }); - }, - - // Get by name - getByName: function(name) { - return this.find(function(addon) { - return addon.get("name") == name; - }); - }, - - // Check addons is installed - isInstalled: function(name) { - if (!_.isString(name)) name = name.get("name"); - - return this.getByName(name) != null; - }, - - // Check addons is a default addon - isDefault: function(name) { - if (!_.isString(name)) name = name.get("name"); - - var m = this.getByName(name); - if (m == null) return false; - return m.get("default"); - }, - - // Check is updated - isUpdated: function(addon) { - var m = this.getByName(addon.get("name")); - if (!m) return true; - return m.version() >= addon.version(); - }, - - // Get addon state - getState: function(name) { - if (!_.isString(name)) name = name.get("name"); - - var m = this.getByName(name); - if (m == null) return null; - return m.get("state"); - }, - - // Install an addon - install: function(git) { - var that = this; - - return rpc.execute("addons/install", { - 'git': git - }).then(function(data) { - that.reset([]); - return that.getInstalled(); - }); - }, - uninstall: function(name) { - var that = this; - - return rpc.execute("addons/uninstall", { - 'name': name - }).then(function() { - that.reset([]); - return that.getInstalled(); - }); - }, - - // Extract from engineer, order addons for loading - checkCycles: function() { - var that = this; - var plugins = this.map(function(addon, index) { - return { - name: addon.get("name"), - provides: addon.get("client.provides", []).concat(), - consumes: addon.get("client.consumes", []).concat(), - i: index - }; - }); - - var changed = true; - var sorted = []; - - while(plugins.length && changed) { - changed = false; - - plugins.concat().forEach(function(plugin) { - var consumes = plugin.consumes.concat(); - - var resolvedAll = true; - for (var i=0; i 0) { - var e = new Error("Error with "+_.size(errors)+" addons"); - e.addonsError = errors; - return Q.reject(e); - } - return Q(); - }); - }, - - // Get addons from an index - loadFromIndex: function(indexUrl) { - var cached, that = this, indexKey = indexUrl; - var box = require("core/box"); - - var resetCollection = function(index) { - that.reset(_.map(index.addons, function(addon) { - return _.extend(addon['package'], { - 'git': addon.git - }); - })); - return Q(index); - }; - - cached = hr.Cache.get("addons", indexKey); - if (cached) return resetCollection(cached); - - return rpc.execute("addons/registry", { - 'url': indexUrl - }) - .then(function(index) { - hr.Cache.set("addons", indexKey, index, 60*60); - return resetCollection(index); - }); - } - }); - - return Addons; -}); \ No newline at end of file diff --git a/client/collections/changes.js b/client/collections/changes.js deleted file mode 100644 index 2105e18e..00000000 --- a/client/collections/changes.js +++ /dev/null @@ -1,27 +0,0 @@ -define([ - "hr/utils", - "hr/hr", - "models/change" -], function(_, hr, Change) { - var Changes = hr.Collection.extend({ - model: Change, - - // Sort comparator - comparator: function(command) { - return command.get("path", "").length; - }, - - // Apply all - applyAll: function() { - console.log("apply all changes", this.size()); - return this.reduce(function(prev, change) { - console.log("next ", change, prev); - return prev.then(function() { - return change.apply(); - }) - }, Q()); - } - }); - - return Changes; -}); \ No newline at end of file diff --git a/client/collections/commands.js b/client/collections/commands.js deleted file mode 100644 index 4c3780ac..00000000 --- a/client/collections/commands.js +++ /dev/null @@ -1,16 +0,0 @@ -define([ - "hr/utils", - "hr/hr", - "models/command" -], function(_, hr, Command) { - var Commands = hr.Collection.extend({ - model: Command, - - // Sort comparator - comparator: function(command) { - return command.get("position", 2); - } - }); - - return Commands; -}); \ No newline at end of file diff --git a/client/collections/files.js b/client/collections/files.js deleted file mode 100644 index 6c51e8dc..00000000 --- a/client/collections/files.js +++ /dev/null @@ -1,11 +0,0 @@ -define([ - "hr/utils", - "hr/hr", - "models/file" -], function(_, hr, File) { - var Files = hr.Collection.extend({ - model: File - }); - - return Files; -}); \ No newline at end of file diff --git a/client/collections/operations.js b/client/collections/operations.js deleted file mode 100644 index 95486c2b..00000000 --- a/client/collections/operations.js +++ /dev/null @@ -1,66 +0,0 @@ -define([ - "hr/utils", - "hr/hr", - "hr/promise", - "models/operation", - "utils/dialogs" -], function(_, hr, Q, Operation, dialogs) { - var Operations = hr.Collection.extend({ - model: Operation, - - // Sort comparator - comparator: function(command) { - return command.get("progress", 0); - }, - - // Get by id - getById: function(opId) { - return this.find(function(op) { - return op.id == opId; - }); - }, - - // Start an operation - start: function(opId, startMethod, properties, options) { - var op, d; - - options = _.defaults({}, options || {}, { - 'unique': true - }); - - op = this.getById(opId); - - if (op) return Q.reject(new Error("An operation with this id is already running: "+opId)); - - op = new Operation({}, _.extend({ - 'id': opId - }, properties || {})); - - this.add(op); - - if (startMethod) { - d = startMethod(op); - - // Error during the operation - d.fail(function(err) { - dialogs.alert("Error during an operation ("+_.escape(opId)+")", err.message || err); - }); - - // Progress - d.progress(function(p) { - if (_.isNumber(p)) op.progress(p); - }); - - // Destroy the operation - d.fin(function() { - op.destroy(); - }); - return d; - } else { - return op; - } - } - }); - - return Operations; -}); \ No newline at end of file diff --git a/client/collections/tabs.js b/client/collections/tabs.js deleted file mode 100644 index 20f6b6f4..00000000 --- a/client/collections/tabs.js +++ /dev/null @@ -1,25 +0,0 @@ -define([ - "hr/utils", - "hr/hr", - "models/tab" -], function(_, hr, Tab) { - var Tabs = hr.Collection.extend({ - model: Tab, - - // Return a tab by its id - getById: function(id) { - return this.find(function(tab) { - return tab.id == id; - }); - }, - - // Return current active tab - getActive: function() { - return this.find(function(tab) { - return tab.get("active"); - }); - }, - }); - - return Tabs; -}); \ No newline at end of file diff --git a/client/collections/users.js b/client/collections/users.js deleted file mode 100644 index 106c2c41..00000000 --- a/client/collections/users.js +++ /dev/null @@ -1,27 +0,0 @@ -define([ - "hr/utils", - "hr/hr", - "core/backends/rpc", - "models/user" -], function(_, hr, rpc, User) { - var Users = hr.Collection.extend({ - model: User, - - // Return an user from the collection by its user id - getById: function(userId) { - return this.find(function(model) { - return model.get("userId") == userId; - }) - }, - - // Get list of collaborators from the box - getCollaborators: function() { - var that = this; - return rpc.execute("users/list").then(function(data) { - that.reset(data); - }); - } - }); - - return Users; -}); \ No newline at end of file diff --git a/client/core/addons.js b/client/core/addons.js deleted file mode 100644 index 01c2b53e..00000000 --- a/client/core/addons.js +++ /dev/null @@ -1,59 +0,0 @@ -define([ - 'hr/hr', - 'hr/promise', - 'models/command', - 'collections/commands', - 'collections/addons', - 'utils/dialogs', - 'core/operations' -], function (hr, Q, Command, Commands, Addons, dialogs, operations) { - // Collection for all installed addons - var addons = new Addons(); - - // Command to install with an url - Command.register("addons.install", { - category: "Add-ons", - title: "Install", - description: "Install with GIT Url", - offline: false, - action: function(url) { - return Q() - .then(function() { - if (url) return url; - return dialogs.prompt("Install a new addon", "GIT url for the addon:", ""); - }) - .then(function(_url) { - return operations.start("addon.install", function(op) { - return addons.install(_url); - }, { - title: "Installing add-on" - }); - }) - } - }); - - // Command to uninstall from a name - Command.register("addons.uninstall", { - category: "Add-ons", - title: "Uninstall", - description: "Uninstall with name", - offline: false, - search: false, - action: function(name) { - return Q() - .then(function() { - if (name) return name; - return dialogs.prompt("Uninstall an addon", "Name of the addon:", ""); - }) - .then(function(_name) { - return operations.start("addon.uninstall", function(op) { - return addons.uninstall(_name); - }, { - title: "Uninstalling add-on" - }); - }) - } - }); - - return addons; -}); \ No newline at end of file diff --git a/client/core/app.js b/client/core/app.js deleted file mode 100644 index 65e1aa1c..00000000 --- a/client/core/app.js +++ /dev/null @@ -1,252 +0,0 @@ -define([ - 'hr/hr', - 'utils/url', - 'utils/dialogs', - 'utils/alerts', - 'utils/loading', - 'views/grid', - 'text!resources/templates/main.html', - 'core/box', - 'core/session', - 'core/addons', - 'core/box', - 'core/files', - 'core/commands/toolbar', - 'core/commands/menu', - 'core/commands/statusbar', - 'core/commands/palette', - 'core/tabs', - 'core/panels', - 'core/operations', - 'core/localfs', - 'core/themes', - 'core/search/commands', - 'core/search/files', - 'core/search/tags', - 'core/search/addons', - 'core/search/code' -], function (hr, url, dialogs, alerts, loading, GridView, templateFile, -box, session, addons, box, files, commands, menu, statusbar, palette, tabs, panels, operations, localfs, themes) { - - // Define base application - var Application = hr.Application.extend({ - name: "Codebox", - template: templateFile, - metas: { - "robots": "noindex, nofollow", - "description": "Cloud IDE on a box.", - "apple-mobile-web-app-capable": "yes", - "apple-mobile-web-app-status-bar-style": "black", - "viewport": "width=device-width, initial-scale=1, user-scalable=no" - }, - links: { - "icon": hr.Urls.static("images/icons/32.png"), - "apple-touch-icon": hr.Urls.static("images/icons/ios.png") - }, - events: { - "click .cb-login .login-box #login-submit": "actionLoginBox" - }, - - // Constructor - initialize: function() { - Application.__super__.initialize.apply(this, arguments); - this._autologin = true; - this.loginError = null; - - // Init base grid for UI - this.grid = new GridView({ - columns: 1000 - }); - - // Add lateral bar: panels and operations - var v = this.grid.addView(new hr.View(), { - width: 18 - }); - panels.$el.appendTo(v.$el); - operations.$el.appendTo(v.$el); - - // Add operations - operations.on("add remove reset", function() { - setTimeout(function() { - panels.$el.css("bottom", operations.$el.height()); - }, 200); - }); - - // Add tabs - this.grid.addView(tabs); - - // Default tab: new file - tabs.on("tabs:default tabs:opennew", function() { - files.openNew(); - }, this); - - // Offline: state/update - hr.Offline.on("state", function(state) { - if (!state) { - alerts.show("Caution: Connection lost, Workspace is now in Offline mode", 5000); - if (!localfs.isSyncEnabled()) { - dialogs.alert("Caution: Connection lost", "Offline file synchronization is not enabled for this workspace, enable it first when online."); - } - } else { - dialogs.confirm("Connection detected", "Save changes before refreshing. Do you want to refresh now (unsaved changes will be lost) ?") - .then(function() { - location.reload(); - }); - } - }); - hr.Offline.on("update", function() { - location.reload(); - }); - - // Title changed - box.on("change:name", function() { - this.title(box.get("name")); - }, this); - - return this; - }, - - // Template rendering context - templateContext: function() { - return { - 'email': hr.Cookies.get("email"), - 'token': hr.Cookies.get("token"), - 'loginError': this.loginError - }; - }, - - // Render the application - render: function() { - var email = hr.Cookies.get("email"); - var password = hr.Cookies.get("token"); - - if (!box.isAuth() && ((email && password) || (email && box.get("public"))) && this._autologin) { - this.doLogin(email, password); - return; - } - return Application.__super__.render.apply(this, arguments); - }, - - // Finish rendering - finish: function() { - var that = this; - - if (box.isAuth()) { - // Add menu - menu.$el.appendTo(this.$(".cb-menubar")); - menu.render(); - - // Add statusbar - statusbar.$el.appendTo(this.$(".cb-statusbar")); - statusbar.render(); - - // Add commands - commands.$el.appendTo(this.$(".cb-commands")); - commands.render(); - - // Add grid - this.grid.$el.appendTo(this.$(".cb-body")); - - // Add palette - palette.$el.appendTo(this.$(".cb-body")); - palette.render(); - - // Load addons - loading.show(addons.loadAll()).fail(function(err) { - return dialogs.alert("Error loading Add-ons", - "

        Error when initializing addons." + - " Please check addons states using the addons manager and reinstall problematic add-ons.

        " + - "

        Error message: "+ (err.message || err) +"

        " + - _.map(err.addonsError || [], function(error) { - return "

        - "+_.escape(error.addon)+": "+(error.error.message || error.error)+"

        "; - }).join("\n")); - }) - .fin(themes.init) - .fin(function() { - // Load new addons - addons.on("add", function(addon) { - addon.load(); - }); - - // Check update - hr.Offline.checkUpdate(); - - // Trigger event that app is ready - that.trigger("ready"); - - // Open new file if not files opened by addons and no restored tabs - tabs.restoreTabs() - .then(function(_n) { - if (files.active.size() == 0 && _n == 0) files.openNew(); - }); - }); - } - return Application.__super__.finish.apply(this, arguments); - }, - - // Login to box - actionLoginBox: function(e) { - var that = this; - if (e) { - e.preventDefault(); - } - - var email = this.$(".login-box #login-email").val(); - var password = this.$(".login-box #login-token").val(); - - this.doLogin(email, password); - }, - - // Do login - doLogin: function(email, password) { - var that = this; - - // If public: generate a random password - if (box.get("public")) { - password = Math.random().toString(36).substring(8); - } - - // Clear errors - this.$(".login-box .form-group").removeClass("has-error"); - - // No email - if (!email) { - this.$(".login-box #login-email").parent(".form-group").addClass("has-error"); - return Q.reject(new Error("No email")); - } - - // No password - if (!password) { - this.$(".login-box #login-token").parent(".form-group").addClass("has-error"); - return Q.reject(new Error("No password")); - } - - return session.start(email, password).then(function() { - hr.Cookies.set("email", email); - hr.Cookies.set("token", password); - - that.render(); - }).fail(function(err) { - that._autologin = false; - that.loginError = err; - - loading.stop(); - that.render(); - }); - }, - - // Toggle mode - toggleMode: function(mode, st) { - $("#codebox").toggleClass("mode-"+mode, st); - st = this.hasMode(mode); - $(".cb-active-mode-"+mode).toggleClass("active", st); - $(".cb-inactive-mode-"+mode).toggleClass("active", !st); - }, - hasMode: function(mode, st) { - return $("#codebox").hasClass("mode-"+mode); - } - }); - - var app = new Application(); - return app; -}); diff --git a/client/core/backends/vfs.js b/client/core/backends/vfs.js deleted file mode 100644 index 0d1ade59..00000000 --- a/client/core/backends/vfs.js +++ /dev/null @@ -1,176 +0,0 @@ -define([ - 'hr/utils', - 'hr/hr', - 'utils/url', - 'core/localfs' -], function(_, hr, Url, localfs) { - var logger = hr.Logger.addNamespace("vfs"); - - // Create backend - var vfs = new hr.Backend({ - prefix: "vfs" - }); - - // Emulate a vfs event - var triggerWatchEvent = function(name, path, data) { - var eventName = "watch.change."+name; - vfs.trigger("event:"+eventName, { - 'event': eventName, - 'data': _.extend({}, { - 'path': path, - 'change': name, - 'source': "fakeVfs" - }, data) - }); - }; - - // Refresh all vfs when offlien change - hr.Offline.on("state", function() { - triggerWatchEvent("folder", "/"); - }); - - // Map vfs method -> http request method - var methodsMap = { - "listdir": "getJSON", - "write": "put", - "mkdir": "put", - "create": "put", - "special": "post", - "remove": "delete", - "read": "get" - }; - - // Base method when connection is on - vfs.defaultMethod({ - execute: function(args, options, method) { - if (args && method != "write") args = JSON.stringify(args); - if (!options.url) return Q.reject(new Error("VFS requests need 'url' option")); - if (!methodsMap[method]) return Q.reject(new Error("Invalid VFS request: "+method)); - - logger.log(method+": "+options.url); - return hr.Requests[methodsMap[method]](options.url, args, options); - }, - after: function(args, results, options, method) { - var path = localfs.urlToPath(options.url); - switch (method) { - case "remove": - triggerWatchEvent("delete", path); - break; - case "special": - // Rename - if (args.renameFrom) { - triggerWatchEvent("delete", args.renameFrom); - triggerWatchEvent("create", path); - } else if (args.copyFrom){ - triggerWatchEvent("create", path); - } - - break; - case "create": - triggerWatchEvent("create", path); - break; - case "mkdir": - triggerWatchEvent("create", path); - break; - case "write": - triggerWatchEvent("update", path); - break; - } - } - }); - - // Read a file content - vfs.addMethod('read', { - fallback: function(args, options) { - var path = localfs.urlToPath(options.url); - return localfs.read(path); - }, - after: function(args, results, options) { - - } - }); - - // Create a new file - vfs.addMethod('create', { - fallback: function(args, options) { - var path = localfs.urlToPath(options.url); - return localfs.create(path, args); - }, - after: function(args, results, options) { - localfs.autoSync(); - } - }); - - // Create a new directory - vfs.addMethod('mkdir', { - fallback: function(args, options) { - var path = localfs.urlToPath(options.url); - return localfs.mkdir(path, args); - }, - after: function(args, results, options) { - localfs.autoSync(); - } - }); - - // Write a file content - vfs.addMethod('write', { - fallback: function(args, options) { - var path = localfs.urlToPath(options.url); - return localfs.write(path, args); - }, - after: function(args, results, options) { - localfs.autoSync(); - } - }); - - // Rename a file - vfs.addMethod('special', { - fallback: function(args, options) { - // Rename - if (args.renameFrom) { - var to = localfs.urlToPath(options.url); - var from = args.renameFrom; - - if (!from) return Q.reject("need 'renameFrom'"); - return localfs.mv(from, to); - } - // Copy - else if (args.copyFrom) { - var to = localfs.urlToPath(options.url); - var from = args.copyFrom; - - if (!from) return Q.reject("need 'copyFrom'"); - return localfs.cp(from, to); - } else { - return Q.reject("Invalid special operations"); - } - }, - after: function(args, results, options) { - localfs.autoSync(); - } - }); - - // Remove a file or directory - vfs.addMethod('remove', { - fallback: function(args, options) { - var path = localfs.urlToPath(options.url); - return localfs.rm(path, args); - }, - after: function(args, results, options) { - localfs.autoSync(); - } - }); - - // List a directory - vfs.addMethod('listdir', { - fallback: function(args, options) { - var path = localfs.urlToPath(options.url); - return localfs.ls(path); - }, - after: function(args, results, options) { - - } - }); - - return vfs; -}); \ No newline at end of file diff --git a/client/core/box.js b/client/core/box.js deleted file mode 100644 index cfdf1687..00000000 --- a/client/core/box.js +++ /dev/null @@ -1,20 +0,0 @@ -define([ - 'hr/promise', - 'hr/hr', - 'models/box', - 'core/search', - 'core/collaborators' -], function (Q, hr, Codebox, search, collaborators) { - // Current box - var box = new Codebox(); - - // Bind collaborators changement - box.on("box:users:add", function(e) { - collaborators.add(e.data); - }); - box.on("box:users:remove", function(e) { - collaborators.remove(collaborators.getById(e.data.userId)); - }); - - return box; -}); \ No newline at end of file diff --git a/client/core/collaborators.js b/client/core/collaborators.js deleted file mode 100644 index 7de8e885..00000000 --- a/client/core/collaborators.js +++ /dev/null @@ -1,19 +0,0 @@ -define([ - 'hr/utils', - 'hr/hr', - 'collections/users', - 'utils/alerts' -], function (_, hr, Users, alerts) { - // Collection for all current collaborators - var collaborators = new Users(); - - collaborators.on("add", function(user) { - alerts.show(user.get("name")+" just joined the workspace", 5000); - }); - - collaborators.on("remove", function(user) { - alerts.show(user.get("name")+" just left the workspace", 5000); - }); - - return collaborators; -}); \ No newline at end of file diff --git a/client/core/commands/menu.js b/client/core/commands/menu.js deleted file mode 100644 index 9c4d8557..00000000 --- a/client/core/commands/menu.js +++ /dev/null @@ -1,50 +0,0 @@ -define([ - 'hr/utils', - 'hr/hr', - 'views/commands/menubar', - 'core/box', - 'core/panels', - 'core/tabs', - 'core/session', - 'core/localfs', - 'core/settings' -], function (_, hr, MenubarView, box, panels, tabs, session, localfs, settings) { - // Collection for all menu commands - var menu = new MenubarView(); - - menu.register("view", { - title: "View", - position: 5 - }).menuSection({ - 'id': "themes.settings", - 'category': "View", - 'title': "Settings", - 'description': "Open Theme and View Settings", - 'offline': false, - 'action': function() { - settings.open("themes"); - } - }).menuSection([ - panels.panelsCommand - ]).menuSection([ - tabs.layoutCommand - ]); - - menu.register("file", { - title: "File", - position: 0 - }).menuSection([{ - 'id': "quit", - 'category': "Application", - 'title': "Quit", - 'description': "Close Current Session", - 'shortcuts': [ - "alt+q" - ], - 'action': session.exit - }], { - 'position': 1000 - }); - - return menu; -}); \ No newline at end of file diff --git a/client/core/commands/palette.js b/client/core/commands/palette.js deleted file mode 100644 index fa426d07..00000000 --- a/client/core/commands/palette.js +++ /dev/null @@ -1,26 +0,0 @@ -define([ - 'views/commands/palette', - 'core/commands/toolbar', - 'core/search' -], function (PaletteView, commands, search) { - - var palette = new PaletteView({ - searchHandler: _.bind(search.query, search) - }); - - commands.register("palette.toggle", { - title: "Palette", - description: "Toggle Command Palette", - icons: { - 'default': "search", - }, - position: 0, - shortcuts: [ - "mod+shift+p", "alt+s" - ] - }, function() { - palette.toggle(); - }); - - return palette; -}); \ No newline at end of file diff --git a/client/core/commands/statusbar.js b/client/core/commands/statusbar.js deleted file mode 100644 index 7ec36f6d..00000000 --- a/client/core/commands/statusbar.js +++ /dev/null @@ -1,20 +0,0 @@ -define([ - 'hr/utils', - 'hr/hr', - 'views/commands/statusbar' -], function (_, hr, StatusbarView) { - // Collection for all statusbar commands - var statusbar = new StatusbarView(); - - // Feedback - statusbar.register("statusbar.sendfeedback", { - title: "Send Feedback", - position: 5, - offline: false, - search: false - }, function() { - window.open("https://github.com/FriendCode/codebox/issues"); - }); - - return statusbar; -}); \ No newline at end of file diff --git a/client/core/commands/toolbar.js b/client/core/commands/toolbar.js deleted file mode 100644 index 0fe133e3..00000000 --- a/client/core/commands/toolbar.js +++ /dev/null @@ -1,11 +0,0 @@ -define([ - 'hr/utils', - 'hr/hr', - 'views/commands/toolbar', - 'core/search', -], function (_, hr, CommandsToolbar, search) { - // Collection for all toolbar commands - var commands = new CommandsToolbar(); - - return commands; -}); \ No newline at end of file diff --git a/client/core/debug/breakpoints.js b/client/core/debug/breakpoints.js deleted file mode 100644 index 55485fcc..00000000 --- a/client/core/debug/breakpoints.js +++ /dev/null @@ -1,47 +0,0 @@ -define([ - "hr/hr", - "hr/utils" -], function(hr, _) { - - var Breakpoints = hr.Class.extend({ - initialize: function() { - Breakpoints.__super__.initialize.apply(this, arguments); - - // map filename -> array of int - this.breakpoints = {}; - }, - - // Signal change for a breakpoint - signalChange: function(change, path, line) { - this.trigger("change:"+change, { - 'change': change, - 'path': path, - 'line': line - }); - }, - - // Return all breakpoints - all: function() { - return _.clone(this.breakpoints); - }, - - // Get breakpoints for a file - getFileBreakpoints: function(path) { - return this.breakpoints[path] || []; - }, - - // When breakpoints changed for a file - setFileBreakpoints: function(path, breakpoints) { - var oldBreakpoints = this.breakpoints[path] || []; - this.breakpoints[path] = _.clone(breakpoints); - - var added = _.difference(this.breakpoints[path], oldBreakpoints); - var removed = _.difference(oldBreakpoints, this.breakpoints[path]); - - _.each(added, _.partial(_.bind(this.signalChange, this), "add", path)); - _.each(removed, _.partial(_.bind(this.signalChange, this), "remove", path)); - } - }); - - return Breakpoints; -}); \ No newline at end of file diff --git a/client/core/debug/manager.js b/client/core/debug/manager.js deleted file mode 100644 index 307d5a35..00000000 --- a/client/core/debug/manager.js +++ /dev/null @@ -1,60 +0,0 @@ -define([ - "hr/hr", - "hr/promise", - "core/debug/session", - "core/debug/breakpoints" -], function(hr, Q, DebuggerSession, DebuggerBreakpoints) { - - var Debugger = hr.Class.extend({ - initialize: function(options) { - Debugger.__super__.initialize.apply(this, arguments); - - // Active debugger - this.activeDebugger = null; - - // Debugegr running - this.state = false; - - // Current breakpoints - this.breakpoints = new DebuggerBreakpoints(); - }, - - // Open a debugger session - open: function() { - if (this.isActive()) { - // already an active debugger -> close it - return this.activeDebugger.close() - .then(_.bind(function() { - return this.open(); - }, this)); - } - - this.activeDebugger = new DebuggerSession(); - this.trigger("state", true); - - this.listenTo(this.activeDebugger, "close", function() { - this.activeDebugger = null; - this.trigger("state", false); - this.trigger("position", null); - }); - this.listenTo(this.activeDebugger, "position", function(position) { - this.trigger("position", position); - }); - - return Q(this.activeDebugger); - }, - - // Return if debug is active - isActive: function(st) { - return this.activeDebugger != null; - }, - - // Get current debug position - getPosition: function() { - if (!this.isActive()) return null; - return this.activeDebugger.position; - } - }); - - return new Debugger(); -}); \ No newline at end of file diff --git a/client/core/debug/session.js b/client/core/debug/session.js deleted file mode 100644 index 9de9b077..00000000 --- a/client/core/debug/session.js +++ /dev/null @@ -1,198 +0,0 @@ -define([ - "hr/hr", - "hr/promise", - "core/backends/rpc" -], function(hr, Q, rpc) { - - var DebuggerSession = hr.Class.extend({ - initialize: function(options) { - DebuggerSession.__super__.initialize.apply(this, arguments); - - // Session id for this debugger - this.id = null; - - // Breakpoints - this._breakpoints = []; - - // Position - this.position = null; - }, - - // Initialize the debugger - init: function(args) { - var that = this; - return rpc.execute("debug/init", args) - .then(function(dbg) { - that.id = dbg.id; - that.trigger("update:init"); - }); - }, - - // Close debugger - close: function() { - var that = this; - if (!that.id) return Q.reject(new Error("Session not yet initialized")); - - return this.execute("close") - .then(function() { - that.id = null; - that.trigger("close"); - that.stopListening(); - that.off(); - }); - }, - - // Execute a RPC requests - execute: function(method, args, options) { - var that = this; - options = _.defaults(options || {}, { - error: true - }); - - return rpc.execute("debug/"+method, _.extend(args || {}, { - 'id': this.id - })) - .then(function(data) { - return data; - }, - function(err) { - if (options.error) that.trigger("error", err); - return Q.reject(err); - }); - }, - - // Get locals - locals: function() { - return this.execute("locals"); - }, - - // Get breakpoints - breakpoints: function() { - var that = this; - - return this.execute("breakpoints") - .then(function(list) { - that._breakpoints = list; - return list; - }); - }, - - // Get backtrace - backtrace: function() { - return this.execute("backtrace") - .then(_.bind(function(trace) { - this.position = _.last(trace); - this.trigger("position", this.position); - - return trace; - }, this)); - }, - - // Get a breapoint id from its location - getBreakpoint: function(location) { - return _.find(this._breakpoints, function(point) { - return point.filename == location.path && point.line == location.line; - }); - }, - - // Add a breakpoint - breakpointAdd: function(args) { - var that = this; - return this.execute("breakpoint/add", args) - .then(function(point) { - that.trigger("update:breakpoints:add"); - return point; - }); - }, - - // Remove a breakpoint - breakpointRemove: function(num) { - var that = this; - - return this.execute("breakpoint/clear", { - 'num': num - }) - .then(function(point) { - that.trigger("update:breakpoints:clear"); - return point; - }); - }, - - // Start - start: function(arg) { - var that = this; - return this.execute("start", { - 'arg': arg - }) - .then(function(output) { - that.trigger("log", output); - that.trigger("update:start"); - }); - }, - - // Stop - stop: function() { - var that = this; - return this.execute("stop") - .then(function(output) { - that.trigger("log", output); - that.trigger("update:stop"); - }); - }, - - // Next - next: function() { - var that = this; - return this.execute("next") - .then(function(output) { - that.trigger("log", output); - that.trigger("update:next"); - }); - }, - - // Continue - cont: function() { - var that = this; - return this.execute("cont") - .then(function(output) { - that.trigger("log", output); - that.trigger("update:cont"); - }); - }, - - // Restart - restart: function() { - var that = this; - return this.execute("restart") - .then(function(output) { - that.trigger("log", output); - that.trigger("update:restart"); - }); - }, - - // Eval code - eval: function(code) { - var that = this; - - var handle = function(type, data) { - that.trigger("update:eval:"+type); - return { - 'type': type, - 'content': data.message || data - }; - }; - - return this.execute("eval", { - 'code': code - }, { - 'error': false - }) - .then( - _.partial(handle, "log"), - _.partial(handle, "error") - ); - }, - }); - - return DebuggerSession; -}); \ No newline at end of file diff --git a/client/core/files.js b/client/core/files.js deleted file mode 100644 index 510016b4..00000000 --- a/client/core/files.js +++ /dev/null @@ -1,255 +0,0 @@ -define([ - 'hr/promise', - 'hr/utils', - 'hr/hr', - 'models/file', - 'collections/files', - 'core/user', - 'core/box', - 'core/tabs', - 'core/settings', - 'utils/dialogs', - 'views/tabs/file', - 'views/files/base', - 'views/files/tab' -], function(Q, _, hr, File, Files, user, box, tabs, settings, dialogs, FileTab) { - var logging = hr.Logger.addNamespace("files"); - - // Settings for files manager - var settings = settings.add({ - 'namespace': "files", - 'title': "Files", - 'fields': {} - }); - var userSettings = user.settings("files"); - - // Recent files - var recentFiles = new Files(); - recentFiles.on("add", function() { - // Limit collection size - if (recentFiles.size() > 20) recentFiles.shift(); - }); - - // Active files - var activeFiles = new Files(); - - // Files handlers map - var handlers = {}; - - // Restorer for tabs - tabs.addRestorer("file", function(tabInfos) { - var parts = tabInfos.id.split(":"); - var handlerId = parts[0]; - var path = parts.slice(1).join(":"); - - var newFile = path.indexOf("temporary") == 0; - if (!newFile) { - return openFile(path.replace("file://", "")) - .then(function() { - return tabs.getById(tabInfos.id); - }); - } - - return null; - }); - - // Add handler - var addHandler = function(handlerId, handler) { - if (!handler - || !handlerId - || !handler.name - || !handler.valid - || (!handler.View && !handler.open)) { - throw "Invalid files handler format"; - } - - handler = _.defaults(handler, { - // Mark this file as active when open with - 'setActive': false, - - // Fallback when no correct handler - 'fallback': false, - - // Priority of this handler - 'position': 10 - }); - - handler.id = handlerId; - - if (handler.View) { - handler.open = function(file, fileOptions) { - var path = file.path(); - var uniqueId = handler.id+":"+file.syncEnvId(); - - // Add files as open - if (handler.setActive) activeFiles.add(file); - - // Add new tab - var tab = tabs.add(FileTab, { - "model": file, - "handler": handler, - 'fileOptions': fileOptions - }, { - "uniqueId": uniqueId, - "type": "file", - }); - - // Focus tab -> set active file - tab.on("tab:state", function(state) { - if (state) box.setActiveFile(file); - }); - - // Close tab -> close active file - tab.on("tab:close", function(state) { - if (handler.setActive) activeFiles.remove(file); - }); - - tab.setFileOptions(fileOptions); - }; - } - - // Add settings - settings.setField(handlerId, { - 'label': handler.name, - 'type': "checkbox", - 'default': true - }); - - // Register handler - handlers[handlerId] = handler; - - return handlers[handlerId]; - }; - - // Get handler for a file - var getHandlers = function(file) { - return _.chain(handlers) - .filter(function(handler) { - return userSettings.get(handler.id, true) && handler.valid(file); - }) - .sortBy(function(handler) { - return handler.position || 10; - }) - .value(); - }; - - // get fallback handlers for a file - var getFallbacks = function(file) { - return _.filter(handlers, function(handler) { - return userSettings.get(handler.id, true) && handler.fallback == true; - }); - }; - - // Open file with handler - var openFileHandler = function(handler, file, fileOptions) { - // Add to recent files - if (!file.isNewfile()) recentFiles.add(file); - - // Options for the file handler - fileOptions = _.defaults(fileOptions || {}, { - line: null, - pattern: null - }); - - return Q(handler.open(file, fileOptions)).then(function() { - box.setActiveFile(file); - }); - }; - - // Select to open a file with any handler - var openFileWith = function(file, fileOptions) { - var choices = {}; - _.each(handlers, function(handler) { - choices[handler.id] = handler.name; - }); - - if (_.size(choices) == 0) { - return Q.reject(new Error("No handlers for this file")); - } - - return dialogs.select("Can't open this file", "Sorry, No handler has been found to open this file. Try to find and install an add-on to manage this file or select one of the following handlers:", choices).then(function(value) { - var handler = handlers[value]; - return Q(openFileHandler(handler, file, fileOptions)); - }); - }; - - // Open a file - var openFile = function(file, options) { - options = _.defaults({}, options || {}, { - 'userChoice': null, - 'useFallback': true, - 'line': null - }); - - // Options for the file handler - var fileOptions = _.pick(options, ["line", "pattern"]); - - if (_.isString(file)) { - var nfile = new File({ - 'codebox': box - }); - return nfile.getByPath(file).then(function() { - return openFile(nfile, options); - }); - } - - var possibleHandlers = getHandlers(file); - - // Get fallbacks - if (_.size(possibleHandlers) == 0 && options.useFallback) { - possibleHandlers = getFallbacks(); - } - - // All choices - if (_.size(possibleHandlers) == 0) { - return openFileWith(file, fileOptions); - } - - if (_.size(possibleHandlers) == 1 || (options.userChoice != true)) { - return Q(openFileHandler(_.first(possibleHandlers), file, fileOptions)); - } - - var choices = {}; - _.each(possibleHandlers, function(handler) { - choices[handler.id] = handler.name; - }) - - if (_.size(choices) == 0) { - return Q.reject(new Error("No handlers for this file")); - } - - return dialogs.select("Open with...", "Select one of the following handlers to open this file:", choices).then(function(value) { - var handler = handlers[value]; - return Q(openFileHandler(handler, file, fileOptions)); - }); - }; - - // Open a new file - var openNew = function(name, content, options) { - name = name || "untitled"; - - // Create a temporary file - var f = new File({ - 'newFileContent': content || "", - 'codebox': box - }, { - 'name': name, - 'size': 0, - 'mtime': 0, - 'mime': "text/plain", - 'href': location.protocol+"//"+location.host+"/vfs/"+name, - 'exists': false - }); - - return openFile(f, options); - }; - - return { - 'addHandler': addHandler, - 'getHandlers': getHandlers, - 'open': openFile, - 'openNew': openNew, - 'recent': recentFiles, - 'active': activeFiles - }; -}); \ No newline at end of file diff --git a/client/core/globals.js b/client/core/globals.js deleted file mode 100644 index 2912459c..00000000 --- a/client/core/globals.js +++ /dev/null @@ -1,7 +0,0 @@ -define(['require'], function (require) { - window.codebox = { - 'require': require - }; - - return window.codebox; -}); \ No newline at end of file diff --git a/client/core/localfs.js b/client/core/localfs.js deleted file mode 100644 index 00210a5a..00000000 --- a/client/core/localfs.js +++ /dev/null @@ -1,519 +0,0 @@ -define([ - 'hr/utils', - 'hr/hr', - 'utils/url', - 'vendors/filer', - 'core/operations', - 'utils/alerts', - 'collections/changes' -], function(_, hr, Url, Filer, operations, alerts, Changes) { - var logger = hr.Logger.addNamespace("localfs"); - - // Base folder for localfs - var base = "/"; - var _isInit = false; - var _syncIsEnable = false; - var _ignoredFiles = []; - var changes = new Changes(); - - // Constant mime type for a directory - var MIME_DIRECTORY = "inode/directory"; - - // Duration for sync (ms) - syncDuration = 1*60*1000; - - - // Create fs interface - var filer = new Filer(); - - var fsCall = function(method, args, context) { - if (!_syncIsEnable) return Q.reject(new Error("Offline synchronization is disabled")); - if (_.isUndefined(args)) args = []; - if (!_.isArray(args)) args = [args]; - - var d = Q.defer(); - args.push(function() { - if (arguments.length == 1) return d.resolve(arguments[0]); - d.resolve(arguments); - }); - args.push(function(err) { - logger.error("Error occurs: ", method.name, err); - d.reject(err); - }) - - try { - method.apply(context, args); - } catch(err) { - d.reject(err); - } - - return d.promise; - }; - - /* - * Init the localfs - */ - var initFs = function(baseDir) { - base = "/"+baseDir; - logger.log("base is", base); - return Q(); - }; - - /* - * Enable/Disable sync - */ - var enableSync = function(state) { - _syncIsEnable = state != undefined? state : true; - }; - - /* - * Set ignored files list - */ - var setIgnoredFiles = function(files) { - _ignoredFiles = files || []; - _ignoredFiles.push("/.git") - _ignoredFiles = _.compact(_ignoredFiles); - _ignoredFiles = _.uniq(_ignoredFiles); - _ignoredFiles = _.map(_ignoredFiles, function(p) { - if (p[0] != "/") p = "/"+p; - return p; - }); - }; - - var prepareFs = function() { - if (_isInit) return Q(); - return fsCall(filer.init, { - persistent: true, - size: 10 * 1024 * 1024 - }, filer) - .then(function() { - logger.log("fs is ready"); - _isInit = true; - return Q(); - }); - }; - - var needFsReady = function(fn) { - return function() { - var args = arguments; - return prepareFs().then(function() { - return fn.apply(fn, args); - }); - }; - } - - /* - * Adapt path - */ - var adaptPath = function(path) { - path = base+path; - path = path.replace("//", "/"); - return path; - } - - /* - * Convert a vfs url in a path - */ - var urlToPath = function(url) { - var basePath = window.location.pathname; - basePath = basePath.substring(0, basePath.lastIndexOf("/")+1) + "vfs/"; - var path = url.substr(basePath.length-1); - if (path.length == 0) path = '/'; - if (path[0] != '/') path = "/" + path; - return path; - }; - - /* - * Test if path is ignored files - */ - var isIgnoredFile = function(path) { - return _.reduce(_ignoredFiles, function(state, ignoredPath) { - if (state) return state; - if (path.indexOf(ignoredPath) == 0) return true; - }, false); - }; - - /* - * Return informations about a fileentry - */ - var getEntryInfos = needFsReady(function(fEntry) { - return fsCall(fEntry.getMetadata, [], fEntry).then(function(metadata) { - var path = fEntry.fullPath.replace(base, "/").replace("//", "/"); - var url = location.protocol+"//"+location.host+"/vfs"+path; - - if (fEntry.isDirectory) url = url + "/"; - - return { - "name": fEntry.name, - "size": metadata.size, - "mtime": metadata.modificationTime.getTime(), - "mime": fEntry.isDirectory ? MIME_DIRECTORY : "application/octet-stream", - "href": url, - "exportUrl": fEntry.toURL(), - "offline": true, - '_fullPath': path - }; - }) - }); - - /* - * List a directory - */ - var listDir = needFsReady(function(path, adapt) { - path = (adapt == false) ? path : adaptPath(path); - - logger.log("ls:", path); - return fsCall(filer.ls, path, filer).then(function(entries) { - return Q.all(_.map(entries, function(entry) { - return getEntryInfos(entry); - })) - }).then(function(entries) { - return entries; - }, function(err) { - logger.error("ls:", err); - }); - }); - - /* - * Create a file - */ - var createFile = needFsReady(function(path) { - path = adaptPath(path); - logger.log("create:", path); - return fsCall(filer.create, [path, true], filer); - }); - - /* - * Write file - */ - var writeFile = needFsReady(function(path, data) { - path = adaptPath(path); - logger.log("write:", path); - return fsCall(filer.write, [path, { - 'data': data || "" - }], filer); - }); - - /* - * Open a file - */ - var openFile = needFsReady(function(path) { - path = adaptPath(path); - logger.log("open:", path); - return fsCall(filer.getEntry, [path], filer).then(function(fEntry) { - return getEntryInfos(fEntry); - }) - }); - - /* - * Read a file - */ - var readFile = needFsReady(function(path) { - path = adaptPath(path); - logger.log("read:", path); - return fsCall(filer.open, [path], filer).then(function(file) { - var d = Q.defer(); - - var reader = new FileReader(); - reader.onerror = function(err) { - d.reject(err); - }; - reader.onload = function(e) { - d.resolve(reader.result); - }; - reader.readAsText(file); - - return d.promise; - }); - }); - - /* - * Create a file - */ - var createDirectory = needFsReady(function(path) { - path = adaptPath(path); - logger.log("mkdir:", path); - return fsCall(filer.mkdir, [path, false], filer); - }); - - /* - * Move a file - */ - var move = needFsReady(function(from, to) { - from = adaptPath(from); - to = adaptPath(to); - - logger.log("move:", from, "to", to); - return fsCall(filer.mv, [from, '.', to], filer); - }); - - /* - * Copy a file - */ - var copy = needFsReady(function(from, to) { - from = adaptPath(from); - to = adaptPath(to); - - logger.log("copy:", from, "to", to); - return fsCall(filer.cp, [from, '.', to], filer); - }); - - /* - * Remove a file or directory - */ - var remove = needFsReady(function(path, adapt) { - path = (adapt == false) ? path : adaptPath(path); - - logger.log("remove:", path); - return fsCall(filer.rm, [path], filer); - }); - - /* - * Return changes - */ - var getChanges = needFsReady(function() { - var File = require("models/file"); - var box = require("core/box"); - changes.reset([]); - - if (!_syncIsEnable) return Q(changes); - - var addChange = function(path, type, args) { - if (isIgnoredFile(path)) { - return; - } - logger.log("change:",type,path); - changes.add(_.extend(args || {}, { - 'path': path, - 'time': Date.now(), - 'type': type || "M" - })); - } - - var getDirChanges = function(path) { - var localEntries, boxEntries, currentEntryInfos, fp; - if (isIgnoredFile(path)) { - return Q(); - } - - logger.log("get changes in:", path); - - // File in the workspace - fp = new File(); - - return openFile(path).then(function(infos) { - return listDir(path); - }).then(function(entries) { - // Entry in the browser - localEntries = entries; - - // Get file on the workspace - return fp.getByPath(path).fail(function() { - return Q(); - }); - }).then(function() { - if (fp.isDirectory()) { - return fp.listdir(); - } - return Q([]); - }).then(function(entries) { - // Entries on the boxes - boxEntries = entries; - }).then(function() { - // Eliminate old useless entries - return Q.all(_.map(boxEntries, function(boxFile) { - if (isIgnoredFile(boxFile.path())) return Q(); - - var localEntry = _.find(localEntries, function(localEntry) { - return localEntry.name == boxFile.get("name"); - }); - - // File don't exists and box file older than current directory - if (!localEntry && boxFile.get("mtime") < currentEntryInfos.mtime) { - // -> Remove the file on the box - addChange(boxFile.path(), "remove"); - } - - // Do nothing - return Q(); - })); - }).then(function() { - // Update entries and create new entries - return Q.all(_.map(localEntries, function(localEntry) { - var entryIsDir = localEntry.mime == MIME_DIRECTORY; - var boxFile = _.find(boxEntries, function(boxFile) { - return localEntry.name == boxFile.get("name"); - }); - - if (!boxFile) { - // Create file - if (!entryIsDir) { - addChange(localEntry._fullPath, "create"); - } else { - addChange(localEntry._fullPath, "mkdir"); - } - } else if (!entryIsDir && boxFile.get("mtime") < localEntry.mtime) { - // Check modification - return readFile(localEntry._fullPath).then(function(content) { - return boxFile.read().then(function(vfsContent) { - if (vfsContent == content) { - // Same content - return Q(); - } - addChange(localEntry._fullPath, "write", { - 'content': content - }); - }) - }); - } - - if (entryIsDir) { - return getDirChanges(localEntry._fullPath); - } - - // Do nothing - return Q(); - })); - }).fail(function(err) { - logger.error("Error during sync: ", err); - }); - }; - - return operations.start("files.sync.changes", function(op) { - return getDirChanges("/").then(function() { - return Q(changes); - }); - }, { - title: "Calculating Offline Changes" - }); - }); - - /* - * Sync a file in the box fs with the local fs - * - * this will download the files and saved them in the localfs - */ - var syncFileBoxToLocal = needFsReady(function() { - var box = require("core/box"); - - var doSync = function(fp) { - var path = fp.path(); - if (isIgnoredFile(path)) return Q(); - - logger.log("sync:box->local:", path); - - if (fp.isDirectory()) { - // Create the directory - return createDirectory(path).then(function() { - // List subfiles - return fp.listdir(); - }).then(function(files) { - // Recursively sync files and directory - return Q.all(_.map(files, function(f) { - return doSync(f); - })); - }); - } else { - // Read file content - return fp.read().then(function(content) { - // Write file content - return writeFile(path, content); - }); - } - }; - return operations.start("files.sync.download", function(op) { - logger.warn("Start sync: box->local"); - - return listDir("/", false).then(function(rootFiles) { - return Q.all(_.map(rootFiles, function(fp) { - return remove("/"+fp.name, false); - })); - }).then(function() { - return doSync(box.root); - }, function() { - return doSync(box.root) - }).then(function() { - changes.reset([]); - logger.warn("Finished sync: box->local"); - }); - }, { - title: "Updating Offline Cache" - }); - }); - - /* - * Global sync: - * -> if never sync: download everything - * -> if already sync: upload changes and download last changes - */ - var sync = needFsReady(function(options) { - options = _.defaults({}, options || {}, { - - }); - - var previousChanges = changes.size(); - - if (hr.Offline.isConnected()) { - var endT, startT = Date.now(); - return openFile("/").then(function(infos) { - return getChanges(); - }, function() { - return createDirectory("/"); - }).then(function() { - if (changes.size() > 0) { - if (changes.size() == previousChanges) return Q.reject(new Error("Offline changes not synced")); - alerts.show(changes.size()+" changes made offline need to be synced manually", 5000); - return Q.reject(new Error("Offline changes not synced")); - } - return syncFileBoxToLocal(); - }).then(function() { - //Calcul duration - endT = Date.now(); - syncDuration = _.max([endT - startT, 5000]); - updateAutoSync(); - return syncDuration; - }, function(err) { - logger.error("Sync error:", err); - }); - } else { - return Q.reject(new Error("Can't synchronize when offline")); - } - }); - - /* - * Auto sync allow to resync the localfs every interval - */ - var autoSync = null; - var updateAutoSync = function() { - syncDuration = _.max([syncDuration, 5*60*1000]); - logger.log("sync took ", syncDuration/1000,"seconds"); - autoSync = _.throttle(function() { - sync(); - }, 2*syncDuration); - }; - updateAutoSync(); - - return { - 'changes': changes, - 'urlToPath': urlToPath, - 'init': initFs, - 'ls': listDir, - 'create': createFile, - 'mkdir': createDirectory, - 'write': writeFile, - 'read': readFile, - 'mv': move, - 'cp': copy, - 'rm': remove, - 'reset': syncFileBoxToLocal, - 'sync': sync, - 'autoSync': function() { - return autoSync(); - }, - 'enableSync': enableSync, - 'isSyncEnabled': function() { return _syncIsEnable; }, - 'filer': filer, - 'syncDuration': syncDuration, - 'setIgnoredFiles': setIgnoredFiles - }; -}); \ No newline at end of file diff --git a/client/core/operations.js b/client/core/operations.js deleted file mode 100644 index 93892c0d..00000000 --- a/client/core/operations.js +++ /dev/null @@ -1,6 +0,0 @@ -define([ - 'views/operations/manager' -], function (Operations) { - var operations = new Operations(); - return operations; -}); \ No newline at end of file diff --git a/client/core/panels.js b/client/core/panels.js deleted file mode 100644 index b3aa8e03..00000000 --- a/client/core/panels.js +++ /dev/null @@ -1,6 +0,0 @@ -define([ - 'views/panels/manager' -], function (PanelsView) { - var panels = new PanelsView(); - return panels; -}); \ No newline at end of file diff --git a/client/core/search.js b/client/core/search.js deleted file mode 100644 index fb666991..00000000 --- a/client/core/search.js +++ /dev/null @@ -1,121 +0,0 @@ -define([ - 'hr/hr', - 'hr/dom', - 'hr/utils', - 'hr/promise', - 'models/command', - 'core/user', - 'core/settings' -],function(hr, $, _, Q, Command, user, settings) { - var logging = hr.Logger.addNamespace("search"); - - var Search = hr.Class.extend({ - defaults: {}, - - // Constructor - initialize: function(){ - Search.__super__.initialize.apply(this, arguments); - - // Search handlers - this.handlers = {}; - - // Settings - this.settings = settings.add({ - 'namespace': "search", - 'title': "Search", - 'fields': {} - }); - - return this; - }, - - /* - * Add a search handler - * @name: name for the search handler - * @getter: method which returns a promise with results - */ - handler: function(infos, getter) { - if (!infos.id || !infos.title) { - throw new Error("Need 'id' and 'title' to define a search handler"); - } - - // Define handler - this.handlers[infos.id] = _.defaults({ - 'getter': getter - }, infos, {}); - - // Define settings - this.settings.setField(infos.id, { - 'label': infos.title, - 'type': "checkbox", - 'default': true - }); - - logging.log("add search handler", infos.id); - - return this; - }, - - /* - * Normalize result - */ - normResult: function(handler, result) { - if (result instanceof Command) { - return result; - } else { - return new Command({}, _.defaults(result, { - 'category': handler.title - })); - } - }, - - /* - * Search by query - */ - query: function(query) { - var that = this; - var errors = []; - var d = Q.defer(); - var n = _.size(this.handlers), i = 0; - - _.each(this.handlers, function(handler, name) { - var done = function(results) { - i = i + 1; - if (results) { - d.notify({ - 'category': { - 'title': handler.title - }, - 'results': _.chain(results) - .map(_.partial(that.normResult, handler)) - .value(), - 'query': query - }); - } - if (i == n) { - if (errors.length == 0) { - d.resolve(n); - } else { - d.reject(errors); - } - } - }; - - if (!user.get("settings.search."+name, true)) return done(); - - Q() - .then(function() { - return handler.getter(query); - }) - .then(done, function(err) { - errors.push(err); - return done(); - }); - }); - - return d.promise; - } - }); - - return (new Search()); -}); \ No newline at end of file diff --git a/client/core/search/addons.js b/client/core/search/addons.js deleted file mode 100644 index d6f9c036..00000000 --- a/client/core/search/addons.js +++ /dev/null @@ -1,111 +0,0 @@ -define([ - 'hr/promise', - 'hr/utils', - 'hr/hr', - 'models/command', - 'collections/addons', - 'core/box', - 'core/addons', - 'core/search', - 'core/settings', - 'utils/string' -], function(Q, _, hr, Command, Addons, box, addons, search, settings, string) { - - var addonsSettings = settings.add({ - 'namespace': "manager", - 'title': "Addons", - 'defaults': { - 'registry': "https://api.codebox.io" - }, - 'fields': { - 'registry': { - 'label': "Registry", - 'type': "text" - } - } - }); - - // Filter a collection fo addons by a query to search for - var filterAddonsByQuery = function(_addons, query) { - return _addons.filter(function(addon) { - var text = [ - addon.get("name"), - addon.get("description") - ].join(" "); - return (string.score("Add-ons", query) > 0 - || string.score(text, query) > 0); - }); - }; - - // Transform an addon to a basic command - var addonToCommand = function(preText, addon, callback) { - return { - 'category': "Add-ons", - 'title': preText+" "+addon.get("name"), - 'label': addon.get("version")+ " - "+addon.get("author.name"), - 'icons': { - 'search': "puzzle-piece" - }, - 'offline': false, - 'action': callback - }; - }; - - // Transform an addon to an install command - var addonToInstallCommand = function(addon) { - var preText = "Install"; - if (addons.isInstalled(addon)) { - if (!addons.isUpdated(addon)) { - preText = "Update"; - } else { - return null; - } - } - return addonToCommand(preText, addon, function() { - return Command.run("addons.install", addon.get("git")); - }); - }; - - // Transform an addon to an uninstall command - var addonToUninstallCommand = function(addon) { - if (addons.isDefault(addon)) return null; - return addonToCommand("Uninstall", addon, function() { - return Command.run("addons.uninstall", addon.get("name")); - }); - }; - - // Search for add-ons to uninstall - search.handler({ - 'id': "addons:uninstall", - 'title': "Uninstall Add-ons" - }, function(query) { - if (!query) return []; - - return _.chain( - filterAddonsByQuery(addons, query) - ) - .map(addonToUninstallCommand) - .compact() - .value(); - }); - - // Search for add-ons to install/update - search.handler({ - 'id': "addons:install", - 'title': "Install Add-ons" - }, function(query) { - if (!query) return []; - - var addonsIndex = new Addons(); - - return addonsIndex.loadFromIndex(addonsSettings.user.get("registry")) - .then(function() { - return _.chain( - filterAddonsByQuery(addonsIndex, query) - ) - .map(addonToInstallCommand) - .compact() - .value(); - }); - }); -}); \ No newline at end of file diff --git a/client/core/search/code.js b/client/core/search/code.js deleted file mode 100644 index 8ca5a855..00000000 --- a/client/core/search/code.js +++ /dev/null @@ -1,155 +0,0 @@ -define([ - 'hr/promise', - 'hr/utils', - 'hr/hr', - 'models/command', - 'core/commands/menu', - 'core/backends/rpc', - 'core/search', - 'core/files', - 'utils/dialogs' -], function(Q, _, hr, Command, menu, rpc, search, files, dialogs) { - var logging = hr.Logger.addNamespace("codeSearch"); - var OPTIONS = [ - 'query', 'path', 'casesensitive', 'replacement', 'pattern', 'maxresults', - 'wholeword', 'regexp', 'replaceAll' - ]; - - - // Normalize results as a buffer - var normResults = function(results) { - // Header - var buffer = 'Searching 1 file for "'+results.options.query+'"'; - if (results.options.casesensitive) buffer += " (case sensitive)" - buffer += '\n\n'; - - _.each(results.files, function(lines, path) { - buffer += path+"\n"; - _.each(lines, function(line) { - buffer += line.line+" "+line.content+"\n"; - }); - buffer += '\n\n'; - }); - - // Footer - buffer += results.matches+" matches across "+_.size(results.files)+" files"; - - return buffer; - }; - - // Do a basic search - var searchCode = function(options) { - options = _.extend({}, options || {}); - return rpc.execute("search/code", _.pick(options, OPTIONS)); - }; - - - - var searchCommandHandler = function(title, fields, forceOptions) { - return function(args) { - if (_.isString(args)) args = {'query': args}; - args = _.defaults(args || {}, {}); - - var doSearch = function(_args) { - return searchCode(_.extend(_args, forceOptions || {})) - .then(function(results) { - return normResults(results); - }, function(err) { - logging.error("error", err); - return "Error during search: "+(err.message || err); - }) - .then(function(buffer) { - return files.openNew("Find Results", buffer); - }); - }; - - if (!args.query) { - return dialogs.fields(title, fields, args) - .then(doSearch); - } - - return doSearch(args); - } - }; - - - // Command search code - var commandSearch = Command.register("code.search", { - title: "Find in Files", - category: "Find", - shortcuts: [ - "mod+shift+f" - ], - action: searchCommandHandler("Find in Files", { - 'query': { - 'label': "Find", - 'type': "text" - }, - 'path': { - 'label': "Where", - 'type': "text" - }, - 'regexp': { - 'label': "Regular expression", - 'type': "checkbox" - }, - 'casesensitive': { - 'label': "Case sensitive", - 'type': "checkbox" - }, - 'wholeword': { - 'label': "Whole word", - 'type': "checkbox" - } - }) - }); - - // Command replace code - var commandReplace = Command.register("code.replace", { - title: "Replace in Files", - category: "Find", - shortcuts: [], - action: searchCommandHandler("Find and Replace in Files", { - 'query': { - 'label': "Find", - 'type': "text" - }, - 'path': { - 'label': "Where", - 'type': "text" - }, - 'replacement': { - 'label': "Replace", - 'type': "text" - }, - 'regexp': { - 'label': "Regular expression", - 'type': "checkbox" - }, - 'casesensitive': { - 'label': "Case Sensitive", - 'type': "checkbox" - }, - 'wholeword': { - 'label': "Whole word", - 'type': "checkbox" - } - }, { - replaceAll: true - }) - }) - - - // Create find menu - menu.register("find", { - title: "Find", - position: 5 - }).menuSection([ - commandSearch, - commandReplace - ]); - - return { - search: searchCode - }; -}); \ No newline at end of file diff --git a/client/core/search/commands.js b/client/core/search/commands.js deleted file mode 100644 index fc38bff3..00000000 --- a/client/core/search/commands.js +++ /dev/null @@ -1,29 +0,0 @@ -define([ - 'hr/promise', - 'hr/utils', - 'hr/hr', - 'models/command', - 'core/search' -], function(Q, _, hr, Command, search) { - // Search for commands - search.handler({ - 'id': "commands", - 'title': "Command" - }, function(query) { - return Command.all.filter(function(command) { - return ( - // Only action - command.get("type") == "action" - - // Accept to be visible in search bar - && command.get("search") - - // Not disabled (offline, ...) - && !command.hasFlag("disabled") - - // Fit the current search - && (!query || command.textScore(query) > 0) - ); - }); - }); -}); \ No newline at end of file diff --git a/client/core/search/files.js b/client/core/search/files.js deleted file mode 100644 index d57fe684..00000000 --- a/client/core/search/files.js +++ /dev/null @@ -1,54 +0,0 @@ -define([ - 'hr/promise', - 'hr/utils', - 'hr/hr', - 'core/box', - 'core/search', - 'core/files' -], function(Q, _, hr, box, search, files) { - // Search for files - search.handler({ - 'id': "files", - 'title': "Files" - }, function(query) { - if (!query) return []; - - return box.searchFiles(query) - .then(function(data) { - return Q(_.map(data.files, _.bind(function(path) { - var filename = _.last(path.split("/")); - if (filename.length == 0) filename = path; - - return { - "title": path, - "icons": { - "search": "file-o" - }, - "action": _.bind(function() { - files.open(path); - }, this) - }; - }, this))); - }); - }); - - // Search for recent opned files - search.handler({ - 'id': "recentfiles", - 'title': "Recent Files" - }, function(query) { - return files.recent.map(function(file) { - return { - "category": "Recent Files", - "title": file.path(), - "position": 0, - "icons": { - "search": "file-o" - }, - "action": _.bind(function() { - files.open(file); - }, this) - }; - }); - }); -}); \ No newline at end of file diff --git a/client/core/search/tags.js b/client/core/search/tags.js deleted file mode 100644 index a26f4bb0..00000000 --- a/client/core/search/tags.js +++ /dev/null @@ -1,40 +0,0 @@ -define([ - 'hr/promise', - 'hr/utils', - 'hr/hr', - 'core/backends/rpc', - 'core/search', - 'core/files' -], function(Q, _, hr, rpc, search, files) { - var normalizeTag = function(tag) { - return { - "title": tag.name, - "label": tag.file, - "icons": { - "search": "code" - }, - "action": _.bind(function() { - files.open(tag.file, { - // Open content "/^ foo $/"" _> "foo" in editor - pattern: tag.pattern.slice(2, -2) - }); - }, this) - }; - }; - - // Search for files - search.handler({ - 'id': "tags", - 'title': "Tags" - }, function(query) { - if (!query) return []; - - return rpc.execute("codecomplete/get", { - 'query': query - }).then(function(data) { - return _.map(data.results, normalizeTag); - }, function() { - return Q([]); - }); - }); -}); \ No newline at end of file diff --git a/client/core/session.js b/client/core/session.js deleted file mode 100644 index 3d843db9..00000000 --- a/client/core/session.js +++ /dev/null @@ -1,66 +0,0 @@ -define([ - "hr/utils", - "hr/hr", - "core/user", - "core/box", - "core/addons", - "core/collaborators", - "core/backends/rpc", - "core/localfs" -], function(_, hr, user, box, addons, collaborators, rpc, localfs) { - // Extend template context - hr.Template.extendContext({ - 'session': { - 'user': user, - 'box': box, - 'addons': addons, - 'collaborators': collaborators - } - }); - - // Redefine check for connection status - hr.Offline.check = function() { - return rpc.execute("box/ping").then(function(data) { - hr.Offline.setState(data.ping == true); - if (!hr.Offline.isConnected()) { - return Q.reject(new Error("No connected")); - } - }, function() { - hr.Offline.setState(false); - }) - }; - - return { - // Prepare session - prepare: function() { - return hr.Offline.check().then(function() { - return box.status(); - }).then(function() { - return localfs.init(box.get("name")); - }); - }, - - // Start session - start: function(email, token) { - var that = this; - - return box.auth({ - 'email': email, - 'token': token - }, user).then(function() { - // Get installed addons - return addons.getInstalled(); - }).then(function() { - // Get collaborators - return collaborators.getCollaborators(); - }); - }, - - // Logout - exit: function() { - hr.Cookies.remove("email"); - hr.Cookies.remove("token"); - location.reload(); - } - }; -}); \ No newline at end of file diff --git a/client/core/settings.js b/client/core/settings.js deleted file mode 100644 index e92c973e..00000000 --- a/client/core/settings.js +++ /dev/null @@ -1,78 +0,0 @@ -define([ - 'hr/hr', - 'models/command', - 'core/user', - 'views/settings/base' -], function (hr, Command, user, SettingsPageView) { - - /* - * This module define a unify way - * to manage user settings. - */ - - var logging = hr.Logger.addNamespace("settings"); - - var settings = { - sections: {}, - - /* - * Define a new settings tab - * Tab: View for the tab - */ - add: function(Tab, options) { - var section, namespace; - if (!_.isFunction(Tab)) { - options = Tab; - Tab = SettingsPageView; - } - - var tab = new Tab(options); - - var namespace = tab.namespace || "main"; - - logging.log("add settings tab", namespace); - settings.sections[namespace] = tab; - - var defaults = options.defaults || {}; - var currentValues = user.get("settings."+namespace, {}); - currentValues = _.defaults(currentValues, defaults); - user.set("settings."+namespace, currentValues); - - return tab; - }, - - /* - * For all tabs - */ - each: function(callback, context) { - _.each(settings.sections, callback, context); - }, - - /* - * Save settings - */ - save: function() { - var data = {}; - this.each(function(tab) { - data[tab.namespace] = tab.submit(); - }); - return user.saveSettings(_.extend({}, user.get("settings"), data)); - }, - - /* - * Open a settings page - */ - open: function(page) { - Command.run("settings", page); - }, - - /* - * User settings - */ - user: function(namespace) { - return user.settings(namespace); - } - }; - - return settings; -}); \ No newline at end of file diff --git a/client/core/tabs.js b/client/core/tabs.js deleted file mode 100644 index 561e1ec6..00000000 --- a/client/core/tabs.js +++ /dev/null @@ -1,6 +0,0 @@ -define([ - 'views/tabs/manager' -], function (TabsView) { - var tabs = new TabsView(); - return tabs; -}); \ No newline at end of file diff --git a/client/core/themes.js b/client/core/themes.js deleted file mode 100644 index ff406837..00000000 --- a/client/core/themes.js +++ /dev/null @@ -1,161 +0,0 @@ -define([ - 'hr/hr', - 'hr/dom', - 'hr/utils', - 'utils/css', - 'core/settings', - 'core/user' -], function (hr, $, _, css, settings, user) { - var logger = hr.Logger.addNamespace("themes"); - - - // User settings - var userSettings = user.settings("themes"); - - // Map of themes - var currentTheme = null; - var themes = {}; - - // CSS dom - var $css = $("" ).appendTo($("body")); - }; - var resetCursor = _.partial(setCursor, null); - - var DropArea = hr.Class.extend({ - defaults: { - // View for this area - view: null, - - // Class when drop data - className: "dragover", - - // Draggable type - dragType: null, - - // Handler for drop - handler: null, - - // Constrain elastic - constrain: null - }, - - initialize: function() { - DropArea.__super__.initialize.apply(this, arguments); - var that = this; - - this.view = this.options.view; - this.$el = this.view.$el; - - this.dragType = this.options.dragType; - - this.$el.on(events["enter"], function(e) { - if (that.dragType.isDragging()) { - e.stopPropagation(); - that.dragType.enterDropArea(that); - that.$el.addClass("dragover"); - } - }); - - this.$el.on(events["leave"], function(e) { - that.$el.removeClass("dragover"); - that.dragType.exitDropArea(); - }); - - this.on("drop", function() { - that.$el.removeClass("dragover"); - }); - - if (this.options.handler) this.on("drop", this.options.handler); - } - }); - - var DraggableType = hr.Class.extend({ - initialize: function() { - DraggableType.__super__.initialize.apply(this, arguments); - - // Data transfered - this.data = null; - - // State - this.state = true; - - // Drop handler - this.drop = []; - }, - - // Toggle enable/disable drag and drop - toggle: function(st) { - this.state = st; - return this; - }, - - // Is currently dragging data - isDragging: function() { - return this.data != null; - }, - - // Get drop - getDrop: function() { - return (this.drop.length > 0)? this.drop[this.drop.length - 1] : null; - }, - - // Enter drop area - enterDropArea: function(area) { - this.drop.push(area); - }, - - // Exit drop area - exitDropArea: function() { - this.drop.pop(); - }, - - // Enable drag and drop in a object - enableDrag: function(options) { - var that = this, $document = $(document), $el, data; - - options = _.defaults(options || {}, { - // View to drag - view: null, - - // Element to drag - el: null, - - // Data to transfer - data: null, - - // Base drop area - baseDropArea: null, - - // Before dragging - start: null, - - // Cursor - cursor: "copy" - }); - if (options.el) $el = $(options.el); - if (options.view) $el = options.view.$el, data = options.view; - if (options.data) data = options.data; - - $el.on(events["start"], function(e) { - if (e.type == 'mousedown' && e.originalEvent.button != 0) return; - if (!that.state) return; - e.preventDefault(); - e.stopPropagation(); - - var dx, dy, hasMove = false; - - // origin mouse - var oX = e.pageX; - var oY = e.pageY; - - // origin element - var poX = $el.offset().left; - var poY = $el.offset().top; - - // element new position - var ex, ey, ew, eh; - ew = $el.width(); - eh = $el.height(); - - // Constrain element - var cw, ch, cx, cy; - - if (options.start && options.start() === false) return; - - that.drop = []; - if (options.baseDropArea) that.enterDropArea(options.baseDropArea); - that.data = data; - - var f = function(e) { - var _drop = that.getDrop(); - - dx = oX - e.pageX; - dy = oY - e.pageY; - - if (Math.abs(dx) > 20 || Math.abs(dy) > 20) { - if (!hasMove) { - setCursor(options.cursor); - $el.addClass("move"); - that.trigger("drag:start"); - } - hasMove = true; - } else { - return; - } - - ex = poX - dx; - ey = poY - dy; - - if (_drop && _drop.options.constrain) { - cw = _drop.$el.width(); - ch = _drop.$el.height(); - cx = _drop.$el.offset().left; - cy = _drop.$el.offset().top; - - if (Math.abs(ey - cy) < 50) ey = cy; - if (Math.abs((ey + eh) - (cy+ch)) < 50) ey = cy + ch - eh; - if (Math.abs(ex - cx) < 50) ex = cx; - if (Math.abs((ex + ew) - (cx+cw)) < 50) ex = cx + cw - ew; - } - - $el.css({ - 'left': ex, - 'top': ey - }); - }; - - $document.on(events["move"], f); - $document.one(events["stop"], function(e) { - $document.unbind(events["move"], f); - resetCursor(); - - var _drop = that.getDrop(); - - if (hasMove && (!options.baseDropArea || !_drop || (options.baseDropArea.cid != _drop.cid))) { - if (_drop) { - _drop.trigger("drop", that.data); - } - that.trigger("drop", _drop, that.data); - } - - that.trigger("drag:end"); - - that.data = null; - that.drop = []; - - $el.removeClass("move"); - $el.css({ - 'left': "auto", - 'top': "auto" - }); - }); - }); - } - }); - - return { - events: events, - cursor: { - set: setCursor, - reset: resetCursor - }, - DropArea: DropArea, - DraggableType: DraggableType - }; -}); \ No newline at end of file diff --git a/editor/utils/string.js b/editor/utils/string.js index bde74a24..363fe3fe 100644 --- a/editor/utils/string.js +++ b/editor/utils/string.js @@ -24,7 +24,7 @@ define([ startAt = 0, fuzzies = 1, fuzzyFactor; - + // Cache fuzzyFactor for speed increase if (fuzziness) fuzzyFactor = 1 - fuzziness; @@ -35,7 +35,7 @@ define([ // Find next first case-insensitive match of a character. idxOf = lString.indexOf(lWord[i], startAt); - + if (-1 === idxOf) { fuzzies += fuzzyFactor; continue; @@ -50,19 +50,19 @@ define([ // preceded it with two perfect character matches. if (string[idxOf - 1] === ' ') charScore += 0.8; } - + // Same case bonus. - if (string[idxOf] === word[i]) charScore += 0.1; - + if (string[idxOf] === word[i]) charScore += 0.1; + // Update scores and startAt position for next round of indexOf runningScore += charScore; startAt = idxOf + 1; } } else { for (var i = 0; i < wordLength; ++i) { - + idxOf = lString.indexOf(lWord[i], startAt); - + if (-1 === idxOf) { return 0; } else if (startAt === idxOf) { @@ -72,8 +72,8 @@ define([ if (string[idxOf - 1] === ' ') charScore += 0.8; } - if (string[idxOf] === word[i]) charScore += 0.1; - + if (string[idxOf] === word[i]) charScore += 0.1; + runningScore += charScore; startAt = idxOf + 1; } @@ -81,11 +81,11 @@ define([ // Reduce penalty for longer strings. finalScore = 0.5 * (runningScore / strLength + runningScore / wordLength) / fuzzies; - + if ((lWord[0] === lString[0]) && (finalScore < 0.85)) { finalScore += 0.15; } - + return finalScore; }; diff --git a/editor/views/grid.js b/editor/views/grid.js deleted file mode 100644 index ea388d00..00000000 --- a/editor/views/grid.js +++ /dev/null @@ -1,299 +0,0 @@ -define([ - "hr/utils", - "hr/dom", - "hr/hr", - "utils/dragdrop" -], function(_, $, hr, dnd) { - var GridView = hr.View.extend({ - className: "component-grid", - defaults: { - columns: 0 // 0 means auto - }, - events: { - - }, - - initialize: function() { - GridView.__super__.initialize.apply(this, arguments); - - this.columns = this.options.columns; - this.views = []; - }, - - /* - * Add a view - */ - addView: function(view, options) { - view._grid = this; - view._gridOptions = _.defaults(options || {}, { - width: null, - at: null - }); - - if (view._gridOptions.at !== null) { - this.views.splice(view._gridOptions.at, 0, view); - } else { - this.views.push(view); - } - this.update(); - - return view; - }, - - /* - * Remove a view - */ - removeView: function(view) { - if (!_.isString(view)) view = view.cid; - - this.views = _.filter(this.views, function(_v) { - return _v.cid != view; - }); - this.update(); - }, - - /* - * Change layout by defining - */ - setLayout: function(n) { - this.columns = n; - this.update(); - }, - - /* - * Return current layout - */ - getLayout: function() { - var layout = this.columns || Math.floor(Math.sqrt(this.views.length)); - - var nColumns = Math.min(layout, this.views.length); - var nLines = Math.ceil(this.views.length/layout); - - return { - 'columns': nColumns, - 'lines': nLines - }; - }, - - /* - * Signal an update on tha layout to all views - */ - signalLayout: function() { - _.each(this.views, function(view) { - view.trigger("grid:layout"); - }); - }, - - /* - * Re-render the complete layout - */ - render: function() { - var x, y, lineW; - - // Detach view - _.each(this.views, function(view) { - view.detach(); - }); - - // Clear the view - this.$el.empty(); - - // Calcul layout - var layout = this.getLayout(); - - var sectionWidth = (100/layout.columns).toFixed(3); - var sectionHeight = (100/layout.lines).toFixed(3); - - // Add grid content - x = 0; y = 0; lineW = 100; - - _.each(this.views, function(view, i) { - var $section, $content, w, dw; - - // Calcul width for this section using optional width - dw = (lineW/(layout.columns - x)); - w = view._gridOptions.width || dw - - w = w.toFixed(4); - - // Container object - $section = $("
        ", { - 'class': 'grid-section', - 'css': { - 'left': (100 - lineW)+"%", - 'top': (y * sectionHeight)+"%", - 'width': w+"%", - 'height': sectionHeight+"%" - } - }); - $section.appendTo(this.$el); - - lineW = lineW - w; - - // Content - $content = $("
        ", { - 'class': 'grid-section-content' - }); - $content.append(view.$el); - $content.appendTo($section); - view.trigger("grid:layout"); - - // Resize bar - if (x < (layout.columns - 1)) { - // Horizontal - var hBar = $("
        ", { - 'class': "grid-resize-bar-h", - 'mousedown': this.resizerHandler(x, y, "h") - }); - hBar.appendTo($section); - $content.addClass("with-bar-h"); - } - - if (y < (layout.lines - 1)) { - // Vertical - var vBar = $("
        ", { - 'class': "grid-resize-bar-v", - 'mousedown': this.resizerHandler(x, y, "v") - }); - vBar.appendTo($section); - $content.addClass("with-bar-v"); - } - - // Calcul next position - x = x + 1; - if (x >= layout.columns) { - x = 0; - y = y + 1; - lineW = 100; - } - }, this); - - return this.ready(); - }, - - // Create a resizer handler - resizerHandler: function(x, y, type) { - var that = this; - var $document = $(document); - var oX, oY, dX, dY; - return function(e) { - e.preventDefault(); - oX = e.pageX; - oY = e.pageY; - - dnd.cursor.set(type == "h" ? "col-resize" : "row-resize"); - - var f = function(e) { - dx = oX - e.pageX; - dy = oY - e.pageY; - - if (type == "h") { - that.resizeColumn(x, -dx); - } else { - that.resizeLine(y, -dy); - } - - oX = e.pageX; - oY = e.pageY; - }; - - $document.mousemove(f); - $document.mouseup(function(e) { - $document.unbind('mousemove', f); - dnd.cursor.reset(); - }); - }; - }, - - getSection: function(sx, sy) { - var x, y, layout = this.getLayout(), that = this; - - x = 0; y = 0; - return this.$("> .grid-section").filter(function() { - var r = false; - - if ((sx !== null && sx == x) - || (sy !== null && sy == y)) { - r = true; - } - - // Calcul next position - x = x + 1; - if (x >= layout.columns) { - x = 0; - y = y + 1; - } - - return r; - }); - }, - - _resize: function(type, i, d) { - var getSection = _.bind(_.partialRight(this.getSection, null), this); - var pixelToPercent = _.bind(_.partialRight(this.pixelToPercent, null), this); - var position = "left"; - var size = "width"; - - if (type == "h") { - getSection = _.bind(_.partial(this.getSection, null), this); - pixelToPercent = _.bind(_.partial(this.pixelToPercent, null), this); - position = "top"; - size = "height"; - } - - // Convert update to percent - d = pixelToPercent(d); - - var $sections = getSection(i); - var $sectionsAfter = getSection(i+1); - - // New size for next sections - // We use el.get(0).style and not el.css because el.css returns pixel and not the real value - var sAfterN = this.strToPercent($sectionsAfter.get(0).style[size])-d; - - // New size for current sections - var sCurrentN = this.strToPercent($sections.get(0).style[size])+d; - - // Limited size - if (sCurrentN < 10 || sAfterN < 10) return false; - - // Resize next line - $sectionsAfter.css(_.object( - [position, size], - [ - (this.strToPercent($sectionsAfter.get(0).style[position])+d).toFixed(2)+"%", - sAfterN.toFixed(2)+"%" - ] - )); - - // Resize current line - $sections.css(_.object( - [size], - [sCurrentN.toFixed(2)+"%"] - )); - - this.signalLayout(); - - return true; - }, - - resizeLine: function(i, d) { - return this._resize("h", i, d); - }, - - resizeColumn: function(i, d) { - return this._resize("w", i, d); - }, - - pixelToPercent: function(x, y) { - if (x !== null) return ((x*100) / this.$el.width()); - if (y !== null) return ((y*100) / this.$el.height()); - }, - - strToPercent: function(size) { - return parseFloat(size.replace("%", "")) - } - }); - - return GridView; -}); \ No newline at end of file diff --git a/package.json b/package.json index 70128dfa..378a6b95 100644 --- a/package.json +++ b/package.json @@ -66,10 +66,15 @@ "hr.view": "*", "hr.collection": "*", "hr.class": "*", + "hr.dnd": "*", + "hr.gridview": "*", + "hr.logger": "*", + "hr.backend": "*", "octicons": "2.2.0", "mousetrap": "1.4.6", "moment": "2.9.0", - "sockjs-client": "0.1.3" + "sockjs-client": "0.1.3", + "axios": "0.5.2" }, "packageDependencies": { "about": "CodeboxIDE/package-about", From 8eae62ab99186c0012fe47db44893370c98b312e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Tue, 7 Apr 2015 16:45:13 +0200 Subject: [PATCH 255/351] Adapt most of the modules --- editor/collections/commands.js | 2 +- editor/collections/packages.js | 2 +- editor/collections/users.js | 2 +- editor/core/rpc.js | 3 + editor/core/socket.js | 2 +- editor/core/users.js | 1 + editor/main.js | 1 - editor/models/user.js | 2 +- editor/settings/keybindings.js | 95 +++---- editor/utils/date.js | 18 -- editor/utils/dialogs.js | 264 +++++++++-------- editor/utils/hash.js | 456 +++++++++++++++--------------- editor/utils/keyboard.js | 197 +++++++------ editor/utils/menu.js | 236 ++++++++-------- editor/utils/string.js | 174 ++++++------ editor/utils/taphold.js | 166 ++++++----- editor/utils/upload.js | 401 +++++++++++++------------- editor/views/dialogs/container.js | 172 ++++++----- editor/views/dialogs/input.js | 110 +++---- editor/views/dialogs/list.js | 385 ++++++++++++------------- editor/views/form.js | 322 +++++++++++---------- editor/views/menu.js | 135 +++++---- gulpfile.js | 2 +- package.json | 6 +- 24 files changed, 1556 insertions(+), 1598 deletions(-) delete mode 100644 editor/utils/date.js diff --git a/editor/collections/commands.js b/editor/collections/commands.js index d2ab2062..0ed19e40 100644 --- a/editor/collections/commands.js +++ b/editor/collections/commands.js @@ -5,7 +5,7 @@ var logger = require("hr.logger")("commands"); var Command = require("../models/command"); -var Commands = hr.Collection.extend({ +var Commands = Collection.extend({ model: Command, // Initialize diff --git a/editor/collections/packages.js b/editor/collections/packages.js index 215f4371..a356dfd6 100644 --- a/editor/collections/packages.js +++ b/editor/collections/packages.js @@ -7,7 +7,7 @@ var Package = require("../models/package"); var rpc = require("../core/rpc"); -var Packages = hr.Collection.extend({ +var Packages = Collection.extend({ model: Package, // Get packages list from backend diff --git a/editor/collections/users.js b/editor/collections/users.js index 62ba62ea..8d7a60f0 100644 --- a/editor/collections/users.js +++ b/editor/collections/users.js @@ -6,7 +6,7 @@ var logger = require("hr.logger")("users"); var User = require("../models/user"); var rpc = require("../core/rpc"); -var Users = hr.Collection.extend({ +var Users = Collection.extend({ model: User, listAll: function() { diff --git a/editor/core/rpc.js b/editor/core/rpc.js index 9928e63f..ccbc9780 100644 --- a/editor/core/rpc.js +++ b/editor/core/rpc.js @@ -8,6 +8,9 @@ var rpc = new Backend({ rpc.defaultMethod({ execute: function(args, options, method) { + console.log("request", method, args, options); + + return Q(axios.post("rpc/"+method, args)) .then(function(data) { return data.result; diff --git a/editor/core/socket.js b/editor/core/socket.js index 00a5c3e4..356e44b6 100644 --- a/editor/core/socket.js +++ b/editor/core/socket.js @@ -1,5 +1,5 @@ var Class = require("hr.class"); -var sockjs = require("sockjs-client"); +var SockJS = require("sockjs-client"); var logger = require("hr.logger")("socket"); var Socket = Class.extend({ diff --git a/editor/core/users.js b/editor/core/users.js index 76f4a6d2..6f8f8676 100644 --- a/editor/core/users.js +++ b/editor/core/users.js @@ -1,4 +1,5 @@ var Users = require("../collections/users"); +var events = require("./events"); var users = new Users(); diff --git a/editor/main.js b/editor/main.js index f1007ad6..8a163bf9 100644 --- a/editor/main.js +++ b/editor/main.js @@ -12,7 +12,6 @@ var dialogs = require("./utils/dialogs"); var menu = require("./utils/menu"); var File = require("./models/file"); -var date = require("./utils/date"); var keybindings = require("./settings/keybindings"); var upload = require("./utils/upload"); diff --git a/editor/models/user.js b/editor/models/user.js index bf4febc3..253be2fb 100644 --- a/editor/models/user.js +++ b/editor/models/user.js @@ -5,7 +5,7 @@ var logger = require("hr.logger")("users"); var rpc = require("../core/rpc"); -var User = hr.Model.extend({ +var User = Model.extend({ defaults: { id: null, name: null, diff --git a/editor/settings/keybindings.js b/editor/settings/keybindings.js index 14aa2b63..8aa3cde6 100644 --- a/editor/settings/keybindings.js +++ b/editor/settings/keybindings.js @@ -1,55 +1,54 @@ -define([ - "core/commands", - "core/settings" -], function(commands, settings) { - /* - * The key bindings configuration allow the user to - * change the default keyboard shortcuts for specific commands - */ - - var keyBindings = settings.schema("keybindings", { - title: "Key bindings", - type: "object", - properties: { - commands: { - type: "array", - items: { - "command": { - type: "string" - }, - "keys": { - type: "array" - } +var _ = require("hr.utils"); +var commands = require("../core/commands"); +var settings = require("../core/settings"); + +/* + * The key bindings configuration allow the user to + * change the default keyboard shortcuts for specific commands + */ + +var keyBindings = settings.schema("keybindings", { + title: "Key bindings", + type: "object", + properties: { + commands: { + type: "array", + items: { + "command": { + type: "string" + }, + "keys": { + type: "array" } } } - }); - - // Update a command - var updateCommand = function(cmd) { - var bindings = keyBindings.data.get("commands"); - var bind = _.find(bindings, { 'command': cmd.id }); - - if (!bind) { - if (cmd.get("originalShortcuts")) cmd.set("shortcuts", cmd.get("originalShortcuts")); - } else { - if (!cmd.get("originalShortcuts")) cmd.set("originalShortcuts", cmd.get("shortcuts")); - cmd.del("shortcuts", { silent: true }); - cmd.set("shortcuts", bind.keys); - } - }; + } +}); + +// Update a command +var updateCommand = function(cmd) { + var bindings = keyBindings.data.get("commands"); + var bind = _.find(bindings, { 'command': cmd.id }); + + if (!bind) { + if (cmd.get("originalShortcuts")) cmd.set("shortcuts", cmd.get("originalShortcuts")); + } else { + if (!cmd.get("originalShortcuts")) cmd.set("originalShortcuts", cmd.get("shortcuts")); + cmd.del("shortcuts", { silent: true }); + cmd.set("shortcuts", bind.keys); + } +}; - // Update all commands - var updateAll = function() { - commands.each(updateCommand); - }; +// Update all commands +var updateAll = function() { + commands.each(updateCommand); +}; - // Update commands everytime settings change and adapt new commands - keyBindings.data.on("change", updateAll); - commands.on("add", updateCommand); - commands.on("reset", updateAll); +// Update commands everytime settings change and adapt new commands +keyBindings.data.on("change", updateAll); +commands.on("add", updateCommand); +commands.on("reset", updateAll); - updateAll +updateAll(); - return keyBindings; -}); \ No newline at end of file +module.exports = keyBindings; diff --git a/editor/utils/date.js b/editor/utils/date.js deleted file mode 100644 index 6e7d80ad..00000000 --- a/editor/utils/date.js +++ /dev/null @@ -1,18 +0,0 @@ -define([ - 'hr/hr', - 'moment' -], function (hr, moment) { - var relativeDate = function(d) { - return moment(d).fromNow(); - }; - - var date = { - 'relative': relativeDate - }; - - hr.Template.extendContext({ - '$date': date - }); - - return date; -}); \ No newline at end of file diff --git a/editor/utils/dialogs.js b/editor/utils/dialogs.js index 3e017038..77c43f29 100644 --- a/editor/utils/dialogs.js +++ b/editor/utils/dialogs.js @@ -1,136 +1,134 @@ -define([ - "hr/utils", - "hr/promise", - "hr/hr", - "views/dialogs/container", - "views/dialogs/input", - "views/dialogs/list", - "text!resources/templates/dialogs/alert.html", - "text!resources/templates/dialogs/confirm.html", - "text!resources/templates/dialogs/prompt.html", - "text!resources/templates/dialogs/schema.html" -], function(_, Q, hr, Dialog, DialogInputView, DialogListView, -alertTemplate, confirmTemplate, promptTemplate, schemaTemplate) { - - // Open a dialog - var open = function(View, options) { - var d = Q.defer(); - - // Create the dialog - var diag = new Dialog(_.extend(options || {}, { - View: View - })); - - // Bind close - diag.on("close", function(force) { - if (force) return d.reject(new Error("Dialog was been closed")); - d.resolve(diag.view); +var _ = require("hr.utils"); +var Q = require("q"); +var Collection = require("hr.collection"); + +var Dialog = require("../views/dialogs/container"); +var DialogInputView = require("../views/dialogs/input"); +var DialogListView = require("../views/dialogs/list"); + +var alertTemplate = require("../resources/templates/dialogs/alert.html"); +var confirmTemplate = require("../resources/templates/dialogs/confirm.html"); +var promptTemplate = require("../resources/templates/dialogs/prompt.html"); +var schemaTemplate = require("../resources/templates/dialogs/schema.html"); + +// Open a dialog +var open = function(View, options) { + var d = Q.defer(); + + // Create the dialog + var diag = new Dialog(_.extend(options || {}, { + View: View + })); + + // Bind close + diag.on("close", function(force) { + if (force) return d.reject(new Error("Dialog was been closed")); + d.resolve(diag.view); + }); + + // Open it (add it to dom) + diag.render(); + + return d.promise; +}; + +// Input dialog +var openInput = function(viewOptions, options, View) { + return open(View || DialogInputView, _.extend(options || {}, { + view: viewOptions || {} + })) + .then(function(view) { + var value = view.getValue(); + + if (value == null) return Q.reject(new Error("Dialog return empty value")); + return value; + }); +}; + +// Alert +var openAlert = function(text, options) { + options = _.defaults(options || {}, { + isHtml: false + }); + return openInput({ + template: alertTemplate, + text: text, + isHtml: options.isHtml + }); +}; +var openErrorAlert = function(err) { + return openAlert("Error: "+(err.message || err)) + .fin(function() { + return Q.reject(err); + }); +}; + +// Confirm +var openConfirm = function(text, options) { + return openInput({ + template: confirmTemplate, + text: text + }); +}; + +// Prompt +var openPrompt = function(text, value, options) { + return openInput({ + template: promptTemplate, + text: text, + defaultValue: value, + value: function(d) { return d.$("input").val(); } + }); +}; + +// List +var openList = function(source, options) { + if (_.isArray(source)) { + source = new Collection({ + models: _.map(source, function(item) { + if (!_.isObject(item)) return { value: item }; + return item; + }) }); - - // Open it (add it to dom) - diag.render(); - - return d.promise; - }; - - // Input dialog - var openInput = function(viewOptions, options, View) { - return open(View || DialogInputView, _.extend(options || {}, { - view: viewOptions || {} - })) - .then(function(view) { - var value = view.getValue(); - - if (value == null) return Q.reject(new Error("Dialog return empty value")); - return value; - }); - }; - - // Alert - var openAlert = function(text, options) { - options = _.defaults(options || {}, { - isHtml: false - }); - return openInput({ - template: alertTemplate, - text: text, - isHtml: options.isHtml - }); - }; - var openErrorAlert = function(err) { - return openAlert("Error: "+(err.message || err)) - .fin(function() { - return Q.reject(err); - }); - }; - - // Confirm - var openConfirm = function(text, options) { - return openInput({ - template: confirmTemplate, - text: text - }); - }; - - // Prompt - var openPrompt = function(text, value, options) { - return openInput({ - template: promptTemplate, - text: text, - defaultValue: value, - value: function(d) { return d.$("input").val(); } - }); - }; - - // List - var openList = function(source, options) { - if (_.isArray(source)) { - source = new hr.Collection({ - models: _.map(source, function(item) { - if (!_.isObject(item)) return { value: item }; - return item; - }) + } + + return openInput( + _.extend({ + template: "
        <%- item.get('value') %>
        ", + placeholder: "", + filter: function() { return true; } + }, options, { + source: source + }), {}, DialogListView); +}; + +// Schema +var openSchema = function(schema, values) { + values = values || {}; + + return openInput({ + template: schemaTemplate, + schema: schema, + defaultValues: values, + value: function(d) { + var nvalues = _.clone(values); + + _.each(schema.properties, function(property, key) { + var v = d.$("*[name='"+key+"']").val(); + nvalues[key] = v; }); - } - return openInput( - _.extend({ - template: "
        <%- item.get('value') %>
        ", - placeholder: "", - filter: function() { return true; } - }, options, { - source: source - }), {}, DialogListView); - }; - - // Schema - var openSchema = function(schema, values) { - values = values || {}; - - return openInput({ - template: schemaTemplate, - schema: schema, - defaultValues: values, - value: function(d) { - var nvalues = _.clone(values); - - _.each(schema.properties, function(property, key) { - var v = d.$("*[name='"+key+"']").val(); - nvalues[key] = v; - }); - - return nvalues; - } - }); - }; - - return { - open: open, - alert: openAlert, - error: openErrorAlert, - confirm: openConfirm, - prompt: openPrompt, - list: openList, - schema: openSchema - }; -}); \ No newline at end of file + return nvalues; + } + }); +}; + +module.exports = { + open: open, + alert: openAlert, + error: openErrorAlert, + confirm: openConfirm, + prompt: openPrompt, + list: openList, + schema: openSchema +}; diff --git a/editor/utils/hash.js b/editor/utils/hash.js index bd7b21f5..833f94f5 100644 --- a/editor/utils/hash.js +++ b/editor/utils/hash.js @@ -1,261 +1,259 @@ -define(function () { - var crc32table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D"; - - var utf8Encode = function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } +var crc32table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D"; - } - - return utftext; - }; - - /** - * Convert value as 8-bit unsigned integer to 2 digit hexadecimal number. - */ - var hex8 = function(val) - { - var n = val & 0xFF, - str = n.toString(16).toUpperCase() - ; - - while(str.length < 2) - str = "0" + str; - - return str; - }; - - /** - * Convert value as 16-bit unsigned integer to 4 digit hexadecimal number. - */ - var hex16 = function(val) - { - return hex8(val >> 8) + hex8(val); - }; - - /** - * Convert value as 32-bit unsigned integer to 8 digit hexadecimal number. - */ - var hex32 = function(val) - { - return hex16(val >> 16) + hex16(val); - }; - - var crc32= function(str) { - str = utf8Encode(str); - - var crc = 0; - var x = 0; - var y = 0; - - crc = crc ^ (-1); - for (var i = 0, iTop = str.length; i < iTop; i++) { - y = (crc ^ str.charCodeAt(i)) & 0xFF; - x = "0x" + crc32table.substr(y * 9, 8); - crc = (crc >>> 8) ^ x; - } +var utf8Encode = function (string) { + string = string.replace(/\r\n/g,"\n"); + var utftext = ""; - return (crc ^ (-1)).toString(); - }; - - /*\ - |*| - |*| Base64 / binary data / UTF-8 strings utilities - |*| - |*| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding - |*| - \*/ - - /* Array of bytes to base64 string decoding */ - - function b64ToUint6 (nChr) { - - return nChr > 64 && nChr < 91 ? - nChr - 65 - : nChr > 96 && nChr < 123 ? - nChr - 71 - : nChr > 47 && nChr < 58 ? - nChr + 4 - : nChr === 43 ? - 62 - : nChr === 47 ? - 63 - : - 0; + for (var n = 0; n < string.length; n++) { - } + var c = string.charCodeAt(n); - function base64DecToArr (sBase64, nBlocksSize) { + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } - var - sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, - nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen); + } - for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4; - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; - } - nUint24 = 0; + return utftext; +}; + +/** + * Convert value as 8-bit unsigned integer to 2 digit hexadecimal number. + */ +var hex8 = function(val) +{ + var n = val & 0xFF, + str = n.toString(16).toUpperCase() + ; + + while(str.length < 2) + str = "0" + str; + + return str; +}; + +/** + * Convert value as 16-bit unsigned integer to 4 digit hexadecimal number. + */ +var hex16 = function(val) +{ + return hex8(val >> 8) + hex8(val); +}; + +/** + * Convert value as 32-bit unsigned integer to 8 digit hexadecimal number. + */ +var hex32 = function(val) +{ + return hex16(val >> 16) + hex16(val); +}; + +var crc32= function(str) { + str = utf8Encode(str); + + var crc = 0; + var x = 0; + var y = 0; + + crc = crc ^ (-1); + for (var i = 0, iTop = str.length; i < iTop; i++) { + y = (crc ^ str.charCodeAt(i)) & 0xFF; + x = "0x" + crc32table.substr(y * 9, 8); + crc = (crc >>> 8) ^ x; + } + return (crc ^ (-1)).toString(); +}; + +/*\ +|*| +|*| Base64 / binary data / UTF-8 strings utilities +|*| +|*| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding +|*| +\*/ + +/* Array of bytes to base64 string decoding */ + +function b64ToUint6 (nChr) { + + return nChr > 64 && nChr < 91 ? + nChr - 65 + : nChr > 96 && nChr < 123 ? + nChr - 71 + : nChr > 47 && nChr < 58 ? + nChr + 4 + : nChr === 43 ? + 62 + : nChr === 47 ? + 63 + : + 0; + +} + +function base64DecToArr (sBase64, nBlocksSize) { + + var + sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, + nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen); + + for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) { + nMod4 = nInIdx & 3; + nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4; + if (nMod4 === 3 || nInLen - nInIdx === 1) { + for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { + taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; } - } + nUint24 = 0; - return taBytes; + } } - /* Base64 string to array encoding */ + return taBytes; +} - function uint6ToB64 (nUint6) { +/* Base64 string to array encoding */ - return nUint6 < 26 ? - nUint6 + 65 - : nUint6 < 52 ? - nUint6 + 71 - : nUint6 < 62 ? - nUint6 - 4 - : nUint6 === 62 ? - 43 - : nUint6 === 63 ? - 47 - : - 65; +function uint6ToB64 (nUint6) { - } + return nUint6 < 26 ? + nUint6 + 65 + : nUint6 < 52 ? + nUint6 + 71 + : nUint6 < 62 ? + nUint6 - 4 + : nUint6 === 62 ? + 43 + : nUint6 === 63 ? + 47 + : + 65; - function base64EncArr (aBytes) { +} - var nMod3, sB64Enc = ""; +function base64EncArr (aBytes) { - for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; } - nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63)); - nUint24 = 0; - } - } + var nMod3, sB64Enc = ""; - return sB64Enc.replace(/A(?=A$|$)/g, "="); + for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { + nMod3 = nIdx % 3; + if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; } + nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24); + if (nMod3 === 2 || aBytes.length - nIdx === 1) { + sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63)); + nUint24 = 0; + } + } + return sB64Enc.replace(/A(?=A$|$)/g, "="); + +} + +/* UTF-8 array to DOMString and vice versa */ + +function UTF8ArrToStr (aBytes) { + + var sView = ""; + + for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) { + nPart = aBytes[nIdx]; + sView += String.fromCharCode( + nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */ + /* (nPart - 252 << 32) is not possible in ECMAScript! So...: */ + (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 + : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */ + (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 + : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */ + (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 + : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */ + (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 + : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */ + (nPart - 192 << 6) + aBytes[++nIdx] - 128 + : /* nPart < 127 ? */ /* one byte */ + nPart + ); } - /* UTF-8 array to DOMString and vice versa */ - - function UTF8ArrToStr (aBytes) { - - var sView = ""; - - for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) { - nPart = aBytes[nIdx]; - sView += String.fromCharCode( - nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */ - /* (nPart - 252 << 32) is not possible in ECMAScript! So...: */ - (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 - : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */ - (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 - : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */ - (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 - : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */ - (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 - : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */ - (nPart - 192 << 6) + aBytes[++nIdx] - 128 - : /* nPart < 127 ? */ /* one byte */ - nPart - ); - } + return sView; - return sView; +} - } +function strToUTF8Arr (sDOMStr) { - function strToUTF8Arr (sDOMStr) { + var aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0; - var aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0; + /* mapping... */ - /* mapping... */ + for (var nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) { + nChr = sDOMStr.charCodeAt(nMapIdx); + nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6; + } - for (var nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) { - nChr = sDOMStr.charCodeAt(nMapIdx); - nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6; + aBytes = new Uint8Array(nArrLen); + + /* transcription... */ + + for (var nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) { + nChr = sDOMStr.charCodeAt(nChrIdx); + if (nChr < 128) { + /* one byte */ + aBytes[nIdx++] = nChr; + } else if (nChr < 0x800) { + /* two bytes */ + aBytes[nIdx++] = 192 + (nChr >>> 6); + aBytes[nIdx++] = 128 + (nChr & 63); + } else if (nChr < 0x10000) { + /* three bytes */ + aBytes[nIdx++] = 224 + (nChr >>> 12); + aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); + aBytes[nIdx++] = 128 + (nChr & 63); + } else if (nChr < 0x200000) { + /* four bytes */ + aBytes[nIdx++] = 240 + (nChr >>> 18); + aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); + aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); + aBytes[nIdx++] = 128 + (nChr & 63); + } else if (nChr < 0x4000000) { + /* five bytes */ + aBytes[nIdx++] = 248 + (nChr >>> 24); + aBytes[nIdx++] = 128 + (nChr >>> 18 & 63); + aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); + aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); + aBytes[nIdx++] = 128 + (nChr & 63); + } else /* if (nChr <= 0x7fffffff) */ { + /* six bytes */ + aBytes[nIdx++] = 252 + /* (nChr >>> 32) is not possible in ECMAScript! So...: */ (nChr / 1073741824); + aBytes[nIdx++] = 128 + (nChr >>> 24 & 63); + aBytes[nIdx++] = 128 + (nChr >>> 18 & 63); + aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); + aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); + aBytes[nIdx++] = 128 + (nChr & 63); } + } - aBytes = new Uint8Array(nArrLen); - - /* transcription... */ - - for (var nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) { - nChr = sDOMStr.charCodeAt(nChrIdx); - if (nChr < 128) { - /* one byte */ - aBytes[nIdx++] = nChr; - } else if (nChr < 0x800) { - /* two bytes */ - aBytes[nIdx++] = 192 + (nChr >>> 6); - aBytes[nIdx++] = 128 + (nChr & 63); - } else if (nChr < 0x10000) { - /* three bytes */ - aBytes[nIdx++] = 224 + (nChr >>> 12); - aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); - aBytes[nIdx++] = 128 + (nChr & 63); - } else if (nChr < 0x200000) { - /* four bytes */ - aBytes[nIdx++] = 240 + (nChr >>> 18); - aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); - aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); - aBytes[nIdx++] = 128 + (nChr & 63); - } else if (nChr < 0x4000000) { - /* five bytes */ - aBytes[nIdx++] = 248 + (nChr >>> 24); - aBytes[nIdx++] = 128 + (nChr >>> 18 & 63); - aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); - aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); - aBytes[nIdx++] = 128 + (nChr & 63); - } else /* if (nChr <= 0x7fffffff) */ { - /* six bytes */ - aBytes[nIdx++] = 252 + /* (nChr >>> 32) is not possible in ECMAScript! So...: */ (nChr / 1073741824); - aBytes[nIdx++] = 128 + (nChr >>> 24 & 63); - aBytes[nIdx++] = 128 + (nChr >>> 18 & 63); - aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); - aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); - aBytes[nIdx++] = 128 + (nChr & 63); - } - } + return aBytes; - return aBytes; +} +module.exports = { + 'crc32': crc32, + 'hex8': hex8, + 'hex16': hex16, + 'hex32': hex32, + 'atob': function(s) { + return UTF8ArrToStr(base64DecToArr(s)); + }, + 'btoa': function(s) { + return base64EncArr(strToUTF8Arr(s)); } - - return { - 'crc32': crc32, - 'hex8': hex8, - 'hex16': hex16, - 'hex32': hex32, - 'atob': function(s) { - return UTF8ArrToStr(base64DecToArr(s)); - }, - 'btoa': function(s) { - return base64EncArr(strToUTF8Arr(s)); - } - }; -}); +}; diff --git a/editor/utils/keyboard.js b/editor/utils/keyboard.js index 3f9ca0fd..f341390e 100644 --- a/editor/utils/keyboard.js +++ b/editor/utils/keyboard.js @@ -1,116 +1,115 @@ -define([ - 'hr/hr', - 'hr/utils', - 'vendors/mousetrap/mousetrap' -], function (hr, _, Mousetrap) { - var originalStopCallback = Mousetrap.stopCallback; - Mousetrap.stopCallback = function(e, element) { - if (e.mousetrap) { - return false; - } - return originalStopCallback(e, element); - }; - - var Keyboard = hr.Class.extend({ - initialize: function() { - this.bindings = {}; - return this; - }, - - /* - * Enable keyboard shortcut for a specific event - */ - enableKeyEvent: function(e) { - e.mousetrap = true; - }, - - /* - * Bind keyboard shortcuts to callback - */ - bind: function(keys, callback, context) { - if (_.isArray(keys)) { - _.each(keys, function(key) { this.bind(key, callback, context) }, this); - return; - } - - // Map shortcut -> action - if (_.isObject(keys)) { - _.each(keys, function(method, key) { - this.bind(key, method, callback); - }, this) - return; - } - - // Bind - if (this.bindings[keys] == null) { - this.bindings[keys] = new hr.Class(); - Mousetrap.bind(keys, _.bind(function(e) { - this.bindings[keys].trigger("action", e); - }, this)); - } - context.listenTo(this.bindings[keys], "action", callback); +var Class = require("hr.class"); +var _ = require("hr.utils"); + +var Mousetrap = require("mousetrap"); + +var originalStopCallback = Mousetrap.stopCallback; +Mousetrap.stopCallback = function(e, element) { + if (e.mousetrap) { + return false; + } + return originalStopCallback(e, element); +}; + +var Keyboard = Class.extend({ + initialize: function() { + this.bindings = {}; + return this; + }, + + /* + * Enable keyboard shortcut for a specific event + */ + enableKeyEvent: function(e) { + e.mousetrap = true; + }, + + /* + * Bind keyboard shortcuts to callback + */ + bind: function(keys, callback, context) { + if (_.isArray(keys)) { + _.each(keys, function(key) { this.bind(key, callback, context) }, this); return; - }, - - /* - * Unbind keyboard shortcuts - */ - unbind: function(keys, context, callback) { - if (_.isArray(keys)) { - _.each(keys, function(key) { this.unbind(key, context, callback) }, this); - return; - } + } - if (!this.bindings[keys]) return; + // Map shortcut -> action + if (_.isObject(keys)) { + _.each(keys, function(method, key) { + this.bind(key, method, callback); + }, this) + return; + } - context.stopListening(this.bindings[keys], "action", callback); + // Bind + if (this.bindings[keys] == null) { + this.bindings[keys] = new Class(); + Mousetrap.bind(keys, _.bind(function(e) { + this.bindings[keys].trigger("action", e); + }, this)); + } + context.listenTo(this.bindings[keys], "action", callback); + return; + }, + + /* + * Unbind keyboard shortcuts + */ + unbind: function(keys, context, callback) { + if (_.isArray(keys)) { + _.each(keys, function(key) { this.unbind(key, context, callback) }, this); return; - }, + } - /* - * Prevent default browser shortcut - */ - preventDefault: function(keys) { - return this.bind(keys, function(e) { - e.preventDefault(); - }, this); - }, + if (!this.bindings[keys]) return; - /* - * Convert shortcut or list of shortcut to a string - */ - toText: function(shortcut) { - if (_.isArray(shortcut)) shortcut = _.first(shortcut); - if (!shortcut) return null; + context.stopListening(this.bindings[keys], "action", callback); + return; + }, - var isMac = /Mac|iPod|iPhone|iPad/.test(navigator.platform); + /* + * Prevent default browser shortcut + */ + preventDefault: function(keys) { + return this.bind(keys, function(e) { + e.preventDefault(); + }, this); + }, - // Replace mod by equivalent for mac or windows - shortcut = shortcut.replace("mod", isMac ? '⌘' : 'ctrl'); + /* + * Convert shortcut or list of shortcut to a string + */ + toText: function(shortcut) { + if (_.isArray(shortcut)) shortcut = _.first(shortcut); + if (!shortcut) return null; - // Replace ctrl - shortcut = shortcut.replace("ctrl", "⌃"); + var isMac = /Mac|iPod|iPhone|iPad/.test(navigator.platform); - // Replace shift - shortcut = shortcut.replace("shift", "⇧"); + // Replace mod by equivalent for mac or windows + shortcut = shortcut.replace("mod", isMac ? '⌘' : 'ctrl'); - if (isMac) { - shortcut = shortcut.replace("alt", "⌥"); - } else { - shortcut = shortcut.replace("alt", "⎇"); - } + // Replace ctrl + shortcut = shortcut.replace("ctrl", "⌃"); - // Replace + - shortcut = shortcut.replace(/\+/g, " "); + // Replace shift + shortcut = shortcut.replace("shift", "⇧"); - return shortcut.toUpperCase(); + if (isMac) { + shortcut = shortcut.replace("alt", "⌥"); + } else { + shortcut = shortcut.replace("alt", "⎇"); } - }); - var keyboard = new Keyboard(); + // Replace + + shortcut = shortcut.replace(/\+/g, " "); + + return shortcut.toUpperCase(); + } +}); + +var keyboard = new Keyboard(); - // Prevent some browser default keyboard interactions - keyboard.preventDefault("mod+r"); +// Prevent some browser default keyboard interactions +keyboard.preventDefault("mod+r"); - return keyboard; -}); \ No newline at end of file +module.exports = keyboard; diff --git a/editor/utils/menu.js b/editor/utils/menu.js index 57f66253..9bf6400a 100644 --- a/editor/utils/menu.js +++ b/editor/utils/menu.js @@ -1,141 +1,133 @@ -define([ - 'hr/dom', - 'hr/utils', - 'views/menu', - 'utils/taphold' -], function ($, _, MenuView, taphold) { +var $ = require("jquery"); +var _ = require("hr.utils"); +var MenuView = require("../views/menu"); +var taphold = require("./taphold"); + +var menu = { + lastTimeOpened: 0, + origin: null, + + /** + * Clear current context menu + */ + clear: function() { + $(".ui-context-menu").removeClass("ui-context-menu"); + $("#ui-context-menu").remove(); + }, /** - * Context menu manager + * Generate menu from menuItems or a generator function * - * @class + * @param {array} menuItems */ - var Menu = { - lastTimeOpened: 0, - origin: null, - - /** - * Clear current context menu - */ - clear: function() { - $(".ui-context-menu").removeClass("ui-context-menu"); - $("#ui-context-menu").remove(); - }, - - /** - * Generate menu from menuItems or a generator function - * - * @param {array} menuItems - */ - generateMenu: function(menuItems) { - if (_.isFunction(menuItems)) menuItems = menuItems(); - - var menu = new MenuView({ - items: menuItems - }); - menu.$el.appendTo($("body")); - menu.on("action", function() { - Menu.clear(); - }) - menu.render(); - return menu; - }, - - /** - * Create a new context menu - * - * @param {array} menuItems - * @param {object} pos position for the menu - */ - open: function(menuItems, pos) { - Menu.clear(); - Menu.lastTimeOpened = Date.now(); - - var menu = Menu.generateMenu(menuItems); - - var w = menu.$el.width(); - var h = menu.$el.height(); - - var windowW = $(window).width(); - var windowH = $(window).height(); - - if ((pos.left+w) > windowW) { - pos.left = pos.left - w; - menu.$el.addClass("submenus-right"); - } - if ((pos.top+h) > windowH) { - pos.top = pos.top - h; - menu.$el.addClass("submenus-top"); - } + generateView: function(menuItems) { + if (_.isFunction(menuItems)) menuItems = menuItems(); + + var menuView = new MenuView({ + items: menuItems + }); + menuView.$el.appendTo($("body")); + menuView.on("action", function() { + menu.clear(); + }) + menuView.render(); + return menuView; + }, - menu.$el.css(_.extend({ - 'position': "fixed", - 'z-index': 100 - }, pos)); - menu.$el.attr("id", "ui-context-menu"); - }, - - /** - * Add a context menu to an element - * the menu can be open by left click and tap hold on ipad - * - * @param {jqueryElement} el - * @param {array} menu menu items - * @param {object} options - */ - add: function(el, menu, options) { - var $el = $(el); - - options = _.defaults({}, options, { - // Menu accessible in textinput - 'textinput': false - }); + /** + * Create a new context menu + * + * @param {array} menuItems + * @param {object} pos position for the menu + */ + open: function(menuItems, pos) { + menu.clear(); + menu.lastTimeOpened = Date.now(); - var handler = function(e) { - Menu.origin = e.type; - var target = e.target || e.srcElement; + var menuView = menu.generateView(menuItems); - // Ignore Menu on textinput - if (!options.textinput && - (target.tagName == 'INPUT' || target.tagName == 'SELECT' || target.tagName == 'TEXTAREA' || target.isContentEditable)) { - return; - } + var w = menuView.$el.width(); + var h = menuView.$el.height(); - var x = e.pageX || e.originalEvent.touches[0].pageX; - var y = e.pageY || e.originalEvent.touches[0].pageY; + var windowW = $(window).width(); + var windowH = $(window).height(); - Menu.open(menu, { - 'left': x, - 'top': y - }); + if ((pos.left+w) > windowW) { + pos.left = pos.left - w; + menuView.$el.addClass("submenus-right"); + } + if ((pos.top+h) > windowH) { + pos.top = pos.top - h; + menuView.$el.addClass("submenus-top"); + } + + menuView.$el.css(_.extend({ + 'position': "fixed", + 'z-index': 100 + }, pos)); + menuView.$el.attr("id", "ui-context-menu"); + }, - $el.addClass("ui-context-menu"); - return false; + /** + * Add a context menu to an element + * the menu can be open by left click and tap hold on ipad + * + * @param {jqueryElement} el + * @param {array} menu menu items + * @param {object} options + */ + add: function(el, menuView, options) { + var $el = $(el); + + options = _.defaults({}, options, { + // Menu accessible in textinput + 'textinput': false + }); + + var handler = function(e) { + menu.origin = e.type; + var target = e.target || e.srcElement; + + // Ignore Menu on textinput + if (!options.textinput && + (target.tagName == 'INPUT' || target.tagName == 'SELECT' || target.tagName == 'TEXTAREA' || target.isContentEditable)) { + return; } - $el.on("contextmenu", handler); - if (navigator.userAgent.match(/iPad/i) != null) taphold.bind($el, handler); - }, + var x = e.pageX || e.originalEvent.touches[0].pageX; + var y = e.pageY || e.originalEvent.touches[0].pageY; - remove: function(el) { - var $el = $(el); + menu.open(menuView, { + 'left': x, + 'top': y + }); - $el.off("contextmenu"); - taphold.unbind($el); + $el.addClass("ui-context-menu"); + return false; } - }; - // Click on the page: clse context menu - $(document).on("click", function (e) { - if (Menu.lastTimeOpened > (Date.now() - 600) && Menu.origin != "contextmenu") return; - Menu.clear(); - }); + $el.on("contextmenu", handler); + if (navigator.userAgent.match(/iPad/i) != null) taphold.bind($el, handler); + }, + + remove: function(el) { + var $el = $(el); + + $el.off("contextmenu"); + taphold.unbind($el); + } +}; + +// Click on the page: clse context menu +$(document).on("click", function (e) { + if (menu.lastTimeOpened > (Date.now() - 600) && menu.origin != "contextmenu") return; + menu.clear(); +}); - // Open new Menu: close other context menu - $(document).on("contextmenu", function() { - Menu.clear(); - }); +// Open new Menu: close other context menu +$(document).on("contextmenu", function() { + menu.clear(); +}); - return Menu; -}); \ No newline at end of file +module.exports = menu; diff --git a/editor/utils/string.js b/editor/utils/string.js index 363fe3fe..067fbdd9 100644 --- a/editor/utils/string.js +++ b/editor/utils/string.js @@ -1,100 +1,96 @@ -define([ - 'hr/hr' -], function (hr) { - /** - * Scores a string against another string. - * score('Hello World', 'he'); //=> 0.5931818181818181 - * score('Hello World', 'Hello'); //=> 0.7318181818181818 - */ - var score = function(string, word, fuzziness) { - // If the string is equal to the word, perfect match. - if (string == word) return 1; - - //if it's not a perfect match and is empty return 0 - if( word == "") return 0; - - var runningScore = 0, - charScore, - finalScore, - lString = string.toLowerCase(), - strLength = string.length, - lWord = word.toLowerCase(), - wordLength = word.length, - idxOf, - startAt = 0, - fuzzies = 1, - fuzzyFactor; - - // Cache fuzzyFactor for speed increase - if (fuzziness) fuzzyFactor = 1 - fuzziness; - - // Walk through word and add up scores. - // Code duplication occurs to prevent checking fuzziness inside for loop - if (fuzziness) { - for (var i = 0; i < wordLength; ++i) { - - // Find next first case-insensitive match of a character. - idxOf = lString.indexOf(lWord[i], startAt); - - if (-1 === idxOf) { - fuzzies += fuzzyFactor; - continue; - } else if (startAt === idxOf) { - // Consecutive letter & start-of-string Bonus - charScore = 0.7; - } else { - charScore = 0.1; - - // Acronym Bonus - // Weighing Logic: Typing the first character of an acronym is as if you - // preceded it with two perfect character matches. - if (string[idxOf - 1] === ' ') charScore += 0.8; - } - - // Same case bonus. - if (string[idxOf] === word[i]) charScore += 0.1; - - // Update scores and startAt position for next round of indexOf - runningScore += charScore; - startAt = idxOf + 1; +/** + * Scores a string against another string. + * score('Hello World', 'he'); //=> 0.5931818181818181 + * score('Hello World', 'Hello'); //=> 0.7318181818181818 + */ +var score = function(string, word, fuzziness) { + // If the string is equal to the word, perfect match. + if (string == word) return 1; + + //if it's not a perfect match and is empty return 0 + if( word == "") return 0; + + var runningScore = 0, + charScore, + finalScore, + lString = string.toLowerCase(), + strLength = string.length, + lWord = word.toLowerCase(), + wordLength = word.length, + idxOf, + startAt = 0, + fuzzies = 1, + fuzzyFactor; + + // Cache fuzzyFactor for speed increase + if (fuzziness) fuzzyFactor = 1 - fuzziness; + + // Walk through word and add up scores. + // Code duplication occurs to prevent checking fuzziness inside for loop + if (fuzziness) { + for (var i = 0; i < wordLength; ++i) { + + // Find next first case-insensitive match of a character. + idxOf = lString.indexOf(lWord[i], startAt); + + if (-1 === idxOf) { + fuzzies += fuzzyFactor; + continue; + } else if (startAt === idxOf) { + // Consecutive letter & start-of-string Bonus + charScore = 0.7; + } else { + charScore = 0.1; + + // Acronym Bonus + // Weighing Logic: Typing the first character of an acronym is as if you + // preceded it with two perfect character matches. + if (string[idxOf - 1] === ' ') charScore += 0.8; } - } else { - for (var i = 0; i < wordLength; ++i) { - idxOf = lString.indexOf(lWord[i], startAt); + // Same case bonus. + if (string[idxOf] === word[i]) charScore += 0.1; - if (-1 === idxOf) { - return 0; - } else if (startAt === idxOf) { - charScore = 0.7; - } else { - charScore = 0.1; - if (string[idxOf - 1] === ' ') charScore += 0.8; - } + // Update scores and startAt position for next round of indexOf + runningScore += charScore; + startAt = idxOf + 1; + } + } else { + for (var i = 0; i < wordLength; ++i) { + + idxOf = lString.indexOf(lWord[i], startAt); + + if (-1 === idxOf) { + return 0; + } else if (startAt === idxOf) { + charScore = 0.7; + } else { + charScore = 0.1; + if (string[idxOf - 1] === ' ') charScore += 0.8; + } - if (string[idxOf] === word[i]) charScore += 0.1; + if (string[idxOf] === word[i]) charScore += 0.1; - runningScore += charScore; - startAt = idxOf + 1; - } + runningScore += charScore; + startAt = idxOf + 1; } + } - // Reduce penalty for longer strings. - finalScore = 0.5 * (runningScore / strLength + runningScore / wordLength) / fuzzies; + // Reduce penalty for longer strings. + finalScore = 0.5 * (runningScore / strLength + runningScore / wordLength) / fuzzies; - if ((lWord[0] === lString[0]) && (finalScore < 0.85)) { - finalScore += 0.15; - } + if ((lWord[0] === lString[0]) && (finalScore < 0.85)) { + finalScore += 0.15; + } - return finalScore; - }; + return finalScore; +}; - var endsWith = function(s, suffix) { - return s.indexOf(suffix, s.length - suffix.length) !== -1; - }; +var endsWith = function(s, suffix) { + return s.indexOf(suffix, s.length - suffix.length) !== -1; +}; - return { - 'score': score, - 'endsWith': endsWith - }; -}); \ No newline at end of file +module.exports = { + 'score': score, + 'endsWith': endsWith +}; diff --git a/editor/utils/taphold.js b/editor/utils/taphold.js index 3fbf421f..f0e2f54e 100644 --- a/editor/utils/taphold.js +++ b/editor/utils/taphold.js @@ -1,98 +1,96 @@ -define([ - 'hr/dom' -], function ($) { - var $document = $(document); - - function triggerCustomEvent( obj, eventType, event, bubble ) { - var originalType = event.type; - event.type = eventType; - if ( bubble ) { - $.event.trigger( event, undefined, obj ); - } else { - $.event.dispatch.call( obj, event ); - } - event.type = originalType; +var $ = require("jquery"); + +var $document = $(document); + +function triggerCustomEvent( obj, eventType, event, bubble ) { + var originalType = event.type; + event.type = eventType; + if ( bubble ) { + $.event.trigger( event, undefined, obj ); + } else { + $.event.dispatch.call( obj, event ); } + event.type = originalType; +} - $.event.special.taphold = { - setup: function(data, namespaces){ - var thisObject = this, - $this = $( thisObject ); - var timeout = null; - var duration = 500; - var maxMove = 5; - var oX, oY; - - // mousemove or touchmove callback - function mousemove_callback(e) { - var x = e.pageX || e.originalEvent.touches[0].pageX; - var y = e.pageY || e.originalEvent.touches[0].pageY; - - if (Math.abs(oX - x) > maxMove || Math.abs(oY - y) > maxMove) { - if (timeout) clearTimeout(timeout); - } - } +$.event.special.taphold = { + setup: function(data, namespaces){ + var thisObject = this, + $this = $( thisObject ); + var timeout = null; + var duration = 500; + var maxMove = 5; + var oX, oY; - // mouseup or touchend callback - function mouseup_callback(e) { - unbindDoc(); - if (timeout) clearTimeout(timeout); - } + // mousemove or touchmove callback + function mousemove_callback(e) { + var x = e.pageX || e.originalEvent.touches[0].pageX; + var y = e.pageY || e.originalEvent.touches[0].pageY; - var bindDoc = function() { - $document.on('mousemove', mousemove_callback); - $document.on('touchmove', mousemove_callback); - $document.on('mouseup', mouseup_callback); - $document.on('touchend', mouseup_callback); + if (Math.abs(oX - x) > maxMove || Math.abs(oY - y) > maxMove) { + if (timeout) clearTimeout(timeout); } + } - var unbindDoc = function() { - $document.unbind('mousemove', mousemove_callback); - $document.unbind('touchmove', mousemove_callback); - $document.unbind('mouseup', mouseup_callback); - $document.unbind('touchend', mouseup_callback); - } + // mouseup or touchend callback + function mouseup_callback(e) { + unbindDoc(); + if (timeout) clearTimeout(timeout); + } - // mousedown or touchstart callback - function mousedown_callback(e) { - // Only accept left click - if (e.type == 'mousedown' && e.originalEvent.button != 0) return; - oX = e.pageX || e.originalEvent.touches[0].pageX; - oY = e.pageY || e.originalEvent.touches[0].pageY; + var bindDoc = function() { + $document.on('mousemove', mousemove_callback); + $document.on('touchmove', mousemove_callback); + $document.on('mouseup', mouseup_callback); + $document.on('touchend', mouseup_callback); + } - bindDoc(); + var unbindDoc = function() { + $document.unbind('mousemove', mousemove_callback); + $document.unbind('touchmove', mousemove_callback); + $document.unbind('mouseup', mouseup_callback); + $document.unbind('touchend', mouseup_callback); + } - // set a timeout to call the longpress callback when time elapses - timeout = setTimeout(function() { - unbindDoc(); + // mousedown or touchstart callback + function mousedown_callback(e) { + // Only accept left click + if (e.type == 'mousedown' && e.originalEvent.button != 0) return; + oX = e.pageX || e.originalEvent.touches[0].pageX; + oY = e.pageY || e.originalEvent.touches[0].pageY; - triggerCustomEvent(thisObject, "taphold", $.Event( "taphold", { - target: e.target, - pageX: oX, - pageY: oY - } )); - }, duration); + bindDoc(); - e.stopPropagation(); - } + // set a timeout to call the longpress callback when time elapses + timeout = setTimeout(function() { + unbindDoc(); - // Browser Support - $this.on('mousedown', mousedown_callback); + triggerCustomEvent(thisObject, "taphold", $.Event( "taphold", { + target: e.target, + pageX: oX, + pageY: oY + } )); + }, duration); - // Mobile Support - $this.on('touchstart', mousedown_callback); - }, - teardown: function(namespaces){ - $(this).unbind(namespaces) - } - }; - - return { - bind: function(el, fn ) { - return el.bind("taphold", fn ); - }, - unbind: function() { - return el.unbind("taphold"); + e.stopPropagation(); } - }; -}); \ No newline at end of file + + // Browser Support + $this.on('mousedown', mousedown_callback); + + // Mobile Support + $this.on('touchstart', mousedown_callback); + }, + teardown: function(namespaces){ + $(this).unbind(namespaces) + } +}; + +module.exports = { + bind: function(el, fn ) { + return el.bind("taphold", fn ); + }, + unbind: function() { + return el.unbind("taphold"); + } +}; diff --git a/editor/utils/upload.js b/editor/utils/upload.js index 59fc3ed3..6539abe3 100644 --- a/editor/utils/upload.js +++ b/editor/utils/upload.js @@ -1,226 +1,225 @@ -define([ - 'hr/hr', - 'hr/promise', - 'hr/dom', - 'hr/utils' -],function(hr, Q, $, _) { - var logging = hr.Logger.addNamespace("uploader"); - - try { - if (XMLHttpRequest.prototype.sendAsBinary){} else { - XMLHttpRequest.prototype.sendAsBinary = function(datastr) { - function byteValue(x) { - return x.charCodeAt(0) & 0xff; - } - var ords = Array.prototype.map.call(datastr, byteValue); - var ui8a = new Uint8Array(ords); - this.send(ui8a); - } - } - } catch(e) {} - - var Uploader = hr.Class.extend({ - defaults: { - url: "", - data: {} - }, - - /* - * Constructor for the uploader - */ - initialize: function(){ - Uploader.__super__.initialize.apply(this, arguments); - - this.lock = false; - this.maxFileSize = 10*1048576; - - return this; - }, - - /* - * Connect to a input file - */ - connect: function(input) { - var self = this; - input.on("change", function(e) { - e.preventDefault(); - self.upload(this.files); - }); - }, +var $ = require("jquery"); +var Q = require("q"); +var _ = require("hr.utils"); +var Class = require("hr.class"); - /* - * Run upload - * @files : html5 files - */ - upload: function(files) { - var d = Q.defer(); - var totalFilesSize = 0; - var that = this; +var logger = require("hr.logger")("uploader"); - if (that.lock == true) { - return Q.reject("Upload already in progress"); +try { + if (XMLHttpRequest.prototype.sendAsBinary){} else { + XMLHttpRequest.prototype.sendAsBinary = function(datastr) { + function byteValue(x) { + return x.charCodeAt(0) & 0xff; } + var ords = Array.prototype.map.call(datastr, byteValue); + var ui8a = new Uint8Array(ords); + this.send(ui8a); + } + } +} catch(e) {} + +var Uploader = Class.extend({ + defaults: { + url: "", + data: {} + }, + + /* + * Constructor for the uploader + */ + initialize: function(){ + Uploader.__super__.initialize.apply(this, arguments); + + this.lock = false; + this.maxFileSize = 10*1048576; + + return this; + }, + + /* + * Connect to a input file + */ + connect: function(input) { + var self = this; + input.on("change", function(e) { + e.preventDefault(); + self.upload(this.files); + }); + }, + + + /* + * Run upload + * @files : html5 files + */ + upload: function(files) { + var d = Q.defer(); + var totalFilesSize = 0; + var that = this; + + if (that.lock == true) { + return Q.reject("Upload already in progress"); + } - // Calcul total files size - totalFilesSize = _.reduce(files, function(memo, file){ return memo + (file.size != null ? file.size : 0); }, 0); + // Calcul total files size + totalFilesSize = _.reduce(files, function(memo, file){ return memo + (file.size != null ? file.size : 0); }, 0); - _.reduce(files, function(d, file) { - return d.then(function() { - return that.uploadFile(file); - }); - }, Q({})).then(function() { - d.resolve(); - }, function(err) { - d.reject(err); - }, function(progress) { - d.notify(progress); + _.reduce(files, function(d, file) { + return d.then(function() { + return that.uploadFile(file); }); + }, Q({})).then(function() { + d.resolve(); + }, function(err) { + d.reject(err); + }, function(progress) { + d.notify(progress); + }); + + return d.promise; + }, + + /* + * Upload one file + */ + uploadFile: function(file) { + var that = this; + var d = Q.defer(); + var filename = file.webkitRelativePath || file.name; + + var error = function(err) { + logging.error("error uploading", filename, ":", err); + that.trigger("error", err); + that.lock = false; + d.reject(err); + } - return d.promise; - }, - - /* - * Upload one file - */ - uploadFile: function(file) { - var that = this; - var d = Q.defer(); - var filename = file.webkitRelativePath || file.name; - - var error = function(err) { - logging.error("error uploading", filename, ":", err); - that.trigger("error", err); - that.lock = false; - d.reject(err); - } + var progress = function(percent) { + logging.log("notify ", filename, percent); + that.trigger("state", percent); + d.notify({ + 'filename': filename, + 'percent': percent + }); + }; - var progress = function(percent) { - logging.log("notify ", filename, percent); - that.trigger("state", percent); - d.notify({ - 'filename': filename, - 'percent': percent - }); - }; - - var end = function(text) { - logging.log("end", text); - that.trigger("end", text); - that.lock = false; - d.resolve(text); - }; - - if (file.name == "." || file.name == "..") { - return Q(); - } + var end = function(text) { + logging.log("end", text); + that.trigger("end", text); + that.lock = false; + d.resolve(text); + }; - if (file.name == null || file.size == null || file.size >= that.maxFileSize) { - return Q.reject(new Error("Invalid file or file too big")); - } + if (file.name == "." || file.name == "..") { + return Q(); + } - that.lock = true; - - logging.log("upload file ", filename, " in ", that.options.url, file.size,"/", file.size); - - var xhr = new XMLHttpRequest(), - upload = xhr.upload, - start_time = new Date().getTime(), - uploadurl = that.options.url.replace(":file", filename); - - logging.log("start uploading ", filename); - - upload.file = file; - upload.downloadStartTime = start_time; - upload.currentStart = start_time; - upload.currentProgress = 0; - upload.startData = 0; - upload.addEventListener("progress",function(e){ - if (e.lengthComputable) { - var percentage = Math.round((e.loaded * 100) / file.size); - progress(percentage); - } - }, false); - - xhr.open("PUT", uploadurl, true); - xhr.onreadystatechange = function(e){ - if (xhr.status != 200) { - error(new Error(xhr.status+": "+xhr.responseText)); - e.preventDefault(); - return; - } - }; - - var formData = new FormData(); - formData.append(filename, file); - _.each(that.options.data, function(v, k) { - formData.append(k, v); - }); + if (file.name == null || file.size == null || file.size >= that.maxFileSize) { + return Q.reject(new Error("Invalid file or file too big")); + } - progress(0); - xhr.onload = function() { - if (xhr.status == 200) { - end(xhr.responseText || ""); - } - } + that.lock = true; - xhr.send(formData); + logging.log("upload file ", filename, " in ", that.options.url, file.size,"/", file.size); - return d.promise; - } - }, { - // Upload file - upload: function(options) { - var d = Q.defer(); - - options = _.defaults({}, options || {}, { - 'url': null, - 'data': {}, - 'directory': false, - 'multiple': true - }); + var xhr = new XMLHttpRequest(), + upload = xhr.upload, + start_time = new Date().getTime(), + uploadurl = that.options.url.replace(":file", filename); - // Uploader - var uploader = new Uploader(options); + logging.log("start uploading ", filename); - var $f = $("input.cb-file-uploader"); - if ($f.length == 0) { - var $f = $("", { - "type": "file", - "class": "cb-file-uploader" - }); - $f.appendTo($("body")); + upload.file = file; + upload.downloadStartTime = start_time; + upload.currentStart = start_time; + upload.currentProgress = 0; + upload.startData = 0; + upload.addEventListener("progress",function(e){ + if (e.lengthComputable) { + var percentage = Math.round((e.loaded * 100) / file.size); + progress(percentage); } + }, false); - $f.hide(); + xhr.open("PUT", uploadurl, true); + xhr.onreadystatechange = function(e){ + if (xhr.status != 200) { + error(new Error(xhr.status+": "+xhr.responseText)); + e.preventDefault(); + return; + } + }; + + var formData = new FormData(); + formData.append(filename, file); + _.each(that.options.data, function(v, k) { + formData.append(k, v); + }); + + progress(0); + xhr.onload = function() { + if (xhr.status == 200) { + end(xhr.responseText || ""); + } + } - $f.prop("webkitdirectory", options.directory); - $f.prop("directory", options.directory); - $f.prop("multiple", options.multiple); + xhr.send(formData); + + return d.promise; + } +}, { + // Upload file + upload: function(options) { + var d = Q.defer(); + + options = _.defaults({}, options || {}, { + 'url': null, + 'data': {}, + 'directory': false, + 'multiple': true + }); + + // Uploader + var uploader = new Uploader(options); + + var $f = $("input.cb-file-uploader"); + if ($f.length == 0) { + var $f = $("", { + "type": "file", + "class": "cb-file-uploader" + }); + $f.appendTo($("body")); + } - // Create file element for selection - $f.change(function(e) { - e.preventDefault(); + $f.hide(); + + $f.prop("webkitdirectory", options.directory); + $f.prop("directory", options.directory); + $f.prop("multiple", options.multiple); + + // Create file element for selection + $f.change(function(e) { + e.preventDefault(); - uploader.upload(e.currentTarget.files) - .progress(function(p) { - d.notify(p.percent); - }) - .then(function() { - d.resolve() - }, function(err) { - d.reject(err); - }) - .fin(function() { - $f.remove(); - }); + uploader.upload(e.currentTarget.files) + .progress(function(p) { + d.notify(p.percent); + }) + .then(function() { + d.resolve() + }, function(err) { + d.reject(err); + }) + .fin(function() { + $f.remove(); }); - $f.trigger('click'); + }); + $f.trigger('click'); - return d.promise; - } + return d.promise; + } - }); +}); - return Uploader; -}); \ No newline at end of file +module.exports = Uploader; diff --git a/editor/views/dialogs/container.js b/editor/views/dialogs/container.js index 29f9cc83..267d8980 100644 --- a/editor/views/dialogs/container.js +++ b/editor/views/dialogs/container.js @@ -1,89 +1,87 @@ -define([ - "hr/utils", - "hr/dom", - "hr/hr" -], function(_, $, hr) { - var DialogView = hr.View.extend({ - className: "component-dialog", - defaults: { - keyboard: true, - keyboardEnter: true, - - View: hr.View, - view: {}, - size: "medium" - }, - events: { - "keydown": "keydown" - }, - - initialize: function(options) { - DialogView.__super__.initialize.apply(this, arguments); - - // Bind keyboard - this.keydownHandler = _.bind(this.keydown, this) - if (this.options.keyboard) $(document).bind("keydown", this.keydownHandler); - - // Adapt style - this.$el.addClass("size-"+this.options.size); - - // Build view - this.view = new options.View(this.options.view, this); - }, - - render: function() { - this.view.render(); - this.view.appendTo(this); - - return this.ready(); - }, - - finish: function() { - this.open(); - return DialogView.__super__.finish.apply(this, arguments); - }, - - open: function() { - if (DialogView.current != null) DialogView.current.close(); - - this.$el.appendTo($("body")); - DialogView.current = this; - - this.trigger("open"); - - return this; - }, - - close: function(e, force) { - if (e) e.preventDefault(); - - // Unbind document keydown - $(document).unbind("keydown", this.keydownHandler); - - // Hide modal - this.trigger("close", force); - this.remove(); - - DialogView.current = null; - }, - - keydown: function(e) { - if (!this.options.keyboard) return; - - var key = e.keyCode || e.which; - - // Enter: valid - if (key == 13 && this.options.keyboardEnter) { - this.close(e); - } else - // Esc: close - if (key == 27) { - this.close(e, true); - } +var _ = require("hr.utils"); +var $ = require("jquery"); +var View = require("hr.view"); + +var DialogView = View.extend({ + className: "component-dialog", + defaults: { + keyboard: true, + keyboardEnter: true, + + View: View, + view: {}, + size: "medium" + }, + events: { + "keydown": "keydown" + }, + + initialize: function(options) { + DialogView.__super__.initialize.apply(this, arguments); + + // Bind keyboard + this.keydownHandler = _.bind(this.keydown, this) + if (this.options.keyboard) $(document).bind("keydown", this.keydownHandler); + + // Adapt style + this.$el.addClass("size-"+this.options.size); + + // Build view + this.view = new options.View(this.options.view, this); + }, + + render: function() { + this.view.render(); + this.view.appendTo(this); + + return this.ready(); + }, + + finish: function() { + this.open(); + return DialogView.__super__.finish.apply(this, arguments); + }, + + open: function() { + if (DialogView.current != null) DialogView.current.close(); + + this.$el.appendTo($("body")); + DialogView.current = this; + + this.trigger("open"); + + return this; + }, + + close: function(e, force) { + if (e) e.preventDefault(); + + // Unbind document keydown + $(document).unbind("keydown", this.keydownHandler); + + // Hide modal + this.trigger("close", force); + this.remove(); + + DialogView.current = null; + }, + + keydown: function(e) { + if (!this.options.keyboard) return; + + var key = e.keyCode || e.which; + + // Enter: valid + if (key == 13 && this.options.keyboardEnter) { + this.close(e); + } else + // Esc: close + if (key == 27) { + this.close(e, true); } - }, { - current: null, - }); + } +}, { + current: null, +}); - return DialogView; -}); \ No newline at end of file +module.exports = DialogView; diff --git a/editor/views/dialogs/input.js b/editor/views/dialogs/input.js index 9100623a..69717036 100644 --- a/editor/views/dialogs/input.js +++ b/editor/views/dialogs/input.js @@ -1,66 +1,66 @@ -define([ - "hr/utils", - "hr/dom", - "hr/hr", - "views/form" -], function(_, $, hr, FormView) { - var DialogInputView = hr.View.extend({ - className: "dialog-input", - defaults: { - className: "", - template: "", - value: true - }, - events: { - "click .do-close": "onClose", - "click .do-confirm": "onConfirm" - }, +var _ = require("hr.utils"); +var $ = require("jquery"); +var View = require("hr.view"); - initialize: function(options) { - DialogInputView.__super__.initialize.apply(this, arguments); +var FormView = require("../form"); - // Adapt style - this.$el.addClass(this.options.className); - // Value - this.value = this.options.value; - }, +var DialogInputView = View.extend({ + className: "dialog-input", + defaults: { + className: "", + template: "", + value: true + }, + events: { + "click .do-close": "onClose", + "click .do-confirm": "onConfirm" + }, - finish: function() { - this.$("input").first().select(); - return DialogInputView.__super__.finish.apply(this, arguments); - }, + initialize: function(options) { + DialogInputView.__super__.initialize.apply(this, arguments); - template: function() { - return this.options.template; - }, - templateContext: function() { - return { - options: this.options - }; - }, + // Adapt style + this.$el.addClass(this.options.className); - getValue: function() { - var selector = this.options.value; - if (_.isFunction(selector)) { - this.value = selector(this); - } else if (_.isString(selector)) { - this.value = this[selector](); - } + // Value + this.value = this.options.value; + }, - return this.value; - }, + finish: function() { + this.$("input").first().select(); + return DialogInputView.__super__.finish.apply(this, arguments); + }, - onConfirm: function(e) { - if (e) e.preventDefault(); + template: function() { + return this.options.template; + }, + templateContext: function() { + return { + options: this.options + }; + }, - this.parent.close(e); - }, - onClose: function(e) { - if (e) e.preventDefault(); - this.parent.close(null, true); + getValue: function() { + var selector = this.options.value; + if (_.isFunction(selector)) { + this.value = selector(this); + } else if (_.isString(selector)) { + this.value = this[selector](); } - }); - return DialogInputView; -}); \ No newline at end of file + return this.value; + }, + + onConfirm: function(e) { + if (e) e.preventDefault(); + + this.parent.close(e); + }, + onClose: function(e) { + if (e) e.preventDefault(); + this.parent.close(null, true); + } +}); + +module.exports = DialogInputView; diff --git a/editor/views/dialogs/list.js b/editor/views/dialogs/list.js index 3bc6e1b3..e9f3c7a8 100644 --- a/editor/views/dialogs/list.js +++ b/editor/views/dialogs/list.js @@ -1,213 +1,214 @@ -define([ - "hr/utils", - "hr/dom", - "hr/hr", - "utils/string", - "views/dialogs/input" -], function(_, $, hr, string, DialogInputView) { - var ListItem = hr.List.Item.extend({ - className: "list-item", - - initialize: function(options) { - ListItem.__super__.initialize.apply(this, arguments); - - this.dialogContent = this.list.parent; - }, - - template: function() { - return this.dialogContent.options.template; - }, - templateContext: function() { - return { - item: this.model - }; +var _ = require("hr.utils"); +var $ = require("jquery"); +var View = require("hr.view"); +var ListView = require("hr.list"); + +var string = require("../../utils/string"); +var DialogInputView = require("./input"); + + +var ListItem = ListView.Item.extend({ + className: "list-item", + + initialize: function(options) { + ListItem.__super__.initialize.apply(this, arguments); + + this.dialogContent = this.list.parent; + }, + + template: function() { + return this.dialogContent.options.template; + }, + templateContext: function() { + return { + item: this.model + }; + } +}); + +var ListView = ListView.extend({ + Item: ListItem, + className: "ui-content-list" +}); + +var DialogListView = DialogInputView.extend({ + defaults: { + textIndex: function(model) { return JSON.stringify(model.toJSON()); } + }, + className: "dialog-list", + + initialize: function() { + DialogListView.__super__.initialize.apply(this, arguments); + + // Source for items + this.results = new Collection(); + this.source = this.options.source; + + if (this.options.source instanceof Collection) { + // Source is a collection + this.results = new this.options.source.constructor() + this.source = function(q) { + return this.options.source.filter(function(model) { + return this.searchText(model, q); + }, this); + }.bind(this); } - }); - - var ListView = hr.List.extend({ - Item: ListItem, - className: "ui-content-list" - }); - - var DialogListView = DialogInputView.extend({ - defaults: { - textIndex: function(model) { return JSON.stringify(model.toJSON()); } - }, - className: "dialog-list", - - initialize: function() { - DialogListView.__super__.initialize.apply(this, arguments); - - // Source for items - this.results = new hr.Collection(); - this.source = this.options.source; - - if (this.options.source instanceof hr.Collection) { - // Source is a collection - this.results = new this.options.source.constructor() - this.source = function(q) { - return this.options.source.filter(function(model) { - return this.searchText(model, q); - }, this); - }.bind(this); - } - // Filter for items - this.$filterInput = $("", { - 'type': "text", - 'placeholder': this.options.placeholder - }); - this.keydownInterval = null; - this.$filterInput.on("keydown", this.onFilterKeydown.bind(this)); - this.$filterInput.on("keyup", this.onFilterKeyup.bind(this)); - this.$filterInput.appendTo(this.$el); - - // Items list - this.list = new ListView({ - collection: this.results - }, this); - this.list.appendTo(this.$el); - - // Focus input - this.listenTo(this.parent, "open", function() { - this.$filterInput.focus(); - this.doSearch(""); - this.selectItem(0); + // Filter for items + this.$filterInput = $("", { + 'type': "text", + 'placeholder': this.options.placeholder + }); + this.keydownInterval = null; + this.$filterInput.on("keydown", this.onFilterKeydown.bind(this)); + this.$filterInput.on("keyup", this.onFilterKeyup.bind(this)); + this.$filterInput.appendTo(this.$el); + + // Items list + this.list = new ListView({ + collection: this.results + }, this); + this.list.appendTo(this.$el); + + // Focus input + this.listenTo(this.parent, "open", function() { + this.$filterInput.focus(); + this.doSearch(""); + this.selectItem(0); + }); + }, + + render: function() { + return this.ready(); + }, + + searchText: function(model, q) { + var t = this.options.textIndex(model); + + var words = q.split("") + + t = t.toLowerCase(); + q = q.toLowerCase(); + + return _.every(q.split(" "), function(_q) { + return t.search(_q) !== -1; + }); + }, + + doSearch: function(query) { + var that = this, toRemove = []; + if (this.list.collection.query == query) return; + + if (this.list.collection.query && query + && query.indexOf(this.list.collection.query) == 0) { + // Continue current search + this.list.collection.query = query; + this.list.collection.each(function(model) { + if (!that.searchText(model, query)) { + toRemove.push(model); + } }); - }, - - render: function() { - return this.ready(); - }, - - searchText: function(model, q) { - var t = this.options.textIndex(model); - - var words = q.split("") - - t = t.toLowerCase(); - q = q.toLowerCase(); + this.list.collection.remove(toRemove); + //this.list.collection.sort(); + this.selectItem(this.getSelectedItem()); + } else { + // Different search + this.list.collection.query = query; + this.list.collection.reset([]); + + Q() + .then(function() { + return that.source(query); + }) + .then(function(result) { + that.list.collection.add(_.filter(result, that.options.filter)); + that.selectItem(that.getSelectedItem()); + }, console.error.bind(console)); + } + }, - return _.every(q.split(" "), function(_q) { - return t.search(_q) !== -1; - }); - }, - - doSearch: function(query) { - var that = this, toRemove = []; - if (this.list.collection.query == query) return; - - if (this.list.collection.query && query - && query.indexOf(this.list.collection.query) == 0) { - // Continue current search - this.list.collection.query = query; - this.list.collection.each(function(model) { - if (!that.searchText(model, query)) { - toRemove.push(model); - } - }); - this.list.collection.remove(toRemove); - //this.list.collection.sort(); - this.selectItem(this.getSelectedItem()); - } else { - // Different search - this.list.collection.query = query; - this.list.collection.reset([]); - - Q() - .then(function() { - return that.source(query); - }) - .then(function(result) { - that.list.collection.add(_.filter(result, that.options.filter)); - that.selectItem(that.getSelectedItem()); - }, console.error.bind(console)); - } - }, + selectItem: function(i) { + var i, boxH = this.list.$el.height(); - selectItem: function(i) { - var i, boxH = this.list.$el.height(); + this.selected = i; - this.selected = i; + if (this.selected >= this.list.collection.size()) this.selected = this.list.collection.size() - 1; + if (this.selected < 0) this.selected = 0; - if (this.selected >= this.list.collection.size()) this.selected = this.list.collection.size() - 1; - if (this.selected < 0) this.selected = 0; + i = 0; + this.list.collection.each(function(model) { + var y, h, item = this.list.items[model.id]; + item.$el.toggleClass("active", i == this.selected); - i = 0; - this.list.collection.each(function(model) { - var y, h, item = this.list.items[model.id]; - item.$el.toggleClass("active", i == this.selected); - - if (i == this.selected) { - h = item.$el.outerHeight(); - y = item.$el.position().top; - - if (y > (boxH-(h/2))) { - this.list.$el.scrollTop((i+1)*h - boxH) - } else if (y <= (h/2)) { - this.list.$el.scrollTop((i)*h) - } - } + if (i == this.selected) { + h = item.$el.outerHeight(); + y = item.$el.position().top; - i = i + 1; - }, this); - }, - - getSelectedItem: function() { - var _ret = 0; - this.list.collection.each(function(model, i) { - var item = this.list.items[model.id]; - if (item.$el.hasClass("active")) { - _ret = i; - return false; + if (y > (boxH-(h/2))) { + this.list.$el.scrollTop((i+1)*h - boxH) + } else if (y <= (h/2)) { + this.list.$el.scrollTop((i)*h) } - }, this); - return _ret; - }, + } - getValue: function() { - return this.list.collection.at(this.getSelectedItem()); - }, + i = i + 1; + }, this); + }, + + getSelectedItem: function() { + var _ret = 0; + this.list.collection.each(function(model, i) { + var item = this.list.items[model.id]; + if (item.$el.hasClass("active")) { + _ret = i; + return false; + } + }, this); + return _ret; + }, - onFilterKeydown: function(e) { - var key = e.which || e.keyCode; + getValue: function() { + return this.list.collection.at(this.getSelectedItem()); + }, - if (key == 38 || key == 40 || key == 13) { - e.preventDefault(); - } + onFilterKeydown: function(e) { + var key = e.which || e.keyCode; - var interval = function() { - var selected = this.getSelectedItem(); - var pSelected = selected; + if (key == 38 || key == 40 || key == 13) { + e.preventDefault(); + } - if (key == 38) { - /* UP */ - selected = selected - 1; - } else if (key == 40) { - /* DOWN */ - selected = selected + 1; - } - if (selected != pSelected) this.selectItem(selected); - }.bind(this); + var interval = function() { + var selected = this.getSelectedItem(); + var pSelected = selected; - if (this.keydownInterval) { - clearInterval(this.keydownInterval); - this.keydownInterval = null; + if (key == 38) { + /* UP */ + selected = selected - 1; + } else if (key == 40) { + /* DOWN */ + selected = selected + 1; } - interval(); - this.keydownInterval = setInterval(interval, 600); - }, - onFilterKeyup: function(e) { - var q = this.$filterInput.val().toLowerCase(); + if (selected != pSelected) this.selectItem(selected); + }.bind(this); + + if (this.keydownInterval) { + clearInterval(this.keydownInterval); + this.keydownInterval = null; + } + interval(); + this.keydownInterval = setInterval(interval, 600); + }, + onFilterKeyup: function(e) { + var q = this.$filterInput.val().toLowerCase(); - this.doSearch(q); + this.doSearch(q); - if (this.keydownInterval) { - clearInterval(this.keydownInterval); - this.keydownInterval = null; - } + if (this.keydownInterval) { + clearInterval(this.keydownInterval); + this.keydownInterval = null; } - }); + } +}); - return DialogListView; -}); \ No newline at end of file +module.exports = DialogListView; diff --git a/editor/views/form.js b/editor/views/form.js index 225772d2..bc0d278c 100644 --- a/editor/views/form.js +++ b/editor/views/form.js @@ -1,181 +1,179 @@ -define([ - "hr/utils", - "hr/dom", - "hr/hr" -], function(_, $, hr) { - - var GETTER = { - 'boolean': function() { - return $(this).is(":checked"); - }, - 'string': function() { - return $(this).val(); - }, - 'number': function() { - return parseInt($(this).val()); - } - }; - - var RENDERER = { - 'boolean': function(propertyName, property, value) { - return $("", { - 'type': "checkbox", - 'checked': value === true, - 'name': propertyName - }); - }, - - 'number': function(propertyName, property, value) { - return $("", { - 'type': "number", - 'value': value, - 'name': propertyName, - 'min': property.minimum, - 'max': property.maximum, - 'step': property.multipleOf || 1 - }); - }, - - 'string': function(propertyName, property, value) { - if (property['enum']) return RENDERER.select.apply(this, arguments); - - return $("", { - 'type': "text", - 'value': value, - 'name': propertyName - }); - }, - - 'select': function(propertyName, property, value) { - var $select = $("", { + 'type': "checkbox", + 'checked': value === true, + 'name': propertyName + }); + }, + + 'number': function(propertyName, property, value) { + return $("", { + 'type': "number", + 'value': value, + 'name': propertyName, + 'min': property.minimum, + 'max': property.maximum, + 'step': property.multipleOf || 1 + }); + }, + + 'string': function(propertyName, property, value) { + if (property['enum']) return RENDERER.select.apply(this, arguments); + + return $("", { + 'type': "text", + 'value': value, + 'name': propertyName + }); + }, + + 'select': function(propertyName, property, value) { + var $select = $(" +
        +
        + + +
        +
        +
        +
        +
        + +
        +
        + +
        +
        - -
        - - -
        \ No newline at end of file diff --git a/editor/resources/templates/dialogs/schema.html b/editor/resources/templates/dialogs/schema.html index d5ae55a6..70699a9d 100644 --- a/editor/resources/templates/dialogs/schema.html +++ b/editor/resources/templates/dialogs/schema.html @@ -1,5 +1,7 @@ -

        <%- options.schema.title %>

        - +
        + <%- options.schema.title %> +
        +
        <% _.each(options.schema.properties, function(property, key) { var value = options.defaultValues[key] || property.default; @@ -16,8 +18,14 @@
        <% } %> <% }); %> - -
        - - -
        \ No newline at end of file +
        +
        +
        +
        + +
        +
        + +
        +
        +
        From 0a069adfc5b8231361f9f7d2e470cfb072b3403b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sat, 11 Apr 2015 22:46:11 -0500 Subject: [PATCH 279/351] Fix option 'isHtml' for alert dialogs --- editor/resources/templates/dialogs/alert.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/resources/templates/dialogs/alert.html b/editor/resources/templates/dialogs/alert.html index 0bf547a8..d65608ba 100644 --- a/editor/resources/templates/dialogs/alert.html +++ b/editor/resources/templates/dialogs/alert.html @@ -1,5 +1,5 @@
        -<% if (options.isHtml) { %> +<% if (!options.isHtml) { %>

        <%- options.text %>

        <% } else { %> <%= options.text %> From 60d1d78b017111b4b4e48df6dfe0990754a2d531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sun, 12 Apr 2015 06:56:25 -0500 Subject: [PATCH 280/351] Focus first input after dialog creation --- editor/views/dialogs/input.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/editor/views/dialogs/input.js b/editor/views/dialogs/input.js index e98be5d1..5d605269 100644 --- a/editor/views/dialogs/input.js +++ b/editor/views/dialogs/input.js @@ -28,7 +28,10 @@ var DialogInputView = View.Template.extend({ }, finish: function() { - this.$("input").first().select(); + var that = this; + _.defer(function() { + that.$("input").first().focus(); + }); return DialogInputView.__super__.finish.apply(this, arguments); }, From b8b6c637006995e276a2821624a4a86fd409dae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sun, 12 Apr 2015 08:36:13 -0500 Subject: [PATCH 281/351] Improve command resolver to use pattern --- editor/collections/commands.js | 20 +++++++++++++++++++- editor/models/command.js | 20 ++++++++++++++++++++ editor/models/file.js | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/editor/collections/commands.js b/editor/collections/commands.js index 3a71f014..9ae0115e 100644 --- a/editor/collections/commands.js +++ b/editor/collections/commands.js @@ -27,12 +27,30 @@ var Commands = Collection.extend({ // Run a command run: function(_cmd, args) { - var cmd = this.get(_cmd); + var cmd = this.resolve(_cmd); if (!cmd) return Q.reject(new Error("Command not found: '"+_cmd+"'")); return cmd.run(args); }, + // Resolve a command + resolve: function(_cmd) { + return _.chain(this.models) + .map(function(m) { + return { + cmd: m, + score: m.resolve(_cmd) + }; + }) + .filter(function(r) { + return r.score > 0; + }) + .sortBy("score") + .pluck("cmd") + .last() + .value(); + }, + // Set context setContext: function(id, data) { logger.log("update context", id); diff --git a/editor/models/command.js b/editor/models/command.js index ad4ecabd..24b64aeb 100644 --- a/editor/models/command.js +++ b/editor/models/command.js @@ -88,6 +88,26 @@ var Command = Model.extend({ || !this.collection || !this.collection.context || _.contains(context, this.collection.context.type)); + }, + + // Valid a command name against this command + resolve: function(cmd) { + var score = 0; + var parts = cmd.split("."); + var thisParts = this.get("id").split("."); + + _.each(parts, function(part, i) { + if (!thisParts[i]) return false; + + var r = new RegExp(thisParts[i]); + if (part.match(r) == null) { + return false; + } + + score = score + 1; + }); + + return score/thisParts.length; } }); diff --git a/editor/models/file.js b/editor/models/file.js index 6d31b9f1..d917e11c 100644 --- a/editor/models/file.js +++ b/editor/models/file.js @@ -54,7 +54,7 @@ var File = Model.extend({ // Open this file open: function() { - return commands.run("file.open", { + return commands.run("file.open."+this.getExtension().slice(1), { path: this.get("path") }); }, From 9b655a7b420ea3789fad65e6a18459d58d01e22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sun, 12 Apr 2015 09:34:34 -0500 Subject: [PATCH 282/351] Return mime type in fs rpc api --- lib/services/fs.js | 4 +++- package.json | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/services/fs.js b/lib/services/fs.js index 06ac7fe5..75f165ce 100644 --- a/lib/services/fs.js +++ b/lib/services/fs.js @@ -4,6 +4,7 @@ var fs = require('fs'); var path = require('path'); var wrench = require('wrench'); var stream = require('stream'); +var mime = require('mime'); var workspace = require('../workspace'); var base64 = require('../utils/base64'); @@ -16,7 +17,8 @@ var fileInfos = function(_path, stat) { 'size': stat.size, 'mtime': stat.mtime.getTime(), 'atime': stat.atime.getTime(), - 'mode': stat.mode + 'mode': stat.mode, + 'mime': mime.lookup(_path) }; }; diff --git a/package.json b/package.json index 8bf30982..6fa0009e 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,8 @@ "open": "0.0.5", "ini": "1.2.1", "basic-auth-connect": "1.0.0", - "connect-multiparty": "1.1.0" + "connect-multiparty": "1.1.0", + "mime": "1.3.4" }, "devDependencies": { "gulp": "^3.8.11", From 35732e3581822cc57f56d28ab9096578c4d6bf36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sun, 12 Apr 2015 09:35:03 -0500 Subject: [PATCH 283/351] Make it possible to read as base64 --- editor/models/file.js | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/editor/models/file.js b/editor/models/file.js index d917e11c..1771ec73 100644 --- a/editor/models/file.js +++ b/editor/models/file.js @@ -17,7 +17,8 @@ var File = Model.extend({ size: 0, mtime: 0, atime: 0, - buffer: null + buffer: null, + mime: "text/plain" }, idAttribute: "name", @@ -103,14 +104,25 @@ var File = Model.extend({ }, // Read file content - read: function() { - if (this.isBuffer()) return Q(this.get("buffer")); + read: function(opts) { + opts = _.defaults(opts || {}, { + base64: false + }); - return rpc.execute("fs/read", { - 'path': this.get("path") - }) - .get("content") - .then(hash.atob); + var p; + + + if (this.isBuffer()) p = Q(hash.btoa(this.get("buffer"))); + else { + p = rpc.execute("fs/read", { + 'path': this.get("path") + }) + .get("content"); + } + + if (!opts.base64) p = p.then(hash.atob); + + return p; }, // Write file content From 6f17e08e42bfe287f01de5897c1accfb10d436c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sun, 12 Apr 2015 09:38:10 -0500 Subject: [PATCH 284/351] Add image package as default --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 6fa0009e..515f6856 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "merge-stream": "0.1.7" }, "packageDependencies": { + "image": "CodeboxIDE/package-image#1.0.0", "about": "CodeboxIDE/package-about", "command-palette": "CodeboxIDE/package-command-palette", "files-tree": "CodeboxIDE/package-files-tree", From 2018c5ddaf955ae69487db41ed3bbcc511b57f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sun, 12 Apr 2015 09:45:27 -0500 Subject: [PATCH 285/351] Fix plugins loading error dialog --- editor/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/main.js b/editor/main.js index 636ac5ae..05f1f09c 100644 --- a/editor/main.js +++ b/editor/main.js @@ -58,7 +58,7 @@ Q.delay(500) }).join("\n")+ "
      "; } - return dialogs.alert(message, { html: true }) + return dialogs.alert(message, { isHtml: true }) }); }) .then(app.start.bind(app)) From e7822acea4ea14375821129fbfc33db8d40b63ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sun, 12 Apr 2015 10:04:14 -0500 Subject: [PATCH 286/351] Improve rpc error handling --- editor/core/rpc.js | 12 ++++-------- editor/main.js | 1 + 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/editor/core/rpc.js b/editor/core/rpc.js index 4a9cb157..ccc75be7 100644 --- a/editor/core/rpc.js +++ b/editor/core/rpc.js @@ -12,14 +12,10 @@ rpc.defaultMethod({ .then(function(res) { return res.data.result || {}; }, function(err) { - try { - var errContent = JSON.parse(err.httpRes); - var e = new Error(errContent.error || err.message); - e.code = errContent.code || err.status || 500; - return Q.reject(e); - } catch(e) { - return Q.reject(err); - } + var e = new Error(err.data.error || err); + e.code = err.status; + + return Q.reject(e); }); } }); diff --git a/editor/main.js b/editor/main.js index 05f1f09c..461f2560 100644 --- a/editor/main.js +++ b/editor/main.js @@ -64,5 +64,6 @@ Q.delay(500) .then(app.start.bind(app)) .fail(function(err) { logger.error("Error:", err.message || "", err.stack || err); + return dialogs.error(err); }); From 11d950fb9ea316656dd4986c25a582273677f484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Sun, 12 Apr 2015 10:06:57 -0500 Subject: [PATCH 287/351] Don't fail if error loading settings locally --- lib/configs/local.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/configs/local.js b/lib/configs/local.js index b78160c0..c3a7bdc1 100644 --- a/lib/configs/local.js +++ b/lib/configs/local.js @@ -23,8 +23,8 @@ module.exports = function(options) { options.hooks = _.defaults(options.hooks, { 'settings.get': function(args) { return Q.nfcall(fs.readFile, SETTINGS_FILE, "utf-8") - .fail(_.constant("{}")) .then(JSON.parse) + .fail(_.constant({})) .then(function(config) { if (!config[options.id]) config[options.id] = {}; return config[options.id][args.user] || {}; @@ -34,8 +34,8 @@ module.exports = function(options) { return Q.nfcall(fs.readFile, SETTINGS_FILE, "utf-8") - .fail(_.constant("{}")) .then(JSON.parse) + .fail(_.constant({})) .then(function(config) { if (!config[options.id]) config[options.id] = {}; config[options.id][args.user] = args.settings; From 92af1a4c0146c179dfc6c80192ddff688f408606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Mon, 13 Apr 2015 14:12:16 -0500 Subject: [PATCH 288/351] Fix commands resolving --- editor/models/command.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/models/command.js b/editor/models/command.js index 24b64aeb..e03d045c 100644 --- a/editor/models/command.js +++ b/editor/models/command.js @@ -107,7 +107,7 @@ var Command = Model.extend({ score = score + 1; }); - return score/thisParts.length; + return score/parts.length; } }); From 509ae7fda7c70b819d3ab75c4826b9f128062fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Mon, 13 Apr 2015 14:38:10 -0500 Subject: [PATCH 289/351] Add method dialogs.input --- editor/utils/dialogs.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/editor/utils/dialogs.js b/editor/utils/dialogs.js index e40eaacb..47dc812d 100644 --- a/editor/utils/dialogs.js +++ b/editor/utils/dialogs.js @@ -130,5 +130,6 @@ module.exports = { confirm: openConfirm, prompt: openPrompt, list: openList, - schema: openSchema + schema: openSchema, + input: openInput }; From 10576d90a89fc8e6369ee94cf6c4359d9b7e4382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Mon, 13 Apr 2015 14:38:23 -0500 Subject: [PATCH 290/351] Give http get access to workspace fs --- editor/models/file.js | 5 +++++ lib/index.js | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/editor/models/file.js b/editor/models/file.js index 1771ec73..f302aba9 100644 --- a/editor/models/file.js +++ b/editor/models/file.js @@ -125,6 +125,11 @@ var File = Model.extend({ return p; }, + // Access url + accessUrl: function() { + return "/fs/"+this.get("path"); + }, + // Write file content write: function(content) { var that = this; diff --git a/lib/index.js b/lib/index.js index 4fae230e..d82dbc1e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -115,6 +115,11 @@ var start = function(config) { // RPC services app.use('/rpc', rpc.router); + // Fs direct access + app.use('/fs', _.memoize(function(req, res, next) { + return express.static(workspace.root()).apply(this, arguments); + })); + // Error handling app.use(function(req, res, next) { var e = new Error("Page not found"); From cde12b9c4f47071ffdc2c5421700eff8aaaf71b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Mon, 13 Apr 2015 14:45:42 -0500 Subject: [PATCH 291/351] Fix fs static access middleware --- lib/index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/index.js b/lib/index.js index d82dbc1e..69d1f597 100644 --- a/lib/index.js +++ b/lib/index.js @@ -116,9 +116,11 @@ var start = function(config) { app.use('/rpc', rpc.router); // Fs direct access - app.use('/fs', _.memoize(function(req, res, next) { - return express.static(workspace.root()).apply(this, arguments); - })); + var _fsmiddleware; + app.use('/fs', function(req, res, next) { + if (!_fsmiddleware) _fsmiddleware = express.static(workspace.root()); + return _fsmiddleware.apply(this, arguments); + }); // Error handling app.use(function(req, res, next) { From 0840054b33a42e9b1b626158e04f4f70c4d56d88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Mon, 13 Apr 2015 15:30:59 -0500 Subject: [PATCH 292/351] Accept multiple command contexts --- editor/collections/commands.js | 9 +++------ editor/models/command.js | 13 ++++++------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/editor/collections/commands.js b/editor/collections/commands.js index 9ae0115e..75d11248 100644 --- a/editor/collections/commands.js +++ b/editor/collections/commands.js @@ -52,12 +52,9 @@ var Commands = Collection.extend({ }, // Set context - setContext: function(id, data) { - logger.log("update context", id); - this.context = { - 'type': id, - 'data': data - }; + setContext: function(ctx) { + logger.log("update context", _.keys(ctx)); + this.context = ctx || {}; this.trigger("context", this.context); } }); diff --git a/editor/models/command.js b/editor/models/command.js index e03d045c..a828f535 100644 --- a/editor/models/command.js +++ b/editor/models/command.js @@ -69,7 +69,7 @@ var Command = Model.extend({ return Q() .then(function() { - return that.get("run").apply(that, [ args || {}, that.collection.context.data, origin ]); + return that.get("run").apply(that, [ args || {}, that.collection.context, origin ]); }) .fail(function(err) { logger.error("Command failed", err); @@ -84,13 +84,12 @@ var Command = Model.extend({ // Valid context isValidContext: function() { var context = this.get("context") || []; - return (context.length == 0 - || !this.collection - || !this.collection.context - || _.contains(context, this.collection.context.type)); + var currentContext = _.keys(this.collection.context); + + return _.difference(context, currentContext).length == 0; }, - // Valid a command name against this command + // Valid a command name against this command and return a match score resolve: function(cmd) { var score = 0; var parts = cmd.split("."); @@ -107,7 +106,7 @@ var Command = Model.extend({ score = score + 1; }); - return score/parts.length; + return (score/parts.length) + (score/thisParts.length); } }); From ef772b72af9a88727578bb79907fcf6da969fae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Tue, 14 Apr 2015 10:04:30 -0500 Subject: [PATCH 293/351] Change method name hasValidContext --- editor/models/command.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/models/command.js b/editor/models/command.js index a828f535..ea95146c 100644 --- a/editor/models/command.js +++ b/editor/models/command.js @@ -63,7 +63,7 @@ var Command = Model.extend({ var that = this; // Check context - if (!this.isValidContext()) return Q(); + if (!this.hasValidContext()) return Q(); logger.log("Run", this.get("id")); @@ -82,7 +82,7 @@ var Command = Model.extend({ }, // Valid context - isValidContext: function() { + hasValidContext: function() { var context = this.get("context") || []; var currentContext = _.keys(this.collection.context); From a2f570ad2517fe68094c385ac34f63b29b69b303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Tue, 14 Apr 2015 10:04:43 -0500 Subject: [PATCH 294/351] Improve rpc error logging --- lib/rpc.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rpc.js b/lib/rpc.js index 097bae53..68a6d60d 100644 --- a/lib/rpc.js +++ b/lib/rpc.js @@ -64,7 +64,7 @@ var init = function() { var method = service[req.params.method]; if (!method) { - var e = new Error("Methodnot found"); + var e = new Error("Method not found"); e.code = 404; return next(e); } @@ -79,7 +79,7 @@ var init = function() { }); }) .fail(function(err) { - logger.error("Error with method '"+method+"'"); + logger.error("Error with method '"+req.params.method+"'"); logger.exception(err, false); res.send(500, { error: err.message || err, From 1fe82128d1a9c55668072fe74798dc20a16af8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Tue, 14 Apr 2015 10:13:57 -0500 Subject: [PATCH 295/351] Add state "enabled" for commands --- editor/models/command.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/editor/models/command.js b/editor/models/command.js index ea95146c..96977ee0 100644 --- a/editor/models/command.js +++ b/editor/models/command.js @@ -27,7 +27,13 @@ var Command = Model.extend({ arguments: [], // Keyboard shortcuts - shortcuts: [] + shortcuts: [], + + // Hidden from command palette + hidden: false, + + // Disabled (not runnable) + enabled: true }, // Constructor @@ -63,7 +69,7 @@ var Command = Model.extend({ var that = this; // Check context - if (!this.hasValidContext()) return Q(); + if (!this.isRunnable()) return Q(); logger.log("Run", this.get("id")); @@ -107,6 +113,11 @@ var Command = Model.extend({ }); return (score/parts.length) + (score/thisParts.length); + }, + + // Check if command is runnable + isRunnable: function() { + return this.hasValidContext() && this.get("enabled"); } }); From 51eff0fa87426675bd91a70b0ee35133ea4c06e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Tue, 14 Apr 2015 11:40:54 -0500 Subject: [PATCH 296/351] Fix command resolving for short command --- editor/models/command.js | 1 + lib/configs/local.js | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/models/command.js b/editor/models/command.js index 96977ee0..cc10352f 100644 --- a/editor/models/command.js +++ b/editor/models/command.js @@ -112,6 +112,7 @@ var Command = Model.extend({ score = score + 1; }); + if (score < thisParts.length) return 0; return (score/parts.length) + (score/thisParts.length); }, diff --git a/lib/configs/local.js b/lib/configs/local.js index c3a7bdc1..42dbcedc 100644 --- a/lib/configs/local.js +++ b/lib/configs/local.js @@ -30,9 +30,8 @@ module.exports = function(options) { return config[options.id][args.user] || {}; }); }, - 'settings.set': function(args) { - + 'settings.set': function(args) { return Q.nfcall(fs.readFile, SETTINGS_FILE, "utf-8") .then(JSON.parse) .fail(_.constant({})) From e2a92c2481d5d35b1deb94d66834f8bf7f90042d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Wed, 15 Apr 2015 11:59:42 -0500 Subject: [PATCH 297/351] Fix size of dialogs --- editor/resources/stylesheets/ui/dialogs.less | 23 ++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/editor/resources/stylesheets/ui/dialogs.less b/editor/resources/stylesheets/ui/dialogs.less index 302eb1cd..00938ba2 100644 --- a/editor/resources/stylesheets/ui/dialogs.less +++ b/editor/resources/stylesheets/ui/dialogs.less @@ -6,12 +6,23 @@ left: 0px; right: 0px; background: rgba(0, 0, 0, 0.4); + overflow-y: auto; + + &.size-large .dialog-wrapper { + width: @dialog-size-large; + margin-left: -@dialog-size-large/2; + } + + &.size-small .dialog-wrapper { + width: @dialog-size-small; + margin-left: -@dialog-size-small/2; + } .dialog-wrapper { position: absolute; z-index: 1001; - top: 10%; + margin: 2% 0px; left: 50%; width: @dialog-size-medium; @@ -19,16 +30,6 @@ background: @color-0-1; - &.size-large { - width: @dialog-size-large; - margin-left: -@dialog-size-large/2; - } - - &.size-small { - width: @dialog-size-small; - margin-left: -@dialog-size-small/2; - } - .dialog-list { input { width: 100%; From b63b3d0f3a3c83270c2d28f85b951cb9dfbe35f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Wed, 15 Apr 2015 14:09:27 -0500 Subject: [PATCH 298/351] Add more packages as default (ctags, audio, image) --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 515f6856..a3219255 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,6 @@ "merge-stream": "0.1.7" }, "packageDependencies": { - "image": "CodeboxIDE/package-image#1.0.0", "about": "CodeboxIDE/package-about", "command-palette": "CodeboxIDE/package-command-palette", "files-tree": "CodeboxIDE/package-files-tree", @@ -95,7 +94,10 @@ "find": "CodeboxIDE/package-find", "git": "CodeboxIDE/package-git", "settings": "CodeboxIDE/package-settings", - "menubar": "CodeboxIDE/package-menubar" + "menubar": "CodeboxIDE/package-menubar", + "image": "CodeboxIDE/package-image#1.0.0", + "ctags": "CodeboxIDE/package-ctags", + "audio": "CodeboxIDE/package-audio" }, "scripts": { "test": "export TESTING=true; mocha --reporter list" From 628253424f912b4963b65a68c1de8f93d6fc0cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Wed, 15 Apr 2015 16:39:10 -0500 Subject: [PATCH 299/351] Add logs for package events --- lib/packages.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/packages.js b/lib/packages.js index 7e0326ee..8085d145 100644 --- a/lib/packages.js +++ b/lib/packages.js @@ -16,9 +16,11 @@ var manager = new Packager({ }); manager.on("add", function(pkg) { + logger.log("add package", pkg.pkg.name); events.emit("packages:add", pkg.infos()); }); manager.on("remove", function(pkg) { + logger.log("remove package", pkg.pkg.name); events.emit("packages:remove", pkg.infos()); }); manager.on("log", function(log) { From 31618f686f04cb8c3724659b4a6ec162792e4647 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 16 Apr 2015 09:29:38 -0500 Subject: [PATCH 300/351] Update happy rhino and use dedupe --- gulpfile.js | 8 +++++++- package.json | 25 +++++++++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index a2c71e1a..8beab60b 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,6 +10,7 @@ var rename = require('gulp-rename'); var uglify = require('gulp-uglify'); var stringify = require('stringify'); var merge = require('merge-stream'); +var exec = require('child_process').exec; // Compile Javascript gulp.task('scripts', function() { @@ -23,6 +24,11 @@ gulp.task('scripts', function() { .pipe(gulp.dest('./build/static/js')); }); +// Dedupe modules +gulp.task('dedupe', function (cb) { + exec('npm dedupe', cb); +}) + // Copy html gulp.task('html', function() { return gulp.src('editor/index.html') @@ -68,5 +74,5 @@ gulp.task('clean', function(cb) { }); gulp.task('default', function(cb) { - runSequence('clean', ['scripts', 'styles', 'html', 'assets'], cb); + runSequence('clean', 'dedupe', ['scripts', 'styles', 'html', 'assets'], cb); }); diff --git a/package.json b/package.json index a3219255..6df48803 100644 --- a/package.json +++ b/package.json @@ -60,18 +60,19 @@ "mocha": "2.2.4", "chai": "2.2.0", "jquery": "~2.1.3", - "hr.utils": "*", - "hr.app": "*", - "hr.list": "*", - "hr.storage": "*", - "hr.model": "0.1.1", - "hr.view": "*", - "hr.collection": "0.1.2", - "hr.class": "*", - "hr.dnd": "*", - "hr.gridview": "0.2.0", - "hr.logger": "0.1.1", - "hr.backend": "0.1.1", + "hr.utils": "0.1.0", + "hr.app": "0.2.0", + "hr.list": "0.3.0", + "hr.storage": "0.2.0", + "hr.model": "0.2.0", + "hr.view": "0.2.0", + "hr.collection": "0.2.0", + "hr.class": "0.4.0", + "hr.dnd": "0.2.0", + "hr.gridview": "0.3.0", + "hr.logger": "0.2.0", + "hr.backend": "0.2.0", + "hr.queue": "0.2.0", "octicons": "2.2.0", "mousetrap": "1.5.2", "moment": "2.9.0", From 57deacfd1229dfd84e268e8d241c3927cf758cf4 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 16 Apr 2015 09:54:42 -0500 Subject: [PATCH 301/351] Update hr.list@0.3.1 --- gulpfile.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 8beab60b..1e9927bd 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -27,7 +27,7 @@ gulp.task('scripts', function() { // Dedupe modules gulp.task('dedupe', function (cb) { exec('npm dedupe', cb); -}) +}); // Copy html gulp.task('html', function() { diff --git a/package.json b/package.json index 6df48803..abc58a2b 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "jquery": "~2.1.3", "hr.utils": "0.1.0", "hr.app": "0.2.0", - "hr.list": "0.3.0", + "hr.list": "0.3.1", "hr.storage": "0.2.0", "hr.model": "0.2.0", "hr.view": "0.2.0", From 56bdc9a05226c376adc25a800325aab3c8075c5a Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 16 Apr 2015 12:43:26 -0500 Subject: [PATCH 302/351] Add method File.saveAs --- editor/models/file.js | 58 ++++++++++++++++++++++++++++++++--------- editor/utils/dialogs.js | 2 ++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/editor/models/file.js b/editor/models/file.js index f302aba9..ada685ad 100644 --- a/editor/models/file.js +++ b/editor/models/file.js @@ -67,7 +67,7 @@ var File = Model.extend({ // Check if a file is a buffer or exists isBuffer: function() { - return this.get("buffer") != null; + return _.isString(this.get("buffer")); }, // Test if a path is child @@ -111,7 +111,6 @@ var File = Model.extend({ var p; - if (this.isBuffer()) p = Q(hash.btoa(this.get("buffer"))); else { p = rpc.execute("fs/read", { @@ -131,16 +130,19 @@ var File = Model.extend({ }, // Write file content - write: function(content) { + write: function(content, opts) { var that = this; + opts = _.defaults(opts || {}, { + base64: false + }); - return Q() - .then(function() { - if (that.isBuffer()) return Q(that.set("buffer", content)); + return opts.base64? Q(content) : File.btoa(content) + .then(function(_content) { + if (that.isBuffer()) return Q(that.set("buffer", hash.atob(content))); return rpc.execute("fs/write", { 'path': that.get("path"), - 'content': hash.btoa(content) + 'content': content }); }) .then(function() { @@ -188,18 +190,18 @@ var File = Model.extend({ }, // Save file - save: function(content) { + save: function(content, opts) { var that = this; - return Q() - .then(function() { - if (!that.isBuffer() || !that.options.saveAsFile) return that.write(content); + return File.btoa(content) + .then(function(_content) { + if (!that.isBuffer() || !that.options.saveAsFile) return that.write(_content, { base64: true }); return dialogs.prompt("Save as:", that.get("name")) .then(function(_path) { return rpc.execute("fs/write", { 'path': _path, - 'content': hash.btoa(content), + 'content': _content, 'override': false }) .then(function() { @@ -221,7 +223,7 @@ var File = Model.extend({ buffer: function(name, content, id, options) { var f = new File(options || {}, { 'name': name, - 'buffer': content, + 'buffer': content || "", 'path': "buffer://"+(id || _.uniqueId("tmp")), 'directory': false }); @@ -249,6 +251,36 @@ var File = Model.extend({ .then(function(f) { return new File({}, f); }); + }, + + // Save as + saveAs: function(filename, content, opts) { + var f = File.buffer(filename); + return f.save(content, opts); + }, + + // Convert string or blob to base64 + btoa: function(b) { + var d = Q.defer(); + + if (b instanceof Blob) { + var reader = new window.FileReader(); + reader.readAsDataURL(b); + reader.onerror = function(err) { + d.reject(err); + } + reader.onloadend = function() { + d.resolve(reader.result); + }; + } else { + try { + d.resolve(hash.btoa(b)); + } catch (e) { + d.reject(e); + } + } + + return d.promise; } }); diff --git a/editor/utils/dialogs.js b/editor/utils/dialogs.js index 47dc812d..aff9513f 100644 --- a/editor/utils/dialogs.js +++ b/editor/utils/dialogs.js @@ -57,6 +57,7 @@ var openAlert = function(text, options) { }); }; var openErrorAlert = function(err) { + console.log("error", err); return openAlert("Error: "+(err.message || err)) .fin(function() { return Q.reject(err); @@ -123,6 +124,7 @@ var openSchema = function(schema, values) { }); }; + module.exports = { open: open, alert: openAlert, From f20b8cb84628d8ca9be95867f4634feb028afb51 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 16 Apr 2015 14:40:53 -0500 Subject: [PATCH 303/351] Improve write of large file using File.write --- editor/models/file.js | 39 ++++++++++++++++++++----- editor/utils/upload.js | 2 +- lib/index.js | 65 ++++++++++++++++++++++++++++++++++++------ lib/services/fs.js | 18 ++++++++---- package.json | 8 ++++-- 5 files changed, 106 insertions(+), 26 deletions(-) diff --git a/editor/models/file.js b/editor/models/file.js index ada685ad..e273100d 100644 --- a/editor/models/file.js +++ b/editor/models/file.js @@ -1,3 +1,5 @@ +var path = require("path"); +var axios = require("axios"); var Q = require("q"); var _ = require("hr.utils"); var Model = require("hr.model"); @@ -136,13 +138,12 @@ var File = Model.extend({ base64: false }); - return opts.base64? Q(content) : File.btoa(content) + return (opts.base64? Q(content) : File.btoa(content)) .then(function(_content) { if (that.isBuffer()) return Q(that.set("buffer", hash.atob(content))); - return rpc.execute("fs/write", { - 'path': that.get("path"), - 'content': content + return File.writeContent(that.get("path"), _content, { + }); }) .then(function() { @@ -199,9 +200,7 @@ var File = Model.extend({ return dialogs.prompt("Save as:", that.get("name")) .then(function(_path) { - return rpc.execute("fs/write", { - 'path': _path, - 'content': _content, + return File.writeContent(_path, _content, { 'override': false }) .then(function() { @@ -281,6 +280,32 @@ var File = Model.extend({ } return d.promise; + }, + + // Write content (large or small) + writeContent: function(filename, content, opts) { + opts = _.extend({ + base64: true + }, opts || {}, { + path: filename + }); + + if (content.length > 1000) { + opts.path = path.dirname(filename); + + var data = new FormData(); + var blob = new Blob([content], { type: 'text/plain' }); + + _.each(opts, function(value, key) { + data.append(key, JSON.stringify(value)); + }); + data.append("content", blob, path.basename(filename)); + + return Q(axios.put('/rpc/fs/upload', data)); + } else { + opts.content = content; + return rpc.execute("fs/write", opts); + } } }); diff --git a/editor/utils/upload.js b/editor/utils/upload.js index 8a40d1f9..fb7757ca 100644 --- a/editor/utils/upload.js +++ b/editor/utils/upload.js @@ -154,7 +154,7 @@ var Uploader = Class.extend({ var formData = new FormData(); formData.append(filename, file); _.each(that.options.data, function(v, k) { - formData.append(k, v); + formData.append(k, JSON.stringify(v)); }); progress(0); diff --git a/lib/index.js b/lib/index.js index 69d1f597..82899add 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,13 +1,16 @@ var Q = require('q'); var _ = require('lodash'); var path = require('path'); +var os = require('os'); +var uuid = require('uuid'); +var fs = require('fs'); var http = require('http'); var express = require('express'); var bodyParser = require('body-parser'); var basicAuth = require('basic-auth-connect'); var cookieParser = require('cookie-parser'); var session = require('express-session'); -var multipart = require('connect-multiparty'); +var Busboy = require('busboy'); var configs = require('./configs'); var hooks = require('./hooks'); @@ -38,20 +41,64 @@ var prepare = function(config) { .then(_.partial(packages.init, config)) }; -var multipartMiddleware = multipart(); -var bodyParserMiddleware = bodyParser(); - var start = function(config) { var app = express(); var server = http.createServer(app); + // Parse form data app.use(function(req, res, next) { - if (req.method == "PUT") { - multipartMiddleware(req, res, next); - } else { - bodyParserMiddleware(req, res, next); - } + if ( + (req.headers['content-type'] || "").indexOf('multipart/form-data') < 0 + && req.method.toLowerCase() != "put" + ) return next(); + + var files = {}, fields = {}; + + var busboy = new Busboy({ + headers: req.headers + }); + busboy.on('file', function(fieldname, file, filename, encoding, mimetype) { + var saveTo = path.join(os.tmpDir(), uuid.v4()); + file.pipe(fs.createWriteStream(saveTo)); + files[fieldname] = { + filename: filename, + path: saveTo, + mimetype: mimetype + }; + }); + busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) { + var pval; + + try { + pval = JSON.parse(val); + } catch (e) { + pval = val; + } + + if (fields[fieldname]) { + if (!_.isArray(fields[fieldname])) fields[fieldname] = [fields[fieldname]]; + fields[fieldname].push(pval); + } else { + fields[fieldname] = pval; + } + }); + busboy.on('finish', function() { + req.body = fields; + req._body = true; + req.files = files; + + res.on ('finish', function () { + _.each(req.files, function(file) { + try { fs.unlinkSync(file.path); } catch(e) {} + }); + req.files = {}; + }); + + next(); + }); + req.pipe(busboy); }); + app.use(bodyParser()); app.use(cookieParser()); // Auth diff --git a/lib/services/fs.js b/lib/services/fs.js index 75f165ce..6f872ef2 100644 --- a/lib/services/fs.js +++ b/lib/services/fs.js @@ -5,6 +5,7 @@ var path = require('path'); var wrench = require('wrench'); var stream = require('stream'); var mime = require('mime'); +var base64Stream = require('base64-stream'); var workspace = require('../workspace'); var base64 = require('../utils/base64'); @@ -118,8 +119,10 @@ var write = function(args) { 'createParent': true }); + var isStream = args.content instanceof stream.Readable; + if (!args.path || args.content == null) throw "Need 'path' and 'content'"; - if (args.base64) args.content = base64.atob(args.content); + if (args.base64 && !isStream) args.content = base64.atob(args.content); return workspace.path(args.path) .then(function(_path) { @@ -132,7 +135,7 @@ var write = function(args) { } // Write stream - if (args.content instanceof stream.Readable) { + if (isStream) { var d = Q.defer(); var writeStream = fs.createWriteStream(_path); @@ -144,7 +147,11 @@ var write = function(args) { d.reject(err); }); - args.content.pipe(writeStream); + var s = args.content; + + if (args.base64) s = s.pipe(base64Stream.decode()); + + s.pipe(writeStream); return d.promise; } else { @@ -217,13 +224,12 @@ var rename = function(args) { // Upload a file var upload = function(args, meta) { args.path = args.path || "."; - return _.reduce(meta.req.files, function(prev, file) { return prev .then(function() { return write(_.extend({}, args, { - 'path': path.join(args.path, file.originalFilename), - 'base64': false, + 'path': path.join(args.path, file.filename), + 'base64': args.base64? true : false, 'content': fs.createReadStream(file.path) })); }); diff --git a/package.json b/package.json index abc58a2b..efa36ee6 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,10 @@ "open": "0.0.5", "ini": "1.2.1", "basic-auth-connect": "1.0.0", - "connect-multiparty": "1.1.0", - "mime": "1.3.4" + "mime": "1.3.4", + "busboy": "0.2.9", + "uuid": "2.0.1", + "base64-stream": "0.1.2" }, "devDependencies": { "gulp": "^3.8.11", @@ -77,7 +79,7 @@ "mousetrap": "1.5.2", "moment": "2.9.0", "sockjs-client": "1.0.0-beta.12", - "axios": "0.5.2", + "axios": "0.5.4", "merge-stream": "0.1.7" }, "packageDependencies": { From c325ae1437db6f1d0793f8fbdbf9b4ff33a5f1a6 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 16 Apr 2015 15:09:14 -0500 Subject: [PATCH 304/351] Improve File.write to support blob --- editor/models/file.js | 98 ++++++++++++++++++++++++------------------- editor/utils/hash.js | 96 +++++++++++++++++++----------------------- 2 files changed, 99 insertions(+), 95 deletions(-) diff --git a/editor/models/file.js b/editor/models/file.js index e273100d..13babebd 100644 --- a/editor/models/file.js +++ b/editor/models/file.js @@ -138,13 +138,16 @@ var File = Model.extend({ base64: false }); - return (opts.base64? Q(content) : File.btoa(content)) - .then(function(_content) { - if (that.isBuffer()) return Q(that.set("buffer", hash.atob(content))); - - return File.writeContent(that.get("path"), _content, { + return Q() + .then(function() { + if (that.isBuffer()) { + return File.blobToString(content) + .then(function(s) { + that.set("buffer", s); + }); + } - }); + return File.writeContent(that.get("path"), content); }) .then(function() { that.trigger("write", content); @@ -194,17 +197,17 @@ var File = Model.extend({ save: function(content, opts) { var that = this; - return File.btoa(content) - .then(function(_content) { - if (!that.isBuffer() || !that.options.saveAsFile) return that.write(_content, { base64: true }); + return Q() + .then(function() { + if (!that.isBuffer() || !that.options.saveAsFile) return that.write(content, opts); return dialogs.prompt("Save as:", that.get("name")) - .then(function(_path) { - return File.writeContent(_path, _content, { + .then(function(filename) { + return File.writeContent(filename, content, { 'override': false }) .then(function() { - return that.stat(_path); + return that.stat(filename); }) .fail(dialogs.error); }); @@ -258,54 +261,65 @@ var File = Model.extend({ return f.save(content, opts); }, - // Convert string or blob to base64 - btoa: function(b) { + // Convert blob to string + blobToString: function(b) { var d = Q.defer(); if (b instanceof Blob) { var reader = new window.FileReader(); - reader.readAsDataURL(b); reader.onerror = function(err) { d.reject(err); } - reader.onloadend = function() { + reader.onload = function() { d.resolve(reader.result); }; + reader.readAsText(b); } else { - try { - d.resolve(hash.btoa(b)); - } catch (e) { - d.reject(e); - } + d.resolve(b); } return d.promise; }, - // Write content (large or small) + // Write content to a file (blob, arraybuffer, string) writeContent: function(filename, content, opts) { - opts = _.extend({ - base64: true - }, opts || {}, { - path: filename + opts = _.defaults(opts || {}, { + base64: false }); + var useUpload = false; - if (content.length > 1000) { - opts.path = path.dirname(filename); - - var data = new FormData(); - var blob = new Blob([content], { type: 'text/plain' }); - - _.each(opts, function(value, key) { - data.append(key, JSON.stringify(value)); - }); - data.append("content", blob, path.basename(filename)); - - return Q(axios.put('/rpc/fs/upload', data)); - } else { - opts.content = content; - return rpc.execute("fs/write", opts); - } + return Q() + .then(function() { + if (_.isString(content)) { + if (opts.base64) return content; + + useUpload = (content.length > 1000); + opts.base64 = true; + return hash.btoa(content); + } else { + useUpload = true; + return content; + } + }) + .then(function(_content) { + if (useUpload) { + opts.path = path.dirname(filename); + + var data = new FormData(); + var blob = new Blob([_content]); + + _.each(opts, function(value, key) { + data.append(key, JSON.stringify(value)); + }); + data.append("content", blob, path.basename(filename)); + + return Q(axios.put('/rpc/fs/upload', data)); + } else { + opts.path = filename; + opts.content = _content; + return rpc.execute("fs/write", opts); + } + }); } }); diff --git a/editor/utils/hash.js b/editor/utils/hash.js index 833f94f5..bd6c53e8 100644 --- a/editor/utils/hash.js +++ b/editor/utils/hash.js @@ -1,77 +1,72 @@ var crc32table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D"; var utf8Encode = function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } + string = string.replace(/\r\n/g,"\n"); + var utftext = ""; + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } - return utftext; + return utftext; }; /** * Convert value as 8-bit unsigned integer to 2 digit hexadecimal number. */ -var hex8 = function(val) -{ - var n = val & 0xFF, - str = n.toString(16).toUpperCase() - ; +var hex8 = function(val) { + var n = val & 0xFF, + str = n.toString(16).toUpperCase() + ; - while(str.length < 2) - str = "0" + str; + while(str.length < 2) + str = "0" + str; - return str; + return str; }; /** * Convert value as 16-bit unsigned integer to 4 digit hexadecimal number. */ -var hex16 = function(val) -{ - return hex8(val >> 8) + hex8(val); +var hex16 = function(val) { + return hex8(val >> 8) + hex8(val); }; /** * Convert value as 32-bit unsigned integer to 8 digit hexadecimal number. */ -var hex32 = function(val) -{ - return hex16(val >> 16) + hex16(val); +var hex32 = function(val) { + return hex16(val >> 16) + hex16(val); }; var crc32= function(str) { - str = utf8Encode(str); + str = utf8Encode(str); - var crc = 0; - var x = 0; - var y = 0; + var crc = 0; + var x = 0; + var y = 0; - crc = crc ^ (-1); - for (var i = 0, iTop = str.length; i < iTop; i++) { - y = (crc ^ str.charCodeAt(i)) & 0xFF; - x = "0x" + crc32table.substr(y * 9, 8); - crc = (crc >>> 8) ^ x; - } + crc = crc ^ (-1); + for (var i = 0, iTop = str.length; i < iTop; i++) { + y = (crc ^ str.charCodeAt(i)) & 0xFF; + x = "0x" + crc32table.substr(y * 9, 8); + crc = (crc >>> 8) ^ x; + } - return (crc ^ (-1)).toString(); + return (crc ^ (-1)).toString(); }; /*\ @@ -85,7 +80,6 @@ var crc32= function(str) { /* Array of bytes to base64 string decoding */ function b64ToUint6 (nChr) { - return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 ? @@ -98,11 +92,9 @@ function b64ToUint6 (nChr) { 63 : 0; - } function base64DecToArr (sBase64, nBlocksSize) { - var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen); @@ -118,14 +110,12 @@ function base64DecToArr (sBase64, nBlocksSize) { } } - return taBytes; } /* Base64 string to array encoding */ function uint6ToB64 (nUint6) { - return nUint6 < 26 ? nUint6 + 65 : nUint6 < 52 ? @@ -138,11 +128,9 @@ function uint6ToB64 (nUint6) { 47 : 65; - } function base64EncArr (aBytes) { - var nMod3, sB64Enc = ""; for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { @@ -156,7 +144,6 @@ function base64EncArr (aBytes) { } return sB64Enc.replace(/A(?=A$|$)/g, "="); - } /* UTF-8 array to DOMString and vice versa */ @@ -255,5 +242,8 @@ module.exports = { }, 'btoa': function(s) { return base64EncArr(strToUTF8Arr(s)); + }, + 'base64': { + 'encodeArray': base64EncArr } }; From 779fe747847d4fb5ef70834f5cb3a9746f5a326c Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 16 Apr 2015 16:26:21 -0500 Subject: [PATCH 305/351] Improve packages and commands error loading --- editor/models/command.js | 2 +- editor/models/package.js | 47 +++++++++++++++++++++++++++++++++------- package.json | 2 +- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/editor/models/command.js b/editor/models/command.js index cc10352f..f1933d81 100644 --- a/editor/models/command.js +++ b/editor/models/command.js @@ -78,7 +78,7 @@ var Command = Model.extend({ return that.get("run").apply(that, [ args || {}, that.collection.context, origin ]); }) .fail(function(err) { - logger.error("Command failed", err); + logger.exception("Command failed", err); }); }, diff --git a/editor/models/package.js b/editor/models/package.js index 3e124308..59d97560 100644 --- a/editor/models/package.js +++ b/editor/models/package.js @@ -4,6 +4,39 @@ var _ = require("hr.utils"); var Model = require("hr.model"); var logger = require("hr.logger")("package"); +function getScript(url, callback) { + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement("script"); + script.src = url; + + // Handle Script loading + { + var done = false; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function(){ + if ( !done && (!this.readyState || + this.readyState == "loaded" || this.readyState == "complete") ) { + done = true; + if (callback) + callback(); + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + } + }; + + script.onerror = function(err) { + callback(err); + }; + } + + head.appendChild(script); + + // We handle everything using the script element injection + return undefined; +} + var Package = Model.extend({ defaults: { name: null, @@ -30,16 +63,14 @@ var Package = Model.extend({ if (!this.get("browser")) return Q(); logger.log("Load", this.get("name")); - $.getScript(this.url()+"/pkg-build.js") - .done(function(script, textStatus) { - d.resolve(); - }) - .fail(function(jqxhr, settings, exception) { - logger.error("Error loading plugin:", exception.stack || exception.message || exception); - d.reject(exception); + getScript(this.url()+"/pkg-build.js", function(err) { + if (!err) return d.resolve(); + + logger.exception("Error loading plugin:", err); + d.reject(err); }); - return d.promise.timeout(5000, "This addon took to long to load (> 5seconds)"); + return d.promise.timeout(10000, "This addon took to long to load (> 10seconds)"); }, /** diff --git a/package.json b/package.json index efa36ee6..7d7bcfc9 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "hr.class": "0.4.0", "hr.dnd": "0.2.0", "hr.gridview": "0.3.0", - "hr.logger": "0.2.0", + "hr.logger": "0.3.0", "hr.backend": "0.2.0", "hr.queue": "0.2.0", "octicons": "2.2.0", From 17dafc7f7a3e483e7886f9bc563ba0e075892847 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 16 Apr 2015 16:40:23 -0500 Subject: [PATCH 306/351] Update critical error in hr.class --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7d7bcfc9..ad7cc684 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "hr.model": "0.2.0", "hr.view": "0.2.0", "hr.collection": "0.2.0", - "hr.class": "0.4.0", + "hr.class": "0.4.1", "hr.dnd": "0.2.0", "hr.gridview": "0.3.0", "hr.logger": "0.3.0", From 186853581439f5b12b52a1476aa194c95cedf034 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 16 Apr 2015 21:54:31 -0500 Subject: [PATCH 307/351] Update hr.view and hr.class to fix inheritance --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ad7cc684..c4383140 100644 --- a/package.json +++ b/package.json @@ -67,9 +67,9 @@ "hr.list": "0.3.1", "hr.storage": "0.2.0", "hr.model": "0.2.0", - "hr.view": "0.2.0", + "hr.view": "1.0.0", "hr.collection": "0.2.0", - "hr.class": "0.4.1", + "hr.class": "1.2.1", "hr.dnd": "0.2.0", "hr.gridview": "0.3.0", "hr.logger": "0.3.0", From 6cbe71a93a2998307169a92aef29106a64976db5 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 09:27:32 -0500 Subject: [PATCH 308/351] Update hr.class --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c4383140..06629dd9 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "hr.model": "0.2.0", "hr.view": "1.0.0", "hr.collection": "0.2.0", - "hr.class": "1.2.1", + "hr.class": "1.2.2", "hr.dnd": "0.2.0", "hr.gridview": "0.3.0", "hr.logger": "0.3.0", From ad38e13d2c99a24a7c0565970156c900c63704ff Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 09:27:46 -0500 Subject: [PATCH 309/351] Add base for publish task --- gulpfile.js | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 1e9927bd..487bed1a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -68,11 +68,43 @@ gulp.task('styles', function() { // Clean output gulp.task('clean', function(cb) { del([ + '.tmp/**', 'build/**', 'packages/*/pkg-build.js' ], cb); }); -gulp.task('default', function(cb) { +// Build client code +gulp.task('build', function(cb) { runSequence('clean', 'dedupe', ['scripts', 'styles', 'html', 'assets'], cb); }); + +// Copy everything to .tmp +gulp.task('copy-tmp', function() { + return gulp.src([ + // Most files except the ones below + "./**", + + // Ignore gitignore + "!.gitignore", + + // Ignore dev related things + "!./tmp/**", + "!./.git/**", + "!./packages/**", + "!./editor/**", + '!./editor', + "!./node_modules/**", + '!./node_modules' + ]) + .pipe(gulp.dest('.tmp')); +}); + +// Publish to NPM +gulp.task('publish', function(cb) { + runSequence('clean', 'build', 'copy-tmp', cb); +}); + +gulp.task('default', function(cb) { + runSequence('build', cb); +}); From 81da5655919084a001a6caba0f135418e4175ee5 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 10:10:47 -0500 Subject: [PATCH 310/351] Use an external folder to store packages --- bin/codebox.js | 1 - lib/configs/default.js | 5 +++ lib/configs/local.js | 6 +++- lib/packages.js | 79 +++++++++++++++++++++++++++++++----------- 4 files changed, 68 insertions(+), 23 deletions(-) diff --git a/bin/codebox.js b/bin/codebox.js index 1f3f6a56..1597f92c 100755 --- a/bin/codebox.js +++ b/bin/codebox.js @@ -44,7 +44,6 @@ var options = { } }; - codebox.start(options) .then(function() { if (program.email) return program.email; diff --git a/lib/configs/default.js b/lib/configs/default.js index 04240f26..9f2148d3 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -45,6 +45,11 @@ module.exports = function(options) { 'email': data.email }; }, + }, + + // Packages + 'packages': { + 'root': undefined } }, _.defaults); diff --git a/lib/configs/local.js b/lib/configs/local.js index 42dbcedc..60e0fe6d 100644 --- a/lib/configs/local.js +++ b/lib/configs/local.js @@ -11,7 +11,7 @@ var LOCAL_SETTINGS_DIR = path.join( '.codebox' ); -var SETTINGS_FILE = path.join(LOCAL_SETTINGS_DIR, 'settings.json') +var SETTINGS_FILE = process.env.WORKSPACE_CODEBOX_DIR || path.join(LOCAL_SETTINGS_DIR, 'settings.json') // Base structure for a local workspace // Store the workspace configuration in a file, ... @@ -48,6 +48,10 @@ module.exports = function(options) { } }); + options.packages = _.defaults(options.packages, { + 'root': process.env.WORKSPACE_ADDONS_DIR || path.resolve(LOCAL_SETTINGS_DIR, 'packages') + }); + // Create .codebox folder logger.log("Creating", LOCAL_SETTINGS_DIR); wrench.mkdirSyncRecursive(LOCAL_SETTINGS_DIR); diff --git a/lib/packages.js b/lib/packages.js index 8085d145..a0ccd2df 100644 --- a/lib/packages.js +++ b/lib/packages.js @@ -1,33 +1,36 @@ var Q = require("q"); var _ = require("lodash"); +var fs = require("fs"); var path = require("path"); +var wrench = require("wrench"); var Packager = require("pkgm"); var pkg = require("../package.json"); var events = require("./events"); var logger = require("./utils/logger")("packages"); -var context; -var manager = new Packager({ - 'engine': "codebox", - 'version': pkg.version, - 'folder': path.resolve(__dirname, "../packages"), - 'lessInclude': path.resolve(__dirname, "../editor/resources/stylesheets/variables.less") -}); - -manager.on("add", function(pkg) { - logger.log("add package", pkg.pkg.name); - events.emit("packages:add", pkg.infos()); -}); -manager.on("remove", function(pkg) { - logger.log("remove package", pkg.pkg.name); - events.emit("packages:remove", pkg.infos()); -}); -manager.on("log", function(log) { - logger[log.type].apply(logger, log.arguments); -}); - -var init = function() { +var context, manager; + +var init = function(config) { + manager = manager = new Packager({ + 'engine': "codebox", + 'version': pkg.version, + 'folder': config.packages.root, + 'lessInclude': path.resolve(__dirname, "../editor/resources/stylesheets/variables.less") + }); + + manager.on("add", function(pkg) { + logger.log("add package", pkg.pkg.name); + events.emit("packages:add", pkg.infos()); + }); + manager.on("remove", function(pkg) { + logger.log("remove package", pkg.pkg.name); + events.emit("packages:remove", pkg.infos()); + }); + manager.on("log", function(log) { + logger[log.type].apply(logger, log.arguments); + }); + context = { utils: _, promise: Q, @@ -42,6 +45,40 @@ var init = function() { logger.log("Load and prepare packages ("+_.size(pkg.packageDependencies)+" dependencies)"); return Q() + .then(function() { + var defaultPackagesRoot = path.resolve(__dirname, "../packages"); + if (defaultPackagesRoot == config.packages.root) return; + + // Copy default packages to the packages folder + var defaultPackages = fs.readdirSync(defaultPackagesRoot); + + // Create packages folder + wrench.mkdirSyncRecursive(config.packages.root); + + return _.each(defaultPackages, function(defaultPkg) { + var pkgPath = path.resolve(defaultPackagesRoot, defaultPkg); + var outPath = path.resolve(config.packages.root, defaultPkg); + + // Remove output if folder or symlink + try { + var stat = fs.lstatSync(outPath); + if (stat.isDirectory()) { + wrench.rmdirSyncRecursive(outPath); + } else { + fs.unlinkSync(outPath); + } + } catch (e) { + if (e.code != "ENOENT") throw e; + } + + // Create a new symlink + logger.log("symlink default package", defaultPkg); + fs.symlinkSync( + pkgPath, + outPath + ); + }); + }) .then(function() { return manager.prepare(pkg.packageDependencies); }) From c971b1eccd102e29efe342133abbc1669c81787f Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 10:55:40 -0500 Subject: [PATCH 311/351] Add utility to pre-install packages --- bin/codebox-pkg.js | 40 ++++++++++++++++++++++++++++++++++++++ lib/configs/default.js | 3 ++- lib/index.js | 2 +- lib/packages.js | 44 +++++++++++++++++++++++++++++++----------- lib/utils/logger.js | 5 ++++- package.json | 5 ++--- 6 files changed, 82 insertions(+), 17 deletions(-) create mode 100755 bin/codebox-pkg.js diff --git a/bin/codebox-pkg.js b/bin/codebox-pkg.js new file mode 100755 index 00000000..d1f738e7 --- /dev/null +++ b/bin/codebox-pkg.js @@ -0,0 +1,40 @@ +#! /usr/bin/env node + +var _ = require("lodash"); +var path = require("path"); +var program = require('commander'); + +var pkg = require("../package.json"); +var codebox = require("../lib"); + +program +.version(pkg.version) +.option('-r, --root [path]', 'Root folder to store packages') +.option('-p, --packages ', 'Comma separated list of packages to install', function (val) { + return _.chain(val.split(",")) + .compact() + .map(function(pkgref) { + var parts = pkgref.split(":"); + var name = _.first(parts); + var url = parts.slice(1).join(":"); + if (!name || !url) throw "Packages need to be formatted as name:url"; + + return [name,url]; + }) + .object() + .value() +}, []) +.parse(process.argv); + +codebox.prepare({ + packages: { + root: program.root, + install: program.packages + } +}) +.then(function() { + process.exit(0); +}) +.fail(function(err) { + console.log(err.stack || err.message || err); +}); \ No newline at end of file diff --git a/lib/configs/default.js b/lib/configs/default.js index 9f2148d3..15893800 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -49,7 +49,8 @@ module.exports = function(options) { // Packages 'packages': { - 'root': undefined + 'root': undefined, + 'install': {} } }, _.defaults); diff --git a/lib/index.js b/lib/index.js index 82899add..2f551c2b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -197,7 +197,7 @@ var start = function(config) { logger.error(err.stack || err); }); - return prepare(config) + return prepare(_.extend(config, { run: true })) .then(_.partial(socket.init, server, config)) .then(function() { logger.log(""); diff --git a/lib/packages.js b/lib/packages.js index a0ccd2df..a49f0eb8 100644 --- a/lib/packages.js +++ b/lib/packages.js @@ -11,6 +11,21 @@ var logger = require("./utils/logger")("packages"); var context, manager; +// Remove output if folder or symlink +function cleanFolder(outPath) { + try { + var stat = fs.lstatSync(outPath); + if (stat.isDirectory()) { + wrench.rmdirSyncRecursive(outPath); + } else { + fs.unlinkSync(outPath); + } + } catch (e) { + if (e.code != "ENOENT") throw e; + } +} + + var init = function(config) { manager = manager = new Packager({ 'engine': "codebox", @@ -45,6 +60,21 @@ var init = function(config) { logger.log("Load and prepare packages ("+_.size(pkg.packageDependencies)+" dependencies)"); return Q() + + // Keep package foler clean (only packages, ...) + .then(function() { + var packages = fs.readdirSync(config.packages.root); + + return _.each(packages, function(iPkg) { + var pkgPath = path.resolve(config.packages.root, iPkg); + + if (!fs.existsSync(path.resolve(pkgPath, "package.json"))) { + logger.warn("remove non-package", pkgPath); + cleanFolder(pkgPath); + } + }); + }) + .then(function() { var defaultPackagesRoot = path.resolve(__dirname, "../packages"); if (defaultPackagesRoot == config.packages.root) return; @@ -60,16 +90,7 @@ var init = function(config) { var outPath = path.resolve(config.packages.root, defaultPkg); // Remove output if folder or symlink - try { - var stat = fs.lstatSync(outPath); - if (stat.isDirectory()) { - wrench.rmdirSyncRecursive(outPath); - } else { - fs.unlinkSync(outPath); - } - } catch (e) { - if (e.code != "ENOENT") throw e; - } + cleanFolder(outPath); // Create a new symlink logger.log("symlink default package", defaultPkg); @@ -80,9 +101,10 @@ var init = function(config) { }); }) .then(function() { - return manager.prepare(pkg.packageDependencies); + return manager.prepare(_.extend(pkg.packageDependencies, config.packages.install || {})); }) .then(function() { + if (!config.run) return; return manager.runAll(context); }); }; diff --git a/lib/utils/logger.js b/lib/utils/logger.js index 93913bff..425bba7a 100644 --- a/lib/utils/logger.js +++ b/lib/utils/logger.js @@ -6,7 +6,8 @@ var enabled = true; // Colors for log types var colors = { 'log': ['\x1B[36m', '\x1B[39m'], - 'error': ['\x1B[31m', '\x1B[39m'] + 'error': ['\x1B[31m', '\x1B[39m'], + 'warn': ['\x1B[33m', '\x1B[39m'] }; // Base print method @@ -20,6 +21,7 @@ var print = function(logType, logSection) { var error = _.partial(print, 'error'); var log = _.partial(print, 'log'); +var warn = _.partial(print, 'warn'); var exception = _.wrap(error, function(func, logSection, err, kill) { func(logSection, err.message || err); if (err.stack) console.error(err.stack); @@ -44,6 +46,7 @@ module.exports = function(name) { return { 'log': _.partial(log, name), 'error': _.partial(error, name), + 'warn': _.partial(warn, name), 'exception': _.partial(exception, name) }; }; diff --git a/package.json b/package.json index 06629dd9..79bd7ba5 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "eventemitter2": "0.4.14", "crc": "0.2.1", "request": "2.37.0", - "commander": "2.3.0", + "commander": "2.8.0", "open": "0.0.5", "ini": "1.2.1", "basic-auth-connect": "1.0.0", @@ -99,8 +99,7 @@ "settings": "CodeboxIDE/package-settings", "menubar": "CodeboxIDE/package-menubar", "image": "CodeboxIDE/package-image#1.0.0", - "ctags": "CodeboxIDE/package-ctags", - "audio": "CodeboxIDE/package-audio" + "ctags": "CodeboxIDE/package-ctags" }, "scripts": { "test": "export TESTING=true; mocha --reporter list" From 93138000a0788b1d894dfae4d2abd370ca4d5488 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 10:56:29 -0500 Subject: [PATCH 312/351] Add codebox-pkg to bin scripts --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 79bd7ba5..45710417 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ } ], "bin": { - "codebox": "./bin/codebox.js" + "codebox": "./bin/codebox.js", + "codebox-pkg": "./bin/codebox-pkg.js" }, "dependencies": { "q": "~1.2.0", From 64ea738bc73b4864cff987dead48b17d981cfcec Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 11:12:03 -0500 Subject: [PATCH 313/351] Fix codebox-pkg to not use packages in module --- bin/codebox-pkg.js | 7 ++++--- lib/configs/default.js | 2 ++ lib/packages.js | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/bin/codebox-pkg.js b/bin/codebox-pkg.js index d1f738e7..e1a81d6d 100755 --- a/bin/codebox-pkg.js +++ b/bin/codebox-pkg.js @@ -17,7 +17,7 @@ program var parts = pkgref.split(":"); var name = _.first(parts); var url = parts.slice(1).join(":"); - if (!name || !url) throw "Packages need to be formatted as name:url"; + if (!name || !url) throw "Packages need to be formatted as 'name:url'"; return [name,url]; }) @@ -28,8 +28,9 @@ program codebox.prepare({ packages: { - root: program.root, - install: program.packages + root: program.root? path.resolve(process.cwd(), program.root) : undefined, + install: program.packages, + defaults: null } }) .then(function() { diff --git a/lib/configs/default.js b/lib/configs/default.js index 15893800..843d1037 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -1,5 +1,6 @@ var _ = require('lodash'); var crc = require('crc'); +var path = require('path'); // Base structure for a configuration module.exports = function(options) { @@ -50,6 +51,7 @@ module.exports = function(options) { // Packages 'packages': { 'root': undefined, + 'defaults': path.resolve(__dirname, "../packages"), 'install': {} } }, _.defaults); diff --git a/lib/packages.js b/lib/packages.js index a49f0eb8..46197c97 100644 --- a/lib/packages.js +++ b/lib/packages.js @@ -76,8 +76,8 @@ var init = function(config) { }) .then(function() { - var defaultPackagesRoot = path.resolve(__dirname, "../packages"); - if (defaultPackagesRoot == config.packages.root) return; + var defaultPackagesRoot = config.packages.defaults; + if (!defaultPackagesRoot || defaultPackagesRoot == config.packages.root) return; // Copy default packages to the packages folder var defaultPackages = fs.readdirSync(defaultPackagesRoot); From 760e0adb436c7ec37f86ed25666098b15447c20f Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 11:34:05 -0500 Subject: [PATCH 314/351] Move codebox-pkg inside codebox --- README.md | 17 +----- bin/codebox-pkg.js | 41 -------------- bin/codebox.js | 136 +++++++++++++++++++++++++++++---------------- gulpfile.js | 16 +++++- package.json | 3 +- 5 files changed, 104 insertions(+), 109 deletions(-) delete mode 100755 bin/codebox-pkg.js diff --git a/README.md b/README.md index 31ca68c6..0496d267 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ $ npm install -g codebox And start the IDE from the command line: ``` -$ codebox --root=./myworkspace --open +$ codebox run ./myworkspace --open ``` Use this command to run and open Codebox IDE. By default, Codebox uses GIT to identify you, you can use the option ```--email=john.doe@gmail.com``` to define the email you want to use during GIT operations. @@ -53,21 +53,6 @@ Others comand line options are available and can be list with: ```codebox --help -p, --port [port] HTTP port ``` -#### Developing and testing packages - -Download and build the source code: - -``` -$ git clone https://github.com/CodeboxIDE/codebox.git -$ cd ./codebox -$ npm install . -$ grunt -``` - -Then you can easily link packages for testing by creating a folder that will contains all your packages (each should start with the prefix `package-`), then run the command `grunt link --origin=../mypackages`. This command will create symlinks between all the packages in `../mypackages` and the folder where are stored packages used by codebox. - -Everytime you update the code of your package, simply run `grunt resetPkg --pkg=mypackage` in it and restart codebox. - #### Need help? The IDE's documentation can be found at [help.codebox.io](http://help.codebox.io). Feel free to ask any questions or signal problems by adding issues. diff --git a/bin/codebox-pkg.js b/bin/codebox-pkg.js deleted file mode 100755 index e1a81d6d..00000000 --- a/bin/codebox-pkg.js +++ /dev/null @@ -1,41 +0,0 @@ -#! /usr/bin/env node - -var _ = require("lodash"); -var path = require("path"); -var program = require('commander'); - -var pkg = require("../package.json"); -var codebox = require("../lib"); - -program -.version(pkg.version) -.option('-r, --root [path]', 'Root folder to store packages') -.option('-p, --packages ', 'Comma separated list of packages to install', function (val) { - return _.chain(val.split(",")) - .compact() - .map(function(pkgref) { - var parts = pkgref.split(":"); - var name = _.first(parts); - var url = parts.slice(1).join(":"); - if (!name || !url) throw "Packages need to be formatted as 'name:url'"; - - return [name,url]; - }) - .object() - .value() -}, []) -.parse(process.argv); - -codebox.prepare({ - packages: { - root: program.root? path.resolve(process.cwd(), program.root) : undefined, - install: program.packages, - defaults: null - } -}) -.then(function() { - process.exit(0); -}) -.fail(function(err) { - console.log(err.stack || err.message || err); -}); \ No newline at end of file diff --git a/bin/codebox.js b/bin/codebox.js index 1597f92c..b220643f 100755 --- a/bin/codebox.js +++ b/bin/codebox.js @@ -10,66 +10,106 @@ var codebox = require("../lib"); var gitconfig = require('../lib/utils/gitconfig'); +function printError(err) { + console.log(err.stack || err.message || err); +} + program .version(pkg.version) -.option('-r, --root [path]', 'Root folder for the workspace, default is current directory', "./") -.option('-t, --templates [list]', 'Configuration templates, separated by commas', "") -.option('-p, --port [port]', 'HTTP port', 3000) -.option('-o, --open', 'Open the IDE in your favorite browser') -.option('-e, --email [email address]', 'Email address to use as a default authentication') -.option('-u, --users [list users]', 'List of coma seperated users and password (formatted as "username:password")'); - - -program.on('--help', function(){ +.on('--help', function(){ console.log(' Examples:'); console.log(''); - console.log(' $ codebox --root=./myfolder'); + console.log(' $ codebox ./myfolder'); console.log(''); }); -program.parse(process.argv); +//// Run Codebox +//// +program +.command('run [root]') +.description('run codebox') +.option('-t, --templates [list]', 'Configuration templates, separated by commas', "") +.option('-p, --port [port]', 'HTTP port', 3000) +.option('-o, --open', 'Open the IDE in your favorite browser') +.option('-e, --email [email address]', 'Email address to use as a default authentication') +.option('-u, --users [list users]', 'List of coma seperated users and password (formatted as "username:password")', function (val) { + return _.object(_.map((val || "").split(','), function(x) { + // x === 'username:password' + return x.split(':', 2); + })); +}, {}) +.action(function(root, opts) { + // Generate configration + var options = { + root: path.resolve(process.cwd(), root || "./"), + port: opts.port, + auth: { + users: opts.users + } + }; -// Parse auth users -var users = !program.users ? {} : _.object(_.map(program.users.split(','), function(x) { - // x === 'username:password' - return x.split(':', 2); -})); + codebox.start(options) + .then(function() { + if (program.email) return program.email; -// Generate configration -var options = { - root: path.resolve(process.cwd(), program.root), - port: program.port, - auth: { - users: users - } -}; + // Path to user's .gitconfig file + var configPath = path.join( + process.env.HOME, + '.gitconfig' + ); -codebox.start(options) -.then(function() { - if (program.email) return program.email; + // Codebox git repo: use to identify the user + return gitconfig(configPath) + .get("user") + .get("email") + .fail(function() { + return ""; + }); + }) + .then(function(email) { + var token = users[email] || Math.random().toString(36).substring(7); + var url = "http://localhost:"+program.port; - // Path to user's .gitconfig file - var configPath = path.join( - process.env.HOME, - '.gitconfig' - ); + console.log("\nCodebox is running at", url); - // Codebox git repo: use to identify the user - return gitconfig(configPath) - .get("user") - .get("email") - .fail(function() { - return ""; - }); -}) -.then(function(email) { - var token = users[email] || Math.random().toString(36).substring(7); - var url = "http://localhost:"+program.port; + if (program.open) open(url+"/?email="+email+"&token="+token); + }) + .fail(printError); +}); - console.log("\nCodebox is running at", url); +//// Install packages +//// +program +.command('install') +.description('pre-install packages') +.option('-r, --root [path]', 'Root folder to store packages') +.option('-p, --packages ', 'Comma separated list of packages to install', function (val) { + return _.chain(val.split(",")) + .compact() + .map(function(pkgref) { + var parts = pkgref.split(":"); + var name = _.first(parts); + var url = parts.slice(1).join(":"); + if (!name || !url) throw "Packages need to be formatted as 'name:url'"; - if (program.open) open(url+"/?email="+email+"&token="+token); -}) -.fail(function(err) { - console.log(err.stack || err.message || err); + return [name,url]; + }) + .object() + .value() +}, []) +.action(function(opts) { + codebox.prepare({ + packages: { + root: opts.root? path.resolve(process.cwd(), opts.root) : undefined, + install: opts.packages, + defaults: null + } + }) + .then(function() { + process.exit(0); + }) + .fail(printError); }); + +program.parse(process.argv); + diff --git a/gulpfile.js b/gulpfile.js index 487bed1a..02f6066f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,7 +10,14 @@ var rename = require('gulp-rename'); var uglify = require('gulp-uglify'); var stringify = require('stringify'); var merge = require('merge-stream'); -var exec = require('child_process').exec; +var child_process = require('child_process'); + +function exec(cmd, cb) { + var c = child_process.exec.apply(child_process, arguments); + c.stdout.pipe(process.stdout); + c.stderr.pipe(process.stderr); +} + // Compile Javascript gulp.task('scripts', function() { @@ -79,6 +86,11 @@ gulp.task('build', function(cb) { runSequence('clean', 'dedupe', ['scripts', 'styles', 'html', 'assets'], cb); }); +// Dedupe modules +gulp.task('preinstall-addons', function (cb) { + exec('./bin/codebox.js install --root=./.tmp/packages', cb); +}); + // Copy everything to .tmp gulp.task('copy-tmp', function() { return gulp.src([ @@ -102,7 +114,7 @@ gulp.task('copy-tmp', function() { // Publish to NPM gulp.task('publish', function(cb) { - runSequence('clean', 'build', 'copy-tmp', cb); + runSequence('clean', 'build', 'copy-tmp', 'preinstall-addons', cb); }); gulp.task('default', function(cb) { diff --git a/package.json b/package.json index 45710417..79bd7ba5 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,7 @@ } ], "bin": { - "codebox": "./bin/codebox.js", - "codebox-pkg": "./bin/codebox-pkg.js" + "codebox": "./bin/codebox.js" }, "dependencies": { "q": "~1.2.0", From 889702edd625761efce63584651d1d17fd4eec26 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 11:34:37 -0500 Subject: [PATCH 315/351] Fix default folder for packages --- lib/configs/default.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configs/default.js b/lib/configs/default.js index 843d1037..8230ab9e 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -51,7 +51,7 @@ module.exports = function(options) { // Packages 'packages': { 'root': undefined, - 'defaults': path.resolve(__dirname, "../packages"), + 'defaults': path.resolve(__dirname, "../../packages"), 'install': {} } }, _.defaults); From bcf222cdd4e1eab6235426a7abab1aa7f412492a Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 11:36:12 -0500 Subject: [PATCH 316/351] By default print help --- bin/codebox.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/codebox.js b/bin/codebox.js index b220643f..6975305d 100755 --- a/bin/codebox.js +++ b/bin/codebox.js @@ -19,7 +19,7 @@ program .on('--help', function(){ console.log(' Examples:'); console.log(''); - console.log(' $ codebox ./myfolder'); + console.log(' $ codebox run ./myfolder'); console.log(''); }); @@ -113,3 +113,6 @@ program program.parse(process.argv); +if (!process.argv.slice(2).length) { + program.outputHelp(); +} From 7e2aba8527cf5382b933bf930c04e00958005fac Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 11:39:54 -0500 Subject: [PATCH 317/351] Fix open after running codebox --- bin/codebox.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/codebox.js b/bin/codebox.js index 6975305d..2669ba9c 100755 --- a/bin/codebox.js +++ b/bin/codebox.js @@ -67,8 +67,8 @@ program }); }) .then(function(email) { - var token = users[email] || Math.random().toString(36).substring(7); - var url = "http://localhost:"+program.port; + var token = opts.users[email] || Math.random().toString(36).substring(7); + var url = "http://localhost:"+opts.port; console.log("\nCodebox is running at", url); From 2c9c31d8ca2d861656f13c2f4215479b46033a28 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 11:44:32 -0500 Subject: [PATCH 318/351] Adapt tests to use tmp folder for packages --- test/helper.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/helper.js b/test/helper.js index 5fd4c82d..15db0a34 100644 --- a/test/helper.js +++ b/test/helper.js @@ -1,12 +1,16 @@ var Q = require("q"); var chai = require("chai"); var path = require("path"); +var os = require("os"); var codebox = require("../lib"); var users = require("../lib/users"); var config = { log: false, - root: path.resolve(__dirname, "workspace") + root: path.resolve(__dirname, "workspace"), + packages: { + root: path.resolve(os.tmpdir()) + } }; // Expose assert globally From 4ea9477d1bb0c2c03fd35c68f5e1fe8be832e239 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 11:54:54 -0500 Subject: [PATCH 319/351] Fix acces to packages --- gulpfile.js | 2 -- lib/index.js | 20 ++++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 02f6066f..8ecd2cfe 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -104,8 +104,6 @@ gulp.task('copy-tmp', function() { "!./tmp/**", "!./.git/**", "!./packages/**", - "!./editor/**", - '!./editor', "!./node_modules/**", '!./node_modules' ]) diff --git a/lib/index.js b/lib/index.js index 2f551c2b..945697ea 100644 --- a/lib/index.js +++ b/lib/index.js @@ -24,6 +24,14 @@ var logging = require('./utils/logger'); var logger = logging("main"); +var _middleware = function(fn) { + var __middleware; + return function(req, res, next) { + if (!__middleware) __middleware = fn(); + return __middleware.apply(this, arguments); + }; +} + var prepare = function(config) { return Q() .then(_.partial(logging.init, config)) @@ -134,7 +142,9 @@ var start = function(config) { // Static files app.use('/', express.static(path.resolve(__dirname, '../build'))); - app.use('/packages', express.static(path.resolve(__dirname, '../packages'))); + app.use('/packages', _middleware(function() { + return express.static(config.packages.root); + })); // Auth app.use(function(req, res, next) { @@ -163,11 +173,9 @@ var start = function(config) { app.use('/rpc', rpc.router); // Fs direct access - var _fsmiddleware; - app.use('/fs', function(req, res, next) { - if (!_fsmiddleware) _fsmiddleware = express.static(workspace.root()); - return _fsmiddleware.apply(this, arguments); - }); + app.use('/fs', _middleware(function() { + return express.static(workspace.root()); + })); // Error handling app.use(function(req, res, next) { From 73017a4dd55a9ad810fe77e49a7a2ecd0e6f2790 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 12:00:03 -0500 Subject: [PATCH 320/351] Fix tests by using local packages folder --- .gitignore | 3 +++ test/helper.js | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d1d04b1d..1171d6d8 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ build # Tmp directory .tmp + +# Packages for testing +test/packages \ No newline at end of file diff --git a/test/helper.js b/test/helper.js index 15db0a34..ffd4a3e5 100644 --- a/test/helper.js +++ b/test/helper.js @@ -1,15 +1,21 @@ var Q = require("q"); var chai = require("chai"); var path = require("path"); +var wrench = require("wrench"); var os = require("os"); var codebox = require("../lib"); var users = require("../lib/users"); +var packagesFolder = path.resolve(__dirname, "./packages"); +try { + wrench.mkdirSyncRecursive(packagesFolder, 0777); +} catch (e) {} + var config = { log: false, root: path.resolve(__dirname, "workspace"), packages: { - root: path.resolve(os.tmpdir()) + root: packagesFolder } }; From 017088d6fb1419b22b655a7b4c5f7388b186853d Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 12:01:31 -0500 Subject: [PATCH 321/351] Add command to npm publish --- gulpfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 8ecd2cfe..6fdcec9c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -111,8 +111,8 @@ gulp.task('copy-tmp', function() { }); // Publish to NPM -gulp.task('publish', function(cb) { - runSequence('clean', 'build', 'copy-tmp', 'preinstall-addons', cb); +gulp.task('publish', 'clean', 'build', 'copy-tmp', 'preinstall-addons', function(cb) { + exec('cd ./.tmp && npm publish', cb); }); gulp.task('default', function(cb) { From d41a3bdedcd5bd24f1aebfc412fd672fcb8a6c41 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 12:01:50 -0500 Subject: [PATCH 322/351] Bump version to 1.0.0-alpha.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 79bd7ba5..c5c18fe6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "codebox", "description": "Extensible hybrid IDE", - "version": "1.0.0", + "version": "1.0.0-alpha.1", "author": "FriendCode Inc. ", "license": "Apache 2", "preferGlobal": true, From 8491324d52354bb2fbf2dedd84041042e456f9c3 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 12:04:47 -0500 Subject: [PATCH 323/351] Fix publish task --- gulpfile.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 6fdcec9c..44374984 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -111,8 +111,11 @@ gulp.task('copy-tmp', function() { }); // Publish to NPM -gulp.task('publish', 'clean', 'build', 'copy-tmp', 'preinstall-addons', function(cb) { - exec('cd ./.tmp && npm publish', cb); +gulp.task('publish', function(cb) { + runSequence('clean', 'build', 'copy-tmp', 'preinstall-addons', function(err) { + if (err) return cb(err); + exec('cd ./.tmp && npm publish', cb); + }); }); gulp.task('default', function(cb) { From 5c08dd8a2d3e7bf16d8e93de6c38185aa0c3037a Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 12:12:32 -0500 Subject: [PATCH 324/351] Don't copy test folder in publish task --- gulpfile.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 44374984..0980920a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -105,7 +105,10 @@ gulp.task('copy-tmp', function() { "!./.git/**", "!./packages/**", "!./node_modules/**", - '!./node_modules' + '!./node_modules', + "!./test/**", + '!./test', + ]) .pipe(gulp.dest('.tmp')); }); From 01bac5d18ed0a0dcc66c6c06f9dba9073584f729 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 12:14:05 -0500 Subject: [PATCH 325/351] Exit process when command failed --- bin/codebox.js | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/codebox.js b/bin/codebox.js index 2669ba9c..6a8fb922 100755 --- a/bin/codebox.js +++ b/bin/codebox.js @@ -12,6 +12,7 @@ var gitconfig = require('../lib/utils/gitconfig'); function printError(err) { console.log(err.stack || err.message || err); + process.exit(1); } program From 17b2adf77cacec864a8feb2f65610cb680872cb6 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 13:08:34 -0500 Subject: [PATCH 326/351] Don't fix image package version --- README.md | 2 -- package.json | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 0496d267..52f8fab9 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ [![Build Status](https://travis-ci.org/CodeboxIDE/codebox.png?branch=master)](https://travis-ci.org/CodeboxIDE/codebox) [![NPM version](https://badge.fury.io/js/codebox.svg)](http://badge.fury.io/js/codebox) -#### :warning: Instructions are for the not yet published version 1.0.0 - Codebox is a complete and modular Cloud IDE. It can run on any unix-like machine (Linux, Mac OS X). It is an open source component of [codebox.io](https://www.codebox.io) (Cloud IDE as a Service). The IDE can run on your desktop (Linux or Mac), on your server or the cloud. You can use the [codebox.io](https://www.codebox.io) service to host and manage IDE instances. diff --git a/package.json b/package.json index c5c18fe6..f522ff59 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "git": "CodeboxIDE/package-git", "settings": "CodeboxIDE/package-settings", "menubar": "CodeboxIDE/package-menubar", - "image": "CodeboxIDE/package-image#1.0.0", + "image": "CodeboxIDE/package-image", "ctags": "CodeboxIDE/package-ctags" }, "scripts": { From ac54d4fb30f5659e01e004c89770a748227ebb14 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 13:29:07 -0500 Subject: [PATCH 327/351] Separate pre-publish task --- gulpfile.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 0980920a..e6e6a20d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -114,11 +114,11 @@ gulp.task('copy-tmp', function() { }); // Publish to NPM -gulp.task('publish', function(cb) { - runSequence('clean', 'build', 'copy-tmp', 'preinstall-addons', function(err) { - if (err) return cb(err); - exec('cd ./.tmp && npm publish', cb); - }); +gulp.task('pre-publish', function(cb) { + runSequence('clean', 'build', 'copy-tmp', 'preinstall-addons', cb); +}); +gulp.task('publish', ['pre-publish'], function(cb) { + exec('cd ./.tmp && npm publish', cb); }); gulp.task('default', function(cb) { From 9798a4504c39d2c52acc1540604a638f5de5d925 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 13:33:58 -0500 Subject: [PATCH 328/351] Accept env PORT --- lib/configs/default.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configs/default.js b/lib/configs/default.js index 8230ab9e..0a2a7f93 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -6,7 +6,7 @@ var path = require('path'); module.exports = function(options) { options = _.merge(options, { // Port for running the webserver - 'port': 3000, + 'port': process.env.PORT || 3000, // Root folder 'root': process.cwd(), From ad7875a9d60b047cc9e20964d8c030f00b5dc7a0 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 13:41:35 -0500 Subject: [PATCH 329/351] Send static files without auth --- lib/index.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/index.js b/lib/index.js index 945697ea..4f75bd85 100644 --- a/lib/index.js +++ b/lib/index.js @@ -127,6 +127,11 @@ var start = function(config) { next(); } }); + + // Static files + app.use('/', express.static(path.resolve(__dirname, '../build'))); + + // Auth app.use(function(req, res, next) { var doAuth = basicAuth(function(user, pass, fn){ users.auth(user, pass) @@ -139,14 +144,6 @@ var start = function(config) { if (req.session.userId || !config.auth.basic) return next(); doAuth(req, res, next); }); - - // Static files - app.use('/', express.static(path.resolve(__dirname, '../build'))); - app.use('/packages', _middleware(function() { - return express.static(config.packages.root); - })); - - // Auth app.use(function(req, res, next) { if (req.user) { req.session.userId = req.user.id; @@ -169,6 +166,11 @@ var start = function(config) { } }); + // Download packages + app.use('/packages', _middleware(function() { + return express.static(config.packages.root); + })); + // RPC services app.use('/rpc', rpc.router); From 91baf08c046e65a56cc8570d9152129dcf318f18 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 13:45:05 -0500 Subject: [PATCH 330/351] Mimify js for production --- gulpfile.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index e6e6a20d..f7e29320 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -12,22 +12,25 @@ var stringify = require('stringify'); var merge = require('merge-stream'); var child_process = require('child_process'); +var debug = !!process.env.DEBUG; + function exec(cmd, cb) { var c = child_process.exec.apply(child_process, arguments); c.stdout.pipe(process.stdout); c.stderr.pipe(process.stderr); } - // Compile Javascript gulp.task('scripts', function() { - return gulp.src('editor/main.js') + var out = gulp.src('editor/main.js') .pipe(browserify({ debug: false, transform: ['stringify', 'require-globify'] - })) - //.pipe(uglify()) - .pipe(rename('application.js')) + })); + + if (!debug) out = out.pipe(uglify()) + + return out.pipe(rename('application.js')) .pipe(gulp.dest('./build/static/js')); }); From d90ab70eb9cb7cef5559dd942a8ab6a4d27eeb11 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 13:59:20 -0500 Subject: [PATCH 331/351] Uglify packages if debug is false Update pkgm@3.2.0 --- lib/configs/default.js | 3 +++ lib/packages.js | 3 ++- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/configs/default.js b/lib/configs/default.js index 0a2a7f93..ec9204a7 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -5,6 +5,9 @@ var path = require('path'); // Base structure for a configuration module.exports = function(options) { options = _.merge(options, { + // Debug + 'debug': !!process.env.DEBUG, + // Port for running the webserver 'port': process.env.PORT || 3000, diff --git a/lib/packages.js b/lib/packages.js index 46197c97..43cd3314 100644 --- a/lib/packages.js +++ b/lib/packages.js @@ -31,7 +31,8 @@ var init = function(config) { 'engine': "codebox", 'version': pkg.version, 'folder': config.packages.root, - 'lessInclude': path.resolve(__dirname, "../editor/resources/stylesheets/variables.less") + 'lessInclude': path.resolve(__dirname, "../editor/resources/stylesheets/variables.less"), + 'uglify': !config.debug }); manager.on("add", function(pkg) { diff --git a/package.json b/package.json index f522ff59..f8a41c52 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dependencies": { "q": "~1.2.0", "lodash": "2.4.1", - "pkgm": "3.1.0", + "pkgm": "3.2.0", "express": "4.6.1", "express-session": "1.7.0", "wrench": "1.5.8", From 2bdadb987baf7b2295cce558cbfa0d653008b2b5 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 17:15:52 -0500 Subject: [PATCH 332/351] Catch uncaught exception in promises --- editor/main.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/editor/main.js b/editor/main.js index 461f2560..acc04faf 100644 --- a/editor/main.js +++ b/editor/main.js @@ -4,6 +4,10 @@ var Q = require("q"); var logger = require("hr.logger")("app"); +Q.onerror = function (error) { + logger.exception("Uncaught Error:", error); +}; + var app = require("./core/application"); var commands = require("./core/commands"); var packages = require("./core/packages"); From 39a2588d17355651c81a59f803f15797e819d379 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Fri, 17 Apr 2015 20:17:12 -0500 Subject: [PATCH 333/351] Fix issue on happyrhino by updating hr.class --- editor/core/application.js | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/editor/core/application.js b/editor/core/application.js index 08eb893f..752ecb85 100644 --- a/editor/core/application.js +++ b/editor/core/application.js @@ -14,7 +14,7 @@ var CodeboxApplication = Application.extend({ routes: {}, initialize: function() { - Application.__super__.initialize.apply(this, arguments); + CodeboxApplication.__super__.initialize.apply(this, arguments); this.grid = new GridView({ columns: 10 @@ -33,4 +33,4 @@ var CodeboxApplication = Application.extend({ }, }); -module.exports = new CodeboxApplication(); +module.exports = new CodeboxApplication(); diff --git a/package.json b/package.json index f8a41c52..283ea25b 100644 --- a/package.json +++ b/package.json @@ -67,9 +67,9 @@ "hr.list": "0.3.1", "hr.storage": "0.2.0", "hr.model": "0.2.0", - "hr.view": "1.0.0", + "hr.view": "1.0.1", "hr.collection": "0.2.0", - "hr.class": "1.2.2", + "hr.class": "1.2.3", "hr.dnd": "0.2.0", "hr.gridview": "0.3.0", "hr.logger": "0.3.0", From 3e5ba13e5a644d08b854149951618cb7098912f7 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Sun, 19 Apr 2015 18:59:57 -0500 Subject: [PATCH 334/351] Fix events reporting using hook --- lib/configs/default.js | 2 +- lib/configs/local.js | 4 ++-- lib/events.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/configs/default.js b/lib/configs/default.js index ec9204a7..9657a571 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -22,7 +22,7 @@ module.exports = function(options) { // Events reporting 'reporting': { - 'timeout': 180 * 1e3 + 'timeout': 180 }, // Authentication settings diff --git a/lib/configs/local.js b/lib/configs/local.js index 60e0fe6d..bfdeb40e 100644 --- a/lib/configs/local.js +++ b/lib/configs/local.js @@ -6,12 +6,12 @@ var wrench = require('wrench'); var logger = require("../utils/logger")("local"); -var LOCAL_SETTINGS_DIR = path.join( +var LOCAL_SETTINGS_DIR = process.env.WORKSPACE_CODEBOX_DIR || path.join( process.env.HOME, '.codebox' ); -var SETTINGS_FILE = process.env.WORKSPACE_CODEBOX_DIR || path.join(LOCAL_SETTINGS_DIR, 'settings.json') +var SETTINGS_FILE = path.join(LOCAL_SETTINGS_DIR, 'settings.json'); // Base structure for a local workspace // Store the workspace configuration in a file, ... diff --git a/lib/events.js b/lib/events.js index 5eb2e64c..fb9ed962 100644 --- a/lib/events.js +++ b/lib/events.js @@ -38,7 +38,7 @@ var init = function(config) { var eventQueue = []; // Send events and empty queue - var sendEvents = _.debounce(function sendEvents() { + var sendEvents = _.debounce(function() { logger.log("report", _.size(eventQueue), "events"); // Hit hook @@ -48,7 +48,7 @@ var init = function(config) { eventQueue = []; }, timeout); - var queueEvent = function queueEvent(eventData) { + var queueEvent = function(eventData) { eventQueue.push(eventData); }; @@ -74,7 +74,7 @@ var init = function(config) { sendEvents(); }); - logger.log("events are ready"); + logger.log("events are ready, reporting is debounced to", (timeout/1000).toFixed(0)+"s"); }; From 89b0f1feb006c039640ae612ae11ce346341d3fb Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Mon, 20 Apr 2015 07:33:35 -0500 Subject: [PATCH 335/351] Fix display of port where codebox is running --- bin/codebox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/codebox.js b/bin/codebox.js index 6a8fb922..4710a5d6 100755 --- a/bin/codebox.js +++ b/bin/codebox.js @@ -69,7 +69,7 @@ program }) .then(function(email) { var token = opts.users[email] || Math.random().toString(36).substring(7); - var url = "http://localhost:"+opts.port; + var url = "http://localhost:"+options.port; console.log("\nCodebox is running at", url); From 4b8fecb5643165b864d6c3be39b8d6b610c8d65b Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Mon, 20 Apr 2015 08:49:35 -0500 Subject: [PATCH 336/351] Use env mapping to extend configs --- lib/configs/default.js | 7 +++-- lib/configs/env.js | 50 ++++++++++++++++++++++++++++++ lib/configs/index.js | 5 +-- lib/configs/local.js | 69 +++++++++++++++++++----------------------- 4 files changed, 89 insertions(+), 42 deletions(-) create mode 100644 lib/configs/env.js diff --git a/lib/configs/default.js b/lib/configs/default.js index 9657a571..3ce54b37 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -6,10 +6,10 @@ var path = require('path'); module.exports = function(options) { options = _.merge(options, { // Debug - 'debug': !!process.env.DEBUG, + 'debug': false, // Port for running the webserver - 'port': process.env.PORT || 3000, + 'port': 3000, // Root folder 'root': process.cwd(), @@ -49,6 +49,9 @@ module.exports = function(options) { 'email': data.email }; }, + 'events': undefined, + 'settings.get': undefined, + 'settings.set': undefined }, // Packages diff --git a/lib/configs/env.js b/lib/configs/env.js new file mode 100644 index 00000000..cd985051 --- /dev/null +++ b/lib/configs/env.js @@ -0,0 +1,50 @@ +var _ = require('lodash'); + +var alias = { + 'PORT': 'CODEBOX_PORT' +} + +var parseEnv = function (env, parent, prefix) { + var k, v, envVar, parsedEnv; + + if (!parent) { + parent = {}; + } + + for(k in parent) { + v = parent[k]; + + envVar = prefix? prefix + '_': ''; + envVar += k.toUpperCase(); + + if (_.isObject(v) && !_.isArray(v) && !_.isFunction(v)) { + parseEnv(env, v, envVar); + } + else { + if (envVar in env) { + if (_.isArray(v) && (v.length == 0 || _.isString(v[0]))) { + parent[k] = _.compact(env[envVar].split(",")); + } else if (_.isNumber(v)) { + parent[k] = parseInt(env[envVar]); + } else if (_.isBoolean(v)) { + parent[k] = (env[envVar] == "false"? false : true); + } else { + parent[k] = env[envVar] + } + } + } + } + + return parent; +}; + + +// Extend configuration with environment variables +module.exports = function(options) { + var env = _.clone(process.env); + _.each(alias, function(to, from) { + env[to] = env[from] || env[to]; + }) + + return parseEnv(env, options, 'CODEBOX'); +}; \ No newline at end of file diff --git a/lib/configs/index.js b/lib/configs/index.js index c6f23484..5574c50c 100644 --- a/lib/configs/index.js +++ b/lib/configs/index.js @@ -3,12 +3,13 @@ var Q = require('q'); var TEMPLATES = { 'default': require('./default'), - 'local': require('./local') + 'local': require('./local'), + 'env': require('./env') }; // Generate a complete config from templates module.exports = function(options) { - var templates = _.unique(["default"].concat((options.templates || "local").split(","))); + var templates = _.unique(["default"].concat((options.templates || "local,env").split(","))); return _.reduce(templates, function(prev, template) { return prev.then(function(_options) { diff --git a/lib/configs/local.js b/lib/configs/local.js index bfdeb40e..e36e1621 100644 --- a/lib/configs/local.js +++ b/lib/configs/local.js @@ -6,51 +6,44 @@ var wrench = require('wrench'); var logger = require("../utils/logger")("local"); -var LOCAL_SETTINGS_DIR = process.env.WORKSPACE_CODEBOX_DIR || path.join( - process.env.HOME, - '.codebox' -); - +var LOCAL_SETTINGS_DIR = process.env.CODEBOX_LOCAL_FOLDER || path.join(process.env.HOME,'.codebox') var SETTINGS_FILE = path.join(LOCAL_SETTINGS_DIR, 'settings.json'); // Base structure for a local workspace // Store the workspace configuration in a file, ... module.exports = function(options) { - options = _.defaults(options, { - - }); - - options.hooks = _.defaults(options.hooks, { - 'settings.get': function(args) { - return Q.nfcall(fs.readFile, SETTINGS_FILE, "utf-8") - .then(JSON.parse) - .fail(_.constant({})) - .then(function(config) { - if (!config[options.id]) config[options.id] = {}; - return config[options.id][args.user] || {}; - }); + options = _.merge(options, { + 'hooks': { + 'settings.get': function(args) { + return Q.nfcall(fs.readFile, SETTINGS_FILE, "utf-8") + .then(JSON.parse) + .fail(_.constant({})) + .then(function(config) { + if (!config[options.id]) config[options.id] = {}; + return config[options.id][args.user] || {}; + }); + }, + + 'settings.set': function(args) { + return Q.nfcall(fs.readFile, SETTINGS_FILE, "utf-8") + .then(JSON.parse) + .fail(_.constant({})) + .then(function(config) { + if (!config[options.id]) config[options.id] = {}; + config[options.id][args.user] = args.settings; + + return Q.nfcall(fs.writeFile, SETTINGS_FILE, JSON.stringify(config)) + .thenResolve(config); + }) + .then(function(config) { + return config[options.id][args.user] || {}; + }); + } }, - - 'settings.set': function(args) { - return Q.nfcall(fs.readFile, SETTINGS_FILE, "utf-8") - .then(JSON.parse) - .fail(_.constant({})) - .then(function(config) { - if (!config[options.id]) config[options.id] = {}; - config[options.id][args.user] = args.settings; - - return Q.nfcall(fs.writeFile, SETTINGS_FILE, JSON.stringify(config)) - .thenResolve(config); - }) - .then(function(config) { - return config[options.id][args.user] || {}; - }); + packages:{ + 'root': path.resolve(LOCAL_SETTINGS_DIR, 'packages') } - }); - - options.packages = _.defaults(options.packages, { - 'root': process.env.WORKSPACE_ADDONS_DIR || path.resolve(LOCAL_SETTINGS_DIR, 'packages') - }); + }, _.defaults); // Create .codebox folder logger.log("Creating", LOCAL_SETTINGS_DIR); From d912082bc4fe22d5b817fb3cbb863823daeb27d8 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Mon, 20 Apr 2015 09:06:27 -0500 Subject: [PATCH 337/351] Force debug to false when publishing --- gulpfile.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index f7e29320..59401bf9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -91,7 +91,11 @@ gulp.task('build', function(cb) { // Dedupe modules gulp.task('preinstall-addons', function (cb) { - exec('./bin/codebox.js install --root=./.tmp/packages', cb); + exec('./bin/codebox.js install --root=./.tmp/packages', { + env: _.extend({}, process.env, { + CODEBOX_DEBUG: debug + }) + }, cb); }); // Copy everything to .tmp @@ -118,6 +122,7 @@ gulp.task('copy-tmp', function() { // Publish to NPM gulp.task('pre-publish', function(cb) { + debug = false; runSequence('clean', 'build', 'copy-tmp', 'preinstall-addons', cb); }); gulp.task('publish', ['pre-publish'], function(cb) { From ab40da2a9887eb18a1088d211a74645de90f0123 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Mon, 20 Apr 2015 09:22:58 -0500 Subject: [PATCH 338/351] Bump version to 1.0.0-alpha.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 283ea25b..2b37f4f5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "codebox", "description": "Extensible hybrid IDE", - "version": "1.0.0-alpha.1", + "version": "1.0.0-alpha.2", "author": "FriendCode Inc. ", "license": "Apache 2", "preferGlobal": true, From fdb08f59ad098bb46cfcef3d0cacc4d9172c3b46 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Mon, 20 Apr 2015 09:51:41 -0500 Subject: [PATCH 339/351] Fix default port --- lib/configs/env.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/configs/env.js b/lib/configs/env.js index cd985051..361aa312 100644 --- a/lib/configs/env.js +++ b/lib/configs/env.js @@ -43,8 +43,8 @@ var parseEnv = function (env, parent, prefix) { module.exports = function(options) { var env = _.clone(process.env); _.each(alias, function(to, from) { - env[to] = env[from] || env[to]; - }) + if (env[from]) env[to] = env[from] || env[to]; + }); return parseEnv(env, options, 'CODEBOX'); }; \ No newline at end of file From dff8f7b1345a8c557d43111189316ba6b8a95572 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Mon, 20 Apr 2015 11:26:12 -0500 Subject: [PATCH 340/351] Send boxid to webhook --- lib/hooks.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/hooks.js b/lib/hooks.js index 2a0cf127..540e739a 100644 --- a/lib/hooks.js +++ b/lib/hooks.js @@ -4,6 +4,7 @@ var request = require('request'); var logger = require("./utils/logger")("hooks"); +var BOXID = null; var HOOKS = {}; var POSTHOOKS = { 'users.auth': function(data) { @@ -36,6 +37,7 @@ var use = function(hook, data) { // Do http requests request.post(handler, { 'body': { + 'id': BOXID, 'data': data, 'hook': hook }, @@ -74,6 +76,7 @@ var use = function(hook, data) { var init = function(options) { logger.log("init hooks"); + BOXID = options.id; HOOKS = options.hooks; SECRET_TOKEN = options.secret; }; From a0377d7bafc16da35a06256f55f080b37d53c1cd Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Mon, 20 Apr 2015 15:52:03 -0500 Subject: [PATCH 341/351] Use 0777 when creating .codebox folder --- lib/configs/local.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configs/local.js b/lib/configs/local.js index e36e1621..7da404b8 100644 --- a/lib/configs/local.js +++ b/lib/configs/local.js @@ -47,7 +47,7 @@ module.exports = function(options) { // Create .codebox folder logger.log("Creating", LOCAL_SETTINGS_DIR); - wrench.mkdirSyncRecursive(LOCAL_SETTINGS_DIR); + wrench.mkdirSyncRecursive(LOCAL_SETTINGS_DIR, 0777); return options; }; From 99f53a6c66e04c96457a23eab2adce52ebaa7e6c Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Tue, 21 Apr 2015 16:39:43 -0500 Subject: [PATCH 342/351] Bump version to 1.0.0-alpha.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b37f4f5..0c033f19 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "codebox", "description": "Extensible hybrid IDE", - "version": "1.0.0-alpha.2", + "version": "1.0.0-alpha.3", "author": "FriendCode Inc. ", "license": "Apache 2", "preferGlobal": true, From 0fb4129af8d15f7dd0d60cae73ac1a7c3fc97764 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Wed, 22 Apr 2015 09:06:44 -0500 Subject: [PATCH 343/351] Add title for workspace --- editor/core/application.js | 3 +++ editor/core/workspace.js | 3 +++ editor/main.js | 15 +++++++++++---- editor/models/workspace.js | 26 ++++++++++++++++++++++++++ lib/configs/default.js | 3 +++ lib/services/codebox.js | 4 ++++ lib/workspace.js | 9 ++++++++- 7 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 editor/core/workspace.js create mode 100644 editor/models/workspace.js diff --git a/editor/core/application.js b/editor/core/application.js index 752ecb85..a96663df 100644 --- a/editor/core/application.js +++ b/editor/core/application.js @@ -5,6 +5,8 @@ var Q = require("q"); var Application = require("hr.app"); var GridView = require("hr.gridview"); +var workspace = require("./workspace"); + // Define base application var CodeboxApplication = Application.extend({ el: null, @@ -24,6 +26,7 @@ var CodeboxApplication = Application.extend({ }, render: function() { + this.head.title(workspace.get('title')); return this.ready(); }, diff --git a/editor/core/workspace.js b/editor/core/workspace.js new file mode 100644 index 00000000..6621de79 --- /dev/null +++ b/editor/core/workspace.js @@ -0,0 +1,3 @@ +var Workspace = require("../models/workspace"); + +module.exports = new Workspace(); diff --git a/editor/main.js b/editor/main.js index acc04faf..416df13a 100644 --- a/editor/main.js +++ b/editor/main.js @@ -12,6 +12,7 @@ var app = require("./core/application"); var commands = require("./core/commands"); var packages = require("./core/packages"); var user = require("./core/user"); +var workspace = require("./core/workspace"); var users = require("./core/users"); var settings = require("./core/settings"); var dialogs = require("./utils/dialogs"); @@ -27,6 +28,7 @@ window.codebox = { require: codeboxRequire, app: app, user: user, + workspace: workspace, root: new File(), settings: settings }; @@ -48,10 +50,15 @@ commands.register({ // Start running the applications logger.log("start application"); Q.delay(500) -.then(codebox.user.whoami.bind(codebox.user)) -.then(codebox.root.stat.bind(codebox.root, "./")) -.then(settings.load.bind(settings)) -.then(users.listAll.bind(users)) +.then(function() { + return Q.all([ + codebox.user.whoami(), + codebox.root.stat('./'), + codebox.workspace.about(), + settings.load(), + users.listAll() + ]); +}) .then(function() { return packages.loadAll() .fail(function(err) { diff --git a/editor/models/workspace.js b/editor/models/workspace.js new file mode 100644 index 00000000..ba1483c5 --- /dev/null +++ b/editor/models/workspace.js @@ -0,0 +1,26 @@ +var Q = require("q"); +var _ = require("hr.utils"); +var Model = require("hr.model"); +var logger = require("hr.logger")("workspace"); + +var rpc = require("../core/rpc"); + +var Workspace = Model.extend({ + defaults: { + id: "", + title: "" + }, + + // Identify the workspace + about: function() { + var that = this; + + return rpc.execute("codebox/about") + .then(function(data) { + return that.set(data); + }) + .thenResolve(that); + }, +}); + +module.exports = Workspace; diff --git a/lib/configs/default.js b/lib/configs/default.js index 3ce54b37..113c4003 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -14,6 +14,9 @@ module.exports = function(options) { // Root folder 'root': process.cwd(), + // Workspace title + 'title': "Codebox", + // Workspace id 'id': null, diff --git a/lib/services/codebox.js b/lib/services/codebox.js index ee6a03c2..4ba1bd8d 100644 --- a/lib/services/codebox.js +++ b/lib/services/codebox.js @@ -2,9 +2,13 @@ var fs = require("fs"); var path = require("path"); var pkg = require("../../package.json"); +var workspace = require('../workspace'); + // About this current version var about = function(args) { return { + 'id': workspace.config('id'), + 'title': workspace.config('title'), 'version': pkg.version }; }; diff --git a/lib/workspace.js b/lib/workspace.js index 612d004c..3dbe93fb 100644 --- a/lib/workspace.js +++ b/lib/workspace.js @@ -6,9 +6,11 @@ var events = require('./events'); var logger = require('./utils/logger')("workspace"); var root = null; +var _config = {}; // Init the workspace var init = function(config) { + _config = config; root = path.resolve(config.root); logger.log("Working on ", root); @@ -38,5 +40,10 @@ module.exports = { init: init, path: getPath, relative: relativePath, - root: function() { return root; } + root: function() { return root; }, + config: function(str) { + return str.split('.').reduce(function(obj, i) { + return obj[i]; + }, _config); + } }; From 297520b015772e89a905210299ee80200724fe60 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Wed, 22 Apr 2015 13:29:55 -0500 Subject: [PATCH 344/351] Use __ as dots in envs --- lib/configs/env.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configs/env.js b/lib/configs/env.js index 361aa312..8828fcb0 100644 --- a/lib/configs/env.js +++ b/lib/configs/env.js @@ -21,6 +21,7 @@ var parseEnv = function (env, parent, prefix) { parseEnv(env, v, envVar); } else { + envVar = envVar.replace(/\./g, '__'); if (envVar in env) { if (_.isArray(v) && (v.length == 0 || _.isString(v[0]))) { parent[k] = _.compact(env[envVar].split(",")); @@ -45,6 +46,5 @@ module.exports = function(options) { _.each(alias, function(to, from) { if (env[from]) env[to] = env[from] || env[to]; }); - return parseEnv(env, options, 'CODEBOX'); }; \ No newline at end of file From 370bfa2c562be3afd00f6408a8d7b843daaca6fa Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Wed, 22 Apr 2015 13:44:28 -0500 Subject: [PATCH 345/351] Bump version to 1.0.0-alpha.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0c033f19..a88ca1d1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "codebox", "description": "Extensible hybrid IDE", - "version": "1.0.0-alpha.3", + "version": "1.0.0-alpha.4", "author": "FriendCode Inc. ", "license": "Apache 2", "preferGlobal": true, From 3dd0877716f2483050735205840e423bac1af42f Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 23 Apr 2015 08:41:38 -0500 Subject: [PATCH 346/351] Improve authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support option “redirect” --- lib/configs/default.js | 10 +++++++++- lib/index.js | 39 +++++++++++++++++++++++++++------------ package.json | 2 +- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/configs/default.js b/lib/configs/default.js index 113c4003..fc425013 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -30,10 +30,13 @@ module.exports = function(options) { // Authentication settings 'auth': { - 'basic': true + // Redirect user to this url for auth + 'redirect': undefined, }, // Hooks + // If value is string: POST to the url + // If function: executed 'hooks': { 'users.auth': function(data) { if (!data.email || !data.token) throw "Need 'token' and 'email' for auth hook"; @@ -59,8 +62,13 @@ module.exports = function(options) { // Packages 'packages': { + // Path to store all packages for the user 'root': undefined, + + // Path to default packages 'defaults': path.resolve(__dirname, "../../packages"), + + // Packages to install when booting 'install': {} } }, _.defaults); diff --git a/lib/index.js b/lib/index.js index 4f75bd85..59de7139 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,7 +7,7 @@ var fs = require('fs'); var http = require('http'); var express = require('express'); var bodyParser = require('body-parser'); -var basicAuth = require('basic-auth-connect'); +var basicAuth = require('basic-auth'); var cookieParser = require('cookie-parser'); var session = require('express-session'); var Busboy = require('busboy'); @@ -115,6 +115,8 @@ var start = function(config) { resave: false, saveUninitialized: true })); + + // Auth by query strings app.use("/", function(req, res, next) { var args = _.extend({}, req.query, req.body); if (args.email && args.token) { @@ -128,21 +130,30 @@ var start = function(config) { } }); - // Static files - app.use('/', express.static(path.resolve(__dirname, '../build'))); - // Auth app.use(function(req, res, next) { - var doAuth = basicAuth(function(user, pass, fn){ - users.auth(user, pass) + if (req.session.userId) return next(); + + var auth = basicAuth(req); + + // Do basic auth + if (auth && auth.name && auth.pass) { + users.auth(auth.name, auth.pass, req) .then(function(user) { - fn(null, user) + req.user = user; + next(); }) - .fail(fn); - }); - - if (req.session.userId || !config.auth.basic) return next(); - doAuth(req, res, next); + .fail(next); + } else { + if (config.auth.redirect) { + console.log('no auth, redirect to', config.auth.redirect); + res.redirect(config.auth.redirect); + } else { + res.header('WWW-Authenticate', 'Basic realm="codebox"'); + res.status(401); + res.end(); + } + } }); app.use(function(req, res, next) { if (req.user) { @@ -166,6 +177,10 @@ var start = function(config) { } }); + // Static files + app.use('/', express.static(path.resolve(__dirname, '../build'))); + + // Download packages app.use('/packages', _middleware(function() { return express.static(config.packages.root); diff --git a/package.json b/package.json index a88ca1d1..52fb7351 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "commander": "2.8.0", "open": "0.0.5", "ini": "1.2.1", - "basic-auth-connect": "1.0.0", + "basic-auth": "1.0.0", "mime": "1.3.4", "busboy": "0.2.9", "uuid": "2.0.1", From 799b17198f7c3548e5437454320f704aa2505d3f Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 23 Apr 2015 09:29:52 -0500 Subject: [PATCH 347/351] For production, use a bundle of all packages --- editor/collections/packages.js | 61 ++++++++++++++++++---------------- editor/main.js | 2 +- lib/index.js | 7 ++++ lib/packages.js | 28 ++++++++++++++-- lib/services/codebox.js | 3 +- package.json | 2 +- 6 files changed, 70 insertions(+), 33 deletions(-) diff --git a/editor/collections/packages.js b/editor/collections/packages.js index a356dfd6..f461ceeb 100644 --- a/editor/collections/packages.js +++ b/editor/collections/packages.js @@ -1,5 +1,6 @@ var Q = require("q"); var _ = require("hr.utils"); +var $ = require("jquery"); var Collection = require("hr.collection"); var logger = require("hr.logger")("packages"); @@ -16,38 +17,42 @@ var Packages = Collection.extend({ .then(this.reset.bind(this)); }, - // Load all plugins from backend - loadAll: function() { + // Load all plugins from backend (using bundle) + loadAll: function(bundle) { var that = this; var errors = []; - return this.listAll() - .then(function() { - return that.reduce(function(prev, pkg) { - errors = errors.concat(_.map(pkg.get("errors"), function(e) { - return { - 'name': pkg.get("name"), - 'error': e - }; - })); - - return prev.then(pkg.load.bind(pkg)) - .fail(function(err) { - errors.push({ - 'name': pkg.get("name"), - 'error': err + if (bundle) { + return Q($.getScript("/packages.js")); + } else { + return this.listAll() + .then(function() { + return that.reduce(function(prev, pkg) { + errors = errors.concat(_.map(pkg.get("errors"), function(e) { + return { + 'name': pkg.get("name"), + 'error': e + }; + })); + + return prev.then(pkg.load.bind(pkg)) + .fail(function(err) { + errors.push({ + 'name': pkg.get("name"), + 'error': err + }); + return Q(); }); - return Q(); - }); - }, Q()); - }) - .then(function() { - if (errors.length > 0) { - var e = new Error("Error loading packages"); - e.errors = errors; - return Q.reject(e); - } - }); + }, Q()); + }) + .then(function() { + if (errors.length > 0) { + var e = new Error("Error loading packages"); + e.errors = errors; + return Q.reject(e); + } + }); + } } }); diff --git a/editor/main.js b/editor/main.js index 416df13a..a173d424 100644 --- a/editor/main.js +++ b/editor/main.js @@ -60,7 +60,7 @@ Q.delay(500) ]); }) .then(function() { - return packages.loadAll() + return packages.loadAll(!codebox.workspace.get('debug')) .fail(function(err) { var message = "

      "+err.message+"

      "; if (err.errors) { diff --git a/lib/index.js b/lib/index.js index 59de7139..c89e973f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -185,6 +185,13 @@ var start = function(config) { app.use('/packages', _middleware(function() { return express.static(config.packages.root); })); + app.get('/packages.js', function(req, res, next) { + return packages.bundle() + .then(function(fp) { + fs.createReadStream(fp).pipe(res); + }) + .fail(next); + }); // RPC services app.use('/rpc', rpc.router); diff --git a/lib/packages.js b/lib/packages.js index 43cd3314..43ab16fc 100644 --- a/lib/packages.js +++ b/lib/packages.js @@ -1,6 +1,7 @@ var Q = require("q"); var _ = require("lodash"); var fs = require("fs"); +var os = require("os"); var path = require("path"); var wrench = require("wrench"); var Packager = require("pkgm"); @@ -107,6 +108,9 @@ var init = function(config) { .then(function() { if (!config.run) return; return manager.runAll(context); + }) + .then(function() { + return bundle(true); }); }; @@ -115,6 +119,9 @@ var install = function(url) { .then(function(pkg) { return pkg.run(context) .thenResolve(pkg); + }) + .then(function() { + return bundle(true); }); }; @@ -126,10 +133,27 @@ var list = function() { return manager.orderedPackages(); }; +var bundle = function(force) { + var pkgBundle = path.resolve(os.tmpdir(), 'codebox-bundle.js'); + + return Q() + .then(function() { + if (fs.existsSync(pkgBundle) && force != true) return; + console.log("bundle into", pkgBundle); + return manager.bundleAll(pkgBundle); + }) + .then(function() { + return pkgBundle; + }); +}; + module.exports = { init: init, - manager: manager, + manager: function() { + return manager; + }, install: install, uninstall: uninstall, - list: list + list: list, + bundle: bundle }; diff --git a/lib/services/codebox.js b/lib/services/codebox.js index 4ba1bd8d..1d211a59 100644 --- a/lib/services/codebox.js +++ b/lib/services/codebox.js @@ -9,7 +9,8 @@ var about = function(args) { return { 'id': workspace.config('id'), 'title': workspace.config('title'), - 'version': pkg.version + 'version': pkg.version, + 'debug': workspace.config('debug') }; }; diff --git a/package.json b/package.json index 52fb7351..9a7b6d1b 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dependencies": { "q": "~1.2.0", "lodash": "2.4.1", - "pkgm": "3.2.0", + "pkgm": "3.3.0", "express": "4.6.1", "express-session": "1.7.0", "wrench": "1.5.8", From d33619be9be8e956159cf47ce7771a5e8f10c439 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 23 Apr 2015 09:32:04 -0500 Subject: [PATCH 348/351] Remove useless log --- lib/packages.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/packages.js b/lib/packages.js index 43ab16fc..39ad01d4 100644 --- a/lib/packages.js +++ b/lib/packages.js @@ -139,7 +139,6 @@ var bundle = function(force) { return Q() .then(function() { if (fs.existsSync(pkgBundle) && force != true) return; - console.log("bundle into", pkgBundle); return manager.bundleAll(pkgBundle); }) .then(function() { From 9e668877b7b5fbdd3f578bd0d83a7a624655ec89 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 23 Apr 2015 09:48:48 -0500 Subject: [PATCH 349/351] Add dialogs for offline events --- editor/core/application.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/editor/core/application.js b/editor/core/application.js index a96663df..8b94f87d 100644 --- a/editor/core/application.js +++ b/editor/core/application.js @@ -1,10 +1,11 @@ var _ = require("hr.utils"); var $ = require("jquery"); var Q = require("q"); - +var logger = require("hr.logger")("app"); var Application = require("hr.app"); var GridView = require("hr.gridview"); +var dialogs = require("../utils/dialogs"); var workspace = require("./workspace"); // Define base application @@ -23,6 +24,18 @@ var CodeboxApplication = Application.extend({ }, this); this.grid.$el.addClass("main-grid"); this.grid.appendTo(this); + + // Signal offline + function updateOnlineStatus(event) { + logger.log("connection changed", navigator.onLine); + if (!navigator.onLine) { + dialogs.alert("It looks like you lost your internet connection. The IDE requires an internet connection."); + } else { + dialogs.alert("Your internet connection is up again. Restart your navigator tab to ensure that codebox works perfectly."); + } + } + window.addEventListener('online', updateOnlineStatus); + window.addEventListener('offline', updateOnlineStatus); }, render: function() { From f65aa280bdd24af973a7514cfb00855bd51ec521 Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 23 Apr 2015 09:58:57 -0500 Subject: [PATCH 350/351] Use node-tmp to get a temp file for the bundle --- lib/packages.js | 18 +++++++++++++----- package.json | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/packages.js b/lib/packages.js index 39ad01d4..846bf9ae 100644 --- a/lib/packages.js +++ b/lib/packages.js @@ -4,13 +4,14 @@ var fs = require("fs"); var os = require("os"); var path = require("path"); var wrench = require("wrench"); +var tmp = require("tmp"); var Packager = require("pkgm"); var pkg = require("../package.json"); var events = require("./events"); var logger = require("./utils/logger")("packages"); -var context, manager; +var context, manager, _bundle; // Remove output if folder or symlink function cleanFolder(outPath) { @@ -134,15 +135,22 @@ var list = function() { }; var bundle = function(force) { - var pkgBundle = path.resolve(os.tmpdir(), 'codebox-bundle.js'); + var exists = true; return Q() .then(function() { - if (fs.existsSync(pkgBundle) && force != true) return; - return manager.bundleAll(pkgBundle); + if (_bundle) return _bundle ; + exists = false; + + return Q.nfcall(tmp.file).get(0); + }) + .then(function(b) { + _bundle = b; + if (exists && force != true) return; + return manager.bundleAll(_bundle ); }) .then(function() { - return pkgBundle; + return _bundle ; }); }; diff --git a/package.json b/package.json index 9a7b6d1b..64f32c2e 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "q": "~1.2.0", "lodash": "2.4.1", "pkgm": "3.3.0", + "tmp": "0.0.25", "express": "4.6.1", "express-session": "1.7.0", "wrench": "1.5.8", From 98b4710f1bdba615dddbab56011a86cd5f16897b Mon Sep 17 00:00:00 2001 From: Samy Pesse Date: Thu, 23 Apr 2015 13:26:47 -0500 Subject: [PATCH 351/351] Bump version to 1.0.0-alpha.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 64f32c2e..f091b217 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "codebox", "description": "Extensible hybrid IDE", - "version": "1.0.0-alpha.4", + "version": "1.0.0-alpha.5", "author": "FriendCode Inc. ", "license": "Apache 2", "preferGlobal": true,