", {
- '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/client/views/operations/manager.js b/client/views/operations/manager.js
deleted file mode 100644
index 473aa3fb..00000000
--- a/client/views/operations/manager.js
+++ /dev/null
@@ -1,38 +0,0 @@
-define([
- "hr/hr",
- "models/operation",
- "collections/operations",
- "text!resources/templates/operations/operation.html"
-], function(hr, Operation, Operations, templateFile) {
-
- var OperationItem = hr.List.Item.extend({
- className: "operation-item",
- template: templateFile,
- events: {
- "click": "open"
- },
-
- finish: function() {
- this.$el.toggle(this.model.get("state") == "running");
- return OperationItem.__super__.finish.apply(this, arguments);
- },
-
- open: function(e) {
- this.model.run();
- }
- });
-
- // Operations list
- var OperationsView = hr.List.extend({
- tagName: "ul",
- className: "cb-operations",
- Item: OperationItem,
- Collection: Operations,
-
- start: function() {
- return this.collection.start.apply(this.collection, arguments)
- }
- });
-
- return OperationsView;
-});
\ No newline at end of file
diff --git a/client/views/panels/base.js b/client/views/panels/base.js
deleted file mode 100644
index 25d4d365..00000000
--- a/client/views/panels/base.js
+++ /dev/null
@@ -1,92 +0,0 @@
-define([
- 'hr/utils',
- 'hr/dom',
- 'hr/hr'
-], function(_, $, hr) {
- /**
- * Base view for a lateral panel
- *
- * @class
- * @constructor
- */
- var PanelBaseView = hr.View.extend({
- defaults: {
- title: ""
- },
- events: {},
-
- initialize: function(options) {
- PanelBaseView.__super__.initialize.apply(this, arguments);
-
- /**
- * Unique id for this panel in the panels manager
- *
- * @property
- */
- this.panelId = this.options.panel;
-
- /**
- * Referance to the panels manager
- *
- * @property
- */
- this.manager = this.parent;
-
- return this;
- },
-
- /**
- * Show up this panel in the lateral bar
- */
- open: function() {
- this.manager.open(this.panelId);
- return this;
- },
-
- /**
- * Hide this panel from the lateral bar
- */
- close: function() {
- this.manager.close(this.panelId);
- return this;
- },
-
- /**
- * Toggle the visibility of this panel
- *
- * @param {boolean} [state] specific state to use
- */
- toggle: function(state) {
- if (state == null) state = !this.isActive();
-
- if (!state) {
- this.close();
- } else {
- this.open();
- }
- return this;
- },
-
- /**
- * Check if this panel is visible
- *
- * @returns {boolean}
- */
- isActive: function() {
- return this.manager.isActive(this.panelId);
- },
-
- /**
- * Connect a command to this panel, the command will toggle this panel
- */
- connectCommand: function(command) {
- var that = this;
- command.set("action", function() {
- that.toggle();
- });
- this.parent.panelsCommand.menu.add(command);
- }
- });
-
- return PanelBaseView;
-});
\ No newline at end of file
diff --git a/client/views/panels/file.js b/client/views/panels/file.js
deleted file mode 100644
index 18b40079..00000000
--- a/client/views/panels/file.js
+++ /dev/null
@@ -1,104 +0,0 @@
-define([
- 'hr/utils',
- 'hr/dom',
- 'hr/hr',
- 'views/panels/base'
-], function(_, $, hr, PanelBaseView) {
- /**
- * Panel related to the current file
- *
- * @class
- * @constructor
- */
- var PanelFileView = PanelBaseView.extend({
- defaults: {},
- events: {},
-
- /**
- * The view class to create an instance from for each file
- *
- * @type {hr.View}
- */
- FileView: hr.View,
-
- /**
- * Displays a popup list of hints for a given editor context.
- *
- * @param {Object} options
- */
- initialize: function(options) {
- PanelFileView.__super__.initialize.apply(this, arguments);
-
- var box = codebox.require("core/box");
- var files = codebox.require("core/files");
-
- // Remove view when close file
- this.listenTo(files.active, "remove", this.detachFile);
-
- // Update view when file changes
- this.listenTo(box, "file.active", this.update);
-
- // Update file view when changes
- this.listenTo(box, "box:watch:change", function(e) {
- this.updateFile(e.data.path);
- });
-
- // Different cached file views
- this.fileViews = {};
- },
-
- /**
- * Update the current file panel
- *
- * @private
- */
- render: function() {
- var box = codebox.require("core/box");
- var path = box.activeFile;
-
- // Detach all file views
- _.each(this.fileViews, function(view)Â {
- view.detach();
- });
-
- // Create view if non existant
- if (!this.fileViews[path]) {
- this.fileViews[path] = new this.FileView({
- path: path
- });
- }
-
- this.fileViews[path].update();
- this.fileViews[path].$el.appendTo(this.$el);
-
- return this.ready();
- },
-
- /**
- * Detach a file from this file panel
- *
- * @private
- */
- detachFile: function(file) {
- var path = _.isString(file) ? file : file.path();
- if (!this.fileViews[path]) return;
-
- this.fileViews[path].remove();
- delete this.fileViews[path];
- },
-
- /**
- * Update a file
- *
- * @private
- */
- updateFile: function(file) {
- var path = _.isString(file) ? file : file.path();
- if (!this.fileViews[path]) return;
-
- this.fileViews[path].update();
- }
- });
-
- return PanelFileView;
-});
\ No newline at end of file
diff --git a/client/views/panels/manager.js b/client/views/panels/manager.js
deleted file mode 100644
index 561f69bf..00000000
--- a/client/views/panels/manager.js
+++ /dev/null
@@ -1,138 +0,0 @@
-define([
- 'hr/utils',
- 'hr/dom',
- 'hr/hr',
- 'models/command',
- 'views/tabs/manager',
- 'views/panels/base',
- 'views/panels/file'
-], function(_, $, hr, Command, TabsManager) {
- /**
- * Manager view for panels
- *
- * @class
- * @constructor
- */
- var PanelsView = hr.View.extend({
- className: "cb-panels",
- defaults: {},
- events: {},
-
- initialize: function(options) {
- var that = this;
- PanelsView.__super__.initialize.apply(this, arguments);
-
- // Tabs
- this.tabs = new TabsManager({
- layout: 1,
- layouts: {
- "Columns: 1": 1
- },
- tabMenu: false,
- newTab: false,
- draggable: false,
- keyboardShortcuts: false,
- maxTabsPerSection: 1
- }, this);
- this.tabs.$el.appendTo(this.$el);
-
- // Active panel
- this.activePanel = null;
-
- // Menu of panels choice
- this.panelsCommand = new Command({}, {
- 'type': "menu",
- 'title': "Panels"
- });
-
- // Panels map
- this.panels = {};
-
- return this;
- },
-
- render: function() {
- return this.ready();
- },
-
- /**
- * Register a new panel
- *
- * @property {string} panelId unique id to identify the panel
- * @property {PanelBaseView} panelView view constructor for this panel
- * @property {object} constructor options for construction of the panel view
- * @return {PanelBaseView} panel just created
- */
- register: function(panelId, panelView, constructor) {
- constructor = _.extend({
- 'title': panelId
- }, constructor || {}, {
- 'panel': panelId
- });
-
- this.panels[panelId] = new panelView(constructor, this);
- this.panels[panelId].update();
-
- return this.panels[panelId];
- },
-
- /**
- * Open a panel by its id
- *
- * @property {string} pId unique id to identify the panel to open
- */
- open: function(pId) {
- var opened = false;
-
- if (pId && this.panels[pId]) {
- opened = true;
- var tab = this.tabs.add(TabsManager.Panel, {}, {
- 'title': this.panels[pId].options.title,
- 'uniqueId': pId
- });
-
- // If new tab
- if (tab.$el.is(':empty')) {
- tab.once("tab:close", function() {
- this.panels[pId].trigger("tab:close");
- this.panels[pId].$el.detach();
- }, this);
-
- this.panels[pId].$el.appendTo(tab.$el);
- this.panels[pId].update();
- }
- }
- this.activePanel = pId;
-
- if (opened) {
- this.trigger("open", pId);
- } else {
- this.trigger("close");
- }
-
- return this;
- },
-
- /**
- * Check the visibility of a specific panel
- *
- * @property {string} pId unique id to identify the panel
- */
- isActive: function(pId) {
- var t = this.tabs.getById(pId);
- return !(t == null || !t.isActive());
- },
-
- /**
- * Close a panel
- *
- * @property {string} pId unique id to identify the panel
- */
- close: function(pId) {
- var tab = this.tabs.getById(pId);
- if (tab) tab.close();
- }
- });
-
- return PanelsView;
-});
\ No newline at end of file
diff --git a/client/views/settings/base.js b/client/views/settings/base.js
deleted file mode 100644
index 2fdb873e..00000000
--- a/client/views/settings/base.js
+++ /dev/null
@@ -1,87 +0,0 @@
-define([
- "hr/utils",
- "hr/dom",
- "hr/hr",
- "text!resources/templates/settings/base.html"
-], function(_, $, hr, templateFile) {
- var SettingsPageView = hr.View.extend({
- template: templateFile,
- defaults: {
- 'namespace': "",
- 'title': "",
- 'settings': {}
- },
- events: {
- "click button[data-settings-action]": "triggerFieldAction"
- },
-
- // Constructor
- initialize: function() {
- SettingsPageView.__super__.initialize.apply(this, arguments);
- var user = require("core/user");
-
- this.namespace = this.options.namespace;
- this.title = this.options.title || this.namespace;
- this.fields = this.options.fields || {};
- this.defaults = this.options.defaults || {};
- this.user = user.settings(this.namespace);
- },
-
- // Define a field
- setField: function(fieldId, field) {
- this.fields[fieldId] = field;
- this.trigger("field:change", fieldId);
- return this;
- },
-
- // Template context
- templateContext: function() {
- return {
- 'fields': this.fields,
- 'defaults': this.defaults,
- 'namespace': this.namespace,
- 'section': this.section
- }
- },
-
- // Trigger action
- triggerFieldAction: function(e) {
- e.preventDefault();
-
- var $btn = $(e.currentTarget);
- var fieldId = $btn.data("settings-action");
-
- if (!this.fields[fieldId]) return;
-
- $btn.button("loading");
- this.fields[fieldId].trigger(fieldId).fin(function() {
- $btn.button("reset");
- });
- },
-
- // Get settings to save
- submit: function() {
- var data = {};
- var that = this;
-
- var selectors = {
- 'text': function(el) { return el.val(); },
- 'password': function(el) { return el.val(); },
- 'textarea': function(el) { return el.val(); },
- 'number': function(el) { return el.val(); },
- 'select': function(el) { return el.val(); },
- 'checkbox': function(el) { return el.is(":checked"); },
- 'action': function(el) Â { return null; }
- };
-
- _.each(this.fields, function(field, key) {
- var v = selectors[field.type](that.$("*[name='"+ that.namespace+"_"+key+"']"));
- if (v !== null) data[key] = v;
- });
-
- return data;
- }
- });
-
- return SettingsPageView;
-});
\ No newline at end of file
diff --git a/client/views/tabs/base.js b/client/views/tabs/base.js
deleted file mode 100644
index c6f14eda..00000000
--- a/client/views/tabs/base.js
+++ /dev/null
@@ -1,213 +0,0 @@
-define([
- "hr/utils",
- "hr/dom",
- "hr/hr",
- "utils/dragdrop",
- "utils/keyboard",
- "utils/contextmenu",
- "models/command",
- "collections/commands"
-], function(_, $, hr, DragDrop, Keyboard, ContextMenu, Command, Commands) {
- /**
- * Tab body base view
- *
- * @class
- * @constructor
- */
- var TabPanelView = hr.View.extend({
- className: "component-tab-panel",
- events: {
- "click": "openTab"
- },
-
- /**
- * Keyboard shortcuts inside the tab
- */
- shortcuts: {
- "alt+w": "closeTab",
- "alt+shift+tab": "tabGotoPrevious",
- "alt+tab": "tabGotoNext"
- },
-
- /**
- * Title in the menu bar
- */
- menuTitle: "Tab",
-
- initialize: function() {
- TabPanelView.__super__.initialize.apply(this, arguments);
-
- var menu = require("core/commands/menu");
- var statusbar = require("core/commands/statusbar");
-
- this.tabs = this.parent;
- this.tab = this.options.tab;
-
- /**
- * Menu for this tab in the menu bar
- * @property
- */
- this.menu = new Command({}, {
- 'type': "menu",
- 'title': this.menuTitle,
- 'position': 1
- });
- if (this.tab.manager.options.tabMenu) menu.collection.add(this.menu);
-
- /**
- * Collection of commands for this tab in the statusbar
- * @property
- */
- this.statusbar = new Commands();
- this.statusbar.pipe(statusbar.collection);
-
- // Bind tab event
- this.listenTo(this.tab.manager, "active", function(tab) {
- var state = tab.id == this.tab.id;
-
- this.trigger("tab:state", state);
-
- // Toggle visibility of commands
- this.menu.toggleFlag("hidden", !state);
- this.statusbar.each(function (command){
- command.toggleFlag("hidden", !state);
- });
- });
- this.on("tab:close", function() {
- this.menu.destroy();
- this.statusbar.stopListening();
- this.statusbar.each(function (command){
- command.destroy();
- });
- }, this);
-
- // Keyboard shortcuts
- this.setShortcuts(this.shortcuts || {});
-
- return this;
- },
-
- /**
- * Define (add) new keyboard shortcuts
- *
- * @param {object} navigations map of keyboard shortcut -> method
- * @param {object} [container] object to get method from if the method is a string
- */
- setShortcuts: function(navigations, container) {
- var navs = {};
- container = container || this;
-
- if (!this.tab.manager.options.keyboardShortcuts) return;
-
- _.each(navigations, function(method, key) {
- navs[key] = function() {
- // Trigger only if active tab
- if (!this.isActiveTab()) return;
-
- // Get method
- if (!_.isFunction(method)) method = container[method];
-
- // Apply method
- if (!method) return;
- method.apply(container, arguments);
- };
- }, this);
-
- Keyboard.bind(navs, this);
- },
-
- /**
- * Close this tab
- */
- closeTab: function(e, force) {
- if (e != null) e.preventDefault();
- this.tab.close(force);
- },
-
- /**
- * Set this tab as active
- */
- openTab: function(e) {
- this.tab.active();
- },
-
- /**
- * Set tab title
- *
- * @param {string} title new title to set
- */
- setTabTitle: function(title) {
- this.tab.set("title", title);
- return this;
- },
-
- /**
- * Set a tab state, states are used to signal
- * for example that the file is loading, ...
- *
- * @param {string} state state id to define
- * @param {boolean} value value for this state
- */
- setTabState: function(state, value) {
- var states = (this.tab.get("state") || "").split(" ");
-
- if (value == null) state = !_.contains(states, state);
- if (value) {
- states.push(state);
- } else {
- states = _.without(states, state);
- }
- this.tab.set("state", _.uniq(states).join(" "));
- return this;
- },
-
- /**
- * Set tab id
- *
- * @param {string} id new id for this tab
- */
- setTabId: function(id) {
- this.tab.set("id", id);
- return this;
- },
-
- /**
- * Check if the tab is active
- *
- * @return {boolean}
- */
- isActiveTab: function() {
- return this.tab.manager.isActiveTab(this.tab);
- },
-
- /**
- * Check if the tab can be closed,
- * this method can be overided
- *
- * @return {boolean}
- */
- tabCanBeClosed: function() {
- return true;
- },
-
- // Navigation between tabs
- tabGotoPrevious: function(e) {
- if (e) e.preventDefault();
- var that = this;
- setTimeout(function() {
- var p = that.tab.prevTab();
- if (p) p.active();
- }, 0);
- },
- tabGotoNext: function(e) {
- if (e) e.preventDefault();
- var that = this;
- setTimeout(function() {
- var p = that.tab.nextTab();
- if (p) p.active();
- }, 0);
- }
- });
-
- return TabPanelView;
-});
\ No newline at end of file
diff --git a/client/views/tabs/file.js b/client/views/tabs/file.js
deleted file mode 100644
index 3f7e8fa5..00000000
--- a/client/views/tabs/file.js
+++ /dev/null
@@ -1,98 +0,0 @@
-define([
- 'hr/utils',
- 'hr/dom',
- 'hr/promise',
- 'hr/hr',
- 'views/tabs/base',
- 'utils/dialogs'
-], function(_, $, Q, hr, Tab, dialogs) {
-
- var FileTab = Tab.extend({
- defaults: {},
- menuTitle: "Editor",
-
- initialize: function(options) {
- FileTab.__super__.initialize.apply(this, arguments);
- var that = this;
-
- this.fileHandler = this.options.handler;
- this.fileOptions = this.options.fileOptions;
- this.fileView = null;
-
- if (!this.fileHandler || !this.fileHandler.View) {
- throw "Invalid handler for file tab";
- }
-
- // Bind file events
- this.listenTo(this.model, "set", this.update);
- this.listenTo(this.model, "destroy", function() {
- this.closeTab();
- });
-
- // When tab is ready : load file
- this.on("tab:ready", function() {
- this.adaptFile();
- }, this);
-
- return this;
- },
-
- /* Render */
- render: function() {
- if (this.fileView) this.fileView.remove();
-
- this.$el.empty();
- this.menu.clearMenu();
-
- this.fileView = new this.fileHandler.View({
- model: this.model
- }, this);
- this.fileView.update();
- this.fileView.$el.appendTo(this.$el);
- this.adaptFile();
- return this.ready();
- },
-
- /* Change the file */
- load: function(path, handler) {
- var that = this;
- if (handler) {
- this.fileHandler = handler;
- }
- this.model.getByPath(path).then(null, function() {
- that.closeTab();
- })
- return this;
- },
-
- /* Adapt the tab to the file (title, ...) */
- adaptFile: function() {
- this.setTabTitle(this.model.get("name", "loading..."));
- this.setTabId(this.fileHandler.id+":"+this.model.syncEnvId());
- this.setFileOptions(this.fileOptions);
- return this;
- },
-
- /* Close the tab: check that file is saved */
- tabCanBeClosed: function() {
- var that = this;
-
- if (this.model.modified && !this.model.isNewfile()) {
- return dialogs.confirm("Do you really want to close "+_.escape(this.model.get("name"))+" without saving changes?", "Your changes will be lost if you don't save them.").then(function(c) {
- return true;
- }, function() {
- return false;
- });
- }
- return true;
- },
-
- /* Set file options: line to highlight, ... */
- setFileOptions: function(fileOptions) {
- this.fileOptions = fileOptions || {};
- if (this.fileView) this.fileView.trigger("file:options", this.fileOptions);
- }
- });
-
- return FileTab;
-});
\ No newline at end of file
diff --git a/client/views/tabs/manager.js b/client/views/tabs/manager.js
deleted file mode 100644
index 611005ea..00000000
--- a/client/views/tabs/manager.js
+++ /dev/null
@@ -1,355 +0,0 @@
-define([
- "hr/utils",
- "hr/dom",
- "hr/hr",
-
- "models/command",
- "models/tab",
-
- "collections/tabs",
-
- "utils/dragdrop",
- "utils/keyboard",
- "utils/contextmenu",
-
- "views/grid",
- "views/tabs/tab",
- "views/tabs/base",
- "views/tabs/section"
-], function(_, $, hr, Command, Tab , Tabs, dnd, Keyboard, ContextMenu, GridView, TabView, TabPanelView, TabsSectionView) {
- // Complete tabs system
- var TabsView = hr.View.extend({
- className: "cb-tabs",
- defaults: {
- // Base layout
- layout: null,
-
- // Available layouts
- layouts: {
- "Auto Grid": 0,
- "Columns: 1": 1,
- "Columns: 2": 2,
- "Columns: 3": 3,
- "Columns: 4": 4
- },
-
- // Enable tab menu
- tabMenu: true,
-
- // Enable open new tab
- newTab: true,
-
- // Max number of tabs per sections (-1 for unlimited)
- maxTabsPerSection: -1,
-
- // Tabs are draggable
- draggable: true,
-
- // Enable keyboard shortcuts
- keyboardShortcuts: true
- },
- events: {},
-
- // Constructor
- initialize: function(options) {
- var that = this;
- TabsView.__super__.initialize.apply(this, arguments);
-
- // Current active tab id
- this.activeTab = null;
- this.activeSection = 0;
-
- // Has been restored
- this._restored = false;
-
- // Current layout
- this.layout = this.options.layout; // null: mode auto
- this.grid = new GridView({}, this);
- this.grid.$el.appendTo(this.$el);
-
- // Drag and drop of tabs
- this.drag = new dnd.DraggableType();
- this.drag.toggle(this.options.draggable);
- this.drag.on("drop", function(section, tab) {
- if (!section && tab) tab.splitSection();
- })
-
- // Commands
- this.layoutCommand = new Command({}, {
- 'type': "menu",
- 'title': "Layout"
- });
- _.each(this.options.layouts, function(layout, layoutName) {
- var command = new Command({}, {
- 'type': "action",
- 'title': layoutName,
- 'action': function() {
- that.setLayout(layout);
- }
- });
- this.layoutCommand.menu.add(command);
- this.on("layout", function(_layout) {
- command.toggleFlag("active", layout == _layout);
- });
- }, this);
-
- // Tabs collection
- this.tabs = new Tabs();
-
- // Restorer
- this.restorer = {};
-
- // Set base layout
- this.setLayout(this.layout);
- return this;
- },
-
- // Return a tab by its id
- getById: function(id) {
- return this.tabs.getById(id);
- },
-
- // Return a section by its id
- getSection: function(id) {
- var s = _.find(this.grid.views, function(section) {
- return section.sectionId == id;
- });
-
- if (!s) {
- s = new TabsSectionView({
- sectionId: id
- }, this);
- this.grid.addView(s);
- }
-
- return s;
- },
-
- // Remove a section
- removeSection: function(id) {
- var s = this.getSection(id);
- this.grid.removeView(s);
- return this;
- },
-
- // Render all tabs
- render: function() {
- return this.ready();
- },
-
- /*
- * Add a tab
- * @V : view class
- * @constructor : contructor options
- * @options : options
- */
- add: function(V, construct, options) {
- var tab = null;
-
- options = _.defaults(options || {}, {
- // Tab type
- type: "unknown",
-
- // Don't trigger event
- silent: false,
-
- // Open after creation
- open: true,
-
- // Base title
- title: "untitled",
-
- // Unique id for this tab
- uniqueId: null,
-
- // Base section id
- section: this.activeSection
- });
-
- if (options.uniqueId) {
- tab = this.tabs.getById(options.uniqueId)
- } else {
- options.uniqueId = _.uniqueId("tab");
- }
-
- if (!tab) {
- tab = new Tab({
- 'manager': this
- }, {
- 'type': options.type,
- 'id': options.uniqueId,
- 'title': options.title
- });
-
- // Create tab object
- this.tabs.add(tab);
-
- // Create content view
- tab.view = new V(_.extend(construct || {}, {
- "tab": tab,
- }), this);
- tab.view.update();
-
- // Add to section
- var sectionId = options.section;
- for (;;) {
- var section = this.getSection(sectionId);
- if (this.options.maxTabsPerSection > 0 && section.tabs.size() >= this.options.maxTabsPerSection) {
- sectionId = _.uniqueId("tabSection");
- } else {
- section.addTab(tab);
- break;
- }
- }
- }
-
- if (options.open) tab.active();
- this.saveTabs();
-
- return tab.view;
- },
-
- // Open default new tab
- openDefault: function() {
- this.trigger("tabs:opennew");
- },
-
- // Define tabs layout
- setLayout: function(l) {
- if (!_.contains(_.values(this.options.layouts), l)) return;
-
- this.grid.setLayout(l);
- this.trigger("layout", l);
- this.saveTabs();
- },
-
- // Check if tab is the active tab
- isActiveTab: function(tab) {
- return this.activeTab == tab.id;
- },
-
- // Check sections
- // -> check that there is no empty sections
- checkSections: function() {
- _.each(this.grid.views, function(section) {
- // If empty remove it
- if (section.tabs.size() == 0) {
- this.grid.removeView(section);
- return;
- }
-
- // If no active tab
- if (section.tabs.getActive() == null) {
- section.tabs.first().active();
- }
-
- }, this);
-
- this.saveTabs();
- },
-
- // Change tab section
- changeTabSection: function(tab, section, options) {
- if (_.isString(tab)) tab = this.tabs.getById(tab);
- if (!tab) return false;
-
- section = this.getSection(section);
-
- // Check limit
- if (this.options.maxTabsPerSection > 0 && section.tabs.size() >= this.options.maxTabsPerSection) return false;
-
- // Remove from old section
- tab.section.remove(tab);
-
- // Add to new section
- section.addTab(tab, options);
-
- // Active
- tab.active();
-
- // Check sections to remove empty one
- this.checkSections();
-
- return true;
- },
-
- // Save tabs
- saveTabs: function() {
- if (!this._restored) return;
-
- var state = {};
-
- // Snapshot sections and tabs
- state.sections = _.map(this.grid.views, function(section) {
- return {
- 'id': section.sectionId,
- 'tabs': section.tabs.map(function(tab) {
- return tab.snapshot();
- })
- };
- });
-
- // Snapshot layout
- state.layout = this.grid.columns;
- hr.Storage.set("tabs", state);
- },
-
- // Add a restorer for tabs
- addRestorer: function(type, handler) {
- this.restorer[type] = handler;
- return this;
- },
-
- // Load tabs saved in last session (return number of tabs restored)
- restoreTabs: function(state) {
- var n = 0, that = this;
-
- state = state || hr.Storage.get("tabs") || {};
-
- // Set layout
- this.setLayout(state.layout);
-
- // Restore tabs
- return Q.all(
- _.chain(state.sections || [])
- .map(function(section) {
- that.getSection(section.id);
- return section.tabs;
- })
- .flatten()
- .map(function(tab) {
- // Restore tab
- return Q()
- .then(function() {
- if (!that.restorer[tab.type]) return;
-
- return Q(that.restorer[tab.type](tab));
- })
- .then(function(_tab) {
- if (!_tab) return;
-
- // restore in right section
- _tab.changeSection(tab.section);
- n = n + 1;
- })
- .fail(function() {
- return Q();
- });
- })
- .value()
- )
- .then(function() {
- that._restored = true;
- that.checkSections();
- return n;
- });
- }
- }, {
- Panel: TabPanelView
- });
-
- // Register as a template component
- hr.View.Template.registerComponent("component.tabs", TabsView);
-
- return TabsView;
-});
\ No newline at end of file
diff --git a/client/views/tabs/section.js b/client/views/tabs/section.js
deleted file mode 100644
index 92fda336..00000000
--- a/client/views/tabs/section.js
+++ /dev/null
@@ -1,144 +0,0 @@
-define([
- "hr/utils",
- "hr/dom",
- "hr/hr",
- "utils/dragdrop",
- "collections/tabs",
- "views/tabs/tab"
-], function(_, $, hr, dnd, Tabs, TabHeaderItem) {
- var TabItem = hr.List.Item.extend({
- className: "component-tab-content",
- events: {
- "click": "click"
- },
- initialize: function() {
- TabItem.__super__.initialize.apply(this, arguments);
- this.$el.append(this.model.view.$el);
- },
-
- // Render active state
- render: function() {
- this.$el.toggleClass("active", this.model.isActive());
- return this.ready();
- },
-
- // Detatch the tab before removing this item
- remove: function() {
- this.model.view.detach();
- return TabItem.__super__.remove.apply(this, arguments);
- },
-
- // On click focus the tab
- click: function() {
- this.model.active();
- }
- });
-
- var TabsList = hr.List.extend({
- Collection: Tabs
- });
-
-
- var TabsSectionContent = TabsList.extend({
- className: "tabs-section-content",
- Item: TabItem,
-
- });
-
- var TabsSectionHeader = TabsList.extend({
- className: "tabs-section-header",
- Item: TabHeaderItem,
- events: {
- 'dblclick': "openNewtab"
- },
-
- initialize: function() {
- TabsSectionHeader.__super__.initialize.apply(this, arguments);
-
- var that = this;
-
- // Drop tabs
- this.dropArea = new dnd.DropArea({
- view: this,
- dragType: this.parent.manager.drag,
- constrain: {
- x: 20,
- y: 20
- },
- handler: function(tab) {
- tab.changeSection(that.parent.sectionId);
- }
- });
-
- return this;
- },
-
- openNewtab: function() {
- this.parent.manager.activeSection = this.parent.sectionId;
- this.parent.manager.openDefault();
- }
- });
-
-
- var TabsSectionView = hr.View.extend({
- className: "tabs-section",
- defaults: {
-
- },
- events: {
-
- },
-
- initialize: function() {
- TabsSectionView.__super__.initialize.apply(this, arguments);
-
- var that = this;
- this.manager = this.parent;
- this.sectionId = this.options.sectionId;
-
- this.tabs = new Tabs();
- this.tabs.sectionId = this.sectionId;
-
- this.header = new TabsSectionHeader({
- collection: this.tabs
- }, this);
- this.content = new TabsSectionContent({
- collection: this.tabs
- }, this);
-
- this.header.$el.appendTo(this.$el);
- this.content.$el.appendTo(this.$el);
-
- this.on("grid:layout", function() {
- this.tabs.each(function(tab) {
- tab.view.trigger("tab:layout");
- });
- }, this);
-
- return this;
- },
-
- /*
- * Add a tab to this section
- */
- addTab: function(tab, options) {
- tab.section = this.tabs;
- this.tabs.add(tab, options);
- return this;
- },
-
- /*
- * Remove a tab from this section
- */
- removeTab: function(tab) {
- this.tabs.remove(tab);
- return this;
- },
-
- render: function() {
- return this.ready();
- }
- });
-
- return TabsSectionView;
-});
\ No newline at end of file
diff --git a/client/views/tabs/tab.js b/client/views/tabs/tab.js
deleted file mode 100644
index 99e8babc..00000000
--- a/client/views/tabs/tab.js
+++ /dev/null
@@ -1,169 +0,0 @@
-define([
- "hr/utils",
- "hr/dom",
- "hr/hr",
- "models/command",
- "utils/dragdrop",
- "utils/keyboard",
- "utils/contextmenu"
-], function(_, $, hr, Command, dnd, Keyboard, ContextMenu) {
-
- // Tab header
- var TabView = hr.List.Item.extend({
- className: "component-tab",
- defaults: {
- title: "",
- tabid: "",
- close: true
- },
- events: {
- "mousedown .close": "close",
- "dblclick": "open",
- "click .close": "close",
- "click": "open",
- },
- states: {
- 'modified': "fa-asterisk",
- 'warning': "fa-exclamation",
- 'offline': "fa-flash",
- 'sync': "fa-exchange",
- 'loading': "fa fa-refresh fa-spin"
- },
-
- // Constructor
- initialize: function() {
- TabView.__super__.initialize.apply(this, arguments);
-
- var that = this;
- var $document = $(document);
-
- // Drop tabs to order
- this.dropArea = new dnd.DropArea({
- view: this,
- dragType: this.model.manager.drag,
- handler: function(tab) {
- var i = that.list.collection.indexOf(that.model);
- var ib = that.list.collection.indexOf(tab);
-
- if (ib >= 0 && ib < i) {
- i = i - 1;
- }
- console.log("drop tab at position", i);
- that.model.manager.changeTabSection(tab, that.list.collection.sectionId, {
- at: i
- });
- }
- });
-
- this.model.manager.drag.enableDrag({
- view: this,
- data: this.model,
- baseDropArea: this.list.dropArea,
- start: function() {
- that.open();
- }
- });
-
- // Context menu
- ContextMenu.add(this.$el, _.compact([
- (this.model.manager.options.newTab ? {
- 'id': "tab.new",
- 'type': "action",
- 'title': "New Tab",
- 'action': function() {
- that.model.manager.openDefault();
- }
- } : null),
- (this.model.manager.options.newTab ? { 'type': "divider" } : null),
- {
- 'id': "tab.close",
- 'type': "action",
- 'title': "Close",
- 'action': function() {
- that.close();
- }
- },
- {
- 'id': "tab.close.others",
- 'type': "action",
- 'title': "Close Other Tabs",
- 'action': function() {
- that.closeOthers();
- }
- },
- { 'type': "divider" },
- {
- 'id': "tab.group.new",
- 'type': "action",
- 'title': "New Group",
- 'action': function() {
- that.model.splitSection();
- }
- },
- { 'type': "divider" },
- that.model.manager.layoutCommand
- ]));
-
- return this;
- },
-
- // Render the tab
- render: function() {
- this.$el.empty();
-
- var inner = $("
", {
- "class": "inner",
- "html": this.model.get("title")
- }).appendTo(this.$el);
-
- var states = this.model.get("state", "").split(" ");
- _.each(states, function(state) {
- if (state && this.states[state]) {
- $("
", {
- "class": "state fa "+this.states[state]+" state-"+state
- }).prependTo(inner);
- }
- }, this);
-
- $("", {
- "class": "close",
- "href": "#",
- "html": "×"
- }).prependTo(inner);
-
- this.$el.toggleClass("active", this.model.isActive());
-
- return this.ready();
- },
-
- // Return true if is active
- isActive: function() {
- return this.$el.hasClass("active");
- },
-
- // (event) open
- open: function(e) {
- if (e != null) {
- e.preventDefault();
- e.stopPropagation();
- }
- this.model.active();
- },
-
- // (event) close
- close: function(e) {
- if (e != null) {
- e.preventDefault();
- e.stopPropagation();
- }
- this.model.close();
- },
-
- // (event) close others tabs
- closeOthers: function(e) {
- this.model.closeOthers();
- }
- });
-
- return TabView;
-});
\ No newline at end of file
diff --git a/core/cb.addons/addon.js b/core/cb.addons/addon.js
deleted file mode 100644
index 7244894d..00000000
--- a/core/cb.addons/addon.js
+++ /dev/null
@@ -1,234 +0,0 @@
-var _ = require('lodash');
-var fs = require('fs');
-var path = require('path');
-var wrench = require('wrench');
-var child_process = require('child_process');
-var Q = require("q");
-var semver = require("semver");
-
-var pkg = require("../../package.json");
-
-var utils = require("../utils");
-
-
-var Addon = function(_rootPath, options) {
- this.root = _rootPath;
- this.infos = {};
- this.options = _.defaults(options || {}, {
- blacklist: [],
- logger: console
- });
- var logger = this.options.logger;
-
- // Load addon infos from an addon's directory
- this.load = Q.fbind(function(addonDir) {
- addonDir = addonDir || this.root;
-
- // Check addon
- var packageJsonFile = path.join(addonDir, "package.json");
- if (!fs.existsSync(packageJsonFile)) {
- throw new Error("No 'package.json' in this repository: "+addonDir);
- }
- this.infos = JSON.parse(fs.readFileSync(packageJsonFile, 'utf8'));
- if (!this.isValid()) {
- throw new Error("Invalid 'package.json' file: "+packageJsonFile);
- }
-
- return this;
- });
-
- // Valid the addon
- // Valid data and valid codebox engine version
- this.isValid = function() {
- return !(!this.infos.name || !this.infos.version
- || (!this.infos.main && !this.infos.client && !this.infos.client.main)
- || !this.infos.engines || !this.infos.engines.codebox || !semver.satisfies(pkg.version, this.infos.engines.codebox));
- };
-
- // Test is symlink
- this.isSymlink = function() {
- return Q.nfcall(fs.lstat, this.root).then(function(stats) {
- return stats.isSymbolicLink();
- });
- };
-
- // Check if an addon is client side
- this.isClientside = function() {
- return (this.infos.client && this.infos.client.main);
- };
-
- // Check if an addon is node addon
- this.isNode = function() {
- return (this.infos.main);
- };
-
- // Check if an addon is already optimized
- this.isOptmized = function() {
- return fs.existsSync(path.join(this.root, "addon-built.js"));
- };
-
- // Check if node dependencies seems to be installed
- this.areDependenciesInstalled = function() {
- return fs.existsSync(path.join(this.root, "node_modules")) || this.isOptmized();
- };
-
- // Check if an addon has node dependencies
- this.hasDependencies = function() {
- return _.size(this.infos.dependencies || {}) > 0;
- };
-
- // Check if an addon has npm scripts
- this.hasScripts = function() {
- return _.size(this.infos.scripts || {}) > 0;
- };
-
- // Check if the addon is blacklisted
- this.isBlacklisted = function() {
- return _.contains(this.options.blacklist, this.infos.name);
- };
-
- // Optimize the addon
- this.optimizeClient = function(force) {
- var that = this;
- var d = Q.defer();
-
- if (!this.isClientside()
- || (this.isOptmized() && !force)) {
- return Q(this);
- }
-
- // Base directory for the addon
- var addonPath = this.root;
-
- // R.js bin
- var rjs = path.resolve(__dirname, "../../node_modules/requirejs/bin/r.js");
-
- // Path to the require-tools
- var requiretoolsPath = path.resolve(__dirname, "require-tools");
-
- // Base main
- var main = this.infos.client.main;
-
- // Output file
- var output = path.resolve(addonPath, "addon-built.js");
-
- // Build config
- var optconfig = {
- 'baseUrl': addonPath,
- 'name': main,
- 'out': output,
- //'logLevel': 4, // silent
- 'paths': {
- 'require-tools': requiretoolsPath
- },
- 'optimize': "uglify",
- 'map': {
- '*': {
- 'css': "require-tools/css/css",
- 'less': "require-tools/less/less",
- 'text': "require-tools/text/text"
- }
- }
- };
-
- // Build command for r.js
- var command = "node "+rjs+" -o "+_.reduce(utils.deepkeys(optconfig), function(s, value, key) {
- return s+key+"="+value+" ";
- }, "");
-
- // Run optimization
- logger.log("Optimizing", this.infos.name);
- return Q.nfcall(fs.unlink, output).fail(function() {
- return Q();
- }).then(function() {
- return utils.exec(command, {
- env: process.env
- })
- }).then(function() {
- logger.log("Finished", that.infos.name, "optimization");
- return Q(that);
- }, function(err) {
- logger.error("error for optimization of", that.infos.name);
- logger.error("options=", optconfig);
- logger.error(err);
- return Q.reject(err);
- });
- };
-
- // Install dependencies for this addon
- this.installDependencies = function(force) {
- var that = this;
- if (!force) {
- if (!this.hasDependencies() && !this.hasScripts()) {
- return Q(this);
- }
- }
- logger.log("Install dependencies for", this.root);
- return utils.exec("npm install .", {
- cwd: this.root,
- env: process.env
- }).then(function() {
- return Q(that);
- });
- };
-
- // Transfer to a new root directory
- this.transfer = function(newRoot, options) {
- var that = this;
- options = _.defaults({}, options || {}, {
- forceDelete: true,
- excludeHiddenUnix: false,
- preserveFiles: false
- });
-
- var addonPath = path.join(newRoot, this.infos.name);
- return Q.nfcall(wrench.copyDirRecursive, this.root, addonPath, options).then(function() {
- var addon = new Addon(addonPath, that.options);
- return addon.load();
- });
- };
-
- // Symlink this addons
- this.symlink = function(newRoot) {
- var that = this;
- var addonPath = path.join(newRoot, this.infos.name);
- return Q.nfcall(fs.symlink, this.root, addonPath, 'dir').then(function() {
- var addon = new Addon(addonPath, that.options);
- return addon.load();
- });
- };
-
- // Unlink this addon
- this.unlink = function() {
- return Q.nfcall(fs.unlink, this.root);
- };
-
- // Start the node process
- this.start = function(app) {
- var that = this;
- if (!this.isNode()) {
- return Q(this);
- }
-
- logger.log("start addon", this.root);
- return app.load([
- {
- 'packagePath': this.root
- }
- ]).then(function() {
- return Q(that);
- });
- };
-
- // Return addons cache resources list
- this.resources = function() {
- return ["addon-built.js"].concat(this.infos.client ? (this.infos.client.resources || []) : []);
- };
-
- // Return addons network resources list
- this.network = function() {
- return [].concat(this.infos.client ? (this.infos.client.network || []) : []);
- };
-};
-
-module.exports = Addon;
\ No newline at end of file
diff --git a/core/cb.addons/main.js b/core/cb.addons/main.js
deleted file mode 100644
index e837980d..00000000
--- a/core/cb.addons/main.js
+++ /dev/null
@@ -1,239 +0,0 @@
-var _ = require('lodash');
-var Q = require("q");
-var fs = require('fs');
-var path = require('path');
-var express = require('express');
-var Gittle = require('gittle');
-var wrench = require('wrench');
-var exec = require('child_process').exec;
-
-var Addon = require("./addon");
-var manager = require("./manager");
-var registry = require("./registry");
-
-// GZIP static middleware
-var gzipStatic = require('connect-gzip-static');
-
-
-function setup(options, imports, register, app) {
- var logger = imports.logger.namespace("addons", false);
- var server = imports.server;
- var events = imports.events;
- var hooks = imports.hooks;
-
- // Directory with all the defaults addons
- var configDefaultsPath = path.resolve(options.defaultsPath);
-
- // Directory with all the box addons
- var configAddonsPath = path.resolve(options.path);
-
- // Directory for temporary storage
- var configTempPath = options.tempPath ? path.resolve(options.tempPath) : null;
-
- // Options for addons
- var addonsOptions = {
- 'blacklist': options.blacklist,
- 'logger': logger
- };
-
- // Build the directory for stroign addons
- if (!fs.existsSync(configAddonsPath)) {
- wrench.mkdirSyncRecursive(configAddonsPath);
- }
-
- // Check if an addons is a default addons
- var isDefaultAddon = function(addon) {
- if (!_.isString(addon)) addon = addon.infos.name;
- return fs.existsSync(path.join(configDefaultsPath, addon));
- };
-
- // Loader
- var loadAddonsInfos = function(addonsRoot, _options) {
- return manager.loadAddonsInfos(addonsOptions, addonsRoot || configAddonsPath, _options)
- .then(function(addons) {
- return _.chain(addons)
- .map(function(addon, name) {
- addon.infos.default = isDefaultAddon(addon);
- return [
- name, addon
- ];
- })
- .object()
- .value()
- });
- };
-
- // Copy defaults addons
- var copyDefaultsAddons = function() {
- var first = loadAddonsInfos(configDefaultsPath);
-
- return first.then(manager.runAddonsOperation(function(addon) {
- logger.log("Adding default addon", addon.infos.name);
-
- // Path to addon
- var addonPath = path.resolve(configAddonsPath, addon.infos.name);
-
- return Q.nfcall(fs.lstat, addonPath)
- .then(function(stats) {
- if (!stats.isSymbolicLink()) {
- logger.error("Remove and replace ", addonPath);
- return wrench.rmdirRecursive(addonPath);
- }
-
- // Unlink only if exists
- return Q.nfcall(fs.unlink, addonPath);
- }, function(err) {
- if (err.code != 'ENOENT') {
- return Q.reject(err);
- }
- })
- .then(function() {
- // Blacklist
- if (addon.isBlacklisted()) {
- logger.error("Default addon", addon.infos.name, "is blacklisted");
- return Q();
- }
-
- // Relink it
- //logger.log("link ", addon.root, configAddonsPath)
- return addon.symlink(configAddonsPath);
- });
- }));
- };
-
- // Install an addon by its git url
- var installAddon = function(git, _options) {
- var addon, tempDir;
-
- _options = _.defaults({}, _options || {}, {
-
- });
-
- var gitRef = "master";
- var gitParts = git.split("#");
- if (gitParts.length == 2) {
- git = gitParts[0];
- gitRef = gitParts[1];
- }
-
- logger.log("Install add-on", git, "ref="+gitRef);
-
- tempDir = path.join(configTempPath, "t"+Date.now());
-
- // Create temporary dir
- return Q.nfcall(fs.mkdir, tempDir).then(function() {
- // Clone git repo
- return Gittle.clone(git, tempDir);
- })
- .then(function(repo) {
- // Checkout the addon ref
- return repo.checkout(gitRef);
- })
- .then(function() {
- // Load addon
- addon = new Addon(tempDir, addonsOptions);
- return addon.load();
- })
- .then(function() {
- // Blacklist
- if (addon.isBlacklisted()) {
- return Q.reject(new Error("Addon "+addon.infos.name+"is blacklisted"));
- }
-
- // Valid installation of addon with a hook
- return hooks.use("addons", addon.infos);
- })
- .then(function() {
- // Copy to addons dir
- return addon.transfer(configAddonsPath);
- })
- .then(function(newAddon) {
- addon = newAddon;
- })
- .fin(function() {
- // Remove temporary dir
- return Q.nfcall(wrench.rmdirRecursive, tempDir, false);
- })
- .then(function() {
- // Install node dependencies
- return addon.installDependencies();
- })
- .then(function() {
- // If client side addon then optimize it
- return addon.optimizeClient();
- })
- .then(function() {
- return addon.start(app);
- })
- .then(function() {
- // Emit events
- events.emit('addons.install', addon.infos);
-
- // Return addon infos
- return Q(addon);
- });
- };
-
- // Uninstall an addon
- var uninstallAddon = function(name) {
- var addonDir = path.join(configAddonsPath, name);
- logger.log("Uninstall add-on", name);
- if (isDefaultAddon(name)) {
- return Q.reject(new Error("Cannot uninstall a default addon"));
- }
- return Q.nfcall(wrench.rmdirRecursive, addonDir, false).then(function() {
- // Emit events
- events.emit('addons.uninstall', {
- 'name': name
- });
-
- return Q(true);
- });
- };
-
- // Init addons
- server.app.use('/static/addons', gzipStatic(configAddonsPath));
-
- // Prepare defaults addons
- return copyDefaultsAddons()
- .then(function() {
- // Load collection of addons
- return loadAddonsInfos(configAddonsPath, {
- unlinkInvalid: true
- });
- })
- .then(manager.runAddonsOperation(function(addon) {
- if (!addon.hasDependencies() || addon.areDependenciesInstalled()) return;
-
- // Install dependencies
- return addon.installDependencies();
- }, {
- failOnError: false
- }))
- .then(manager.runAddonsOperation(function(addon) {
- // Build non optimized addons
- return addon.optimizeClient();
- }, {
- failOnError: false
- }))
- .then(manager.runAddonsOperation(function(addon) {
- // Start addons
- return addon.start(app);
- }, {
- failOnError: false
- }))
- .then(function() {
- logger.log("Addons are ready");
- return {
- 'addons': {
- 'registry': registry.get,
- 'list': _.partial(loadAddonsInfos, configAddonsPath),
- 'install': installAddon,
- 'uninstall': uninstallAddon
- }
- };
- });
-};
-
-// Exports
-module.exports = setup;
diff --git a/core/cb.addons/manager.js b/core/cb.addons/manager.js
deleted file mode 100644
index ee66566f..00000000
--- a/core/cb.addons/manager.js
+++ /dev/null
@@ -1,95 +0,0 @@
-var _ = require('lodash');
-var Q = require("q");
-var fs = require('fs');
-var path = require('path');
-var express = require('express');
-var Gittle = require('gittle');
-var wrench = require('wrench');
-var exec = require('child_process').exec;
-
-var Addon = require("./addon");
-
-// Load addons list from a directory return as a map name -> addon
-var loadAddonsInfos = function(addonOptions, addonsRoot, _options) {
- // Directory to explore
- addonsRoot = addonsRoot;
-
- // Options
- _options = _.defaults({}, _options || {}, {
- ignoreError: true,
- unlinkInvalid: false
- });
-
- // Addons options
- addonOptions = _.defaults(addonOptions || {}, {
- logger: console
- });
-
- return Q.nfcall(fs.readdir, addonsRoot).then(function(dirs) {
- return _.reduce(dirs, function(previous, dir) {
- return previous.then(function(addons) {
- if (dir.indexOf('.') == 0) return Q(addons);
-
- var addonPath = path.join(addonsRoot, dir);
- var addon = new Addon(addonPath, addonOptions);
- return addon.load()
- .then(function() {
- addons[addon.infos.name] = addon;
- return Q(addons);
- }, function(err) {
- addonOptions.logger.error("error", err);
- if (_options.unlinkInvalid) {
- // When ignoring error
- // it will check that the addon is not a symlink
- // and unlink invalid ones
- addonOptions.logger.error("ignore invalid addon", addonPath);
- return addon.isSymlink().then(function(symlink) {
- if (symlink) {
- addonOptions.logger.error("unlink invalid addon:", addon.root);
- return addon.unlink();
- }
- }).then(function() {
- return Q(addons);
- }, function() {
- return Q(addons);
- });
- }
-
- if (_options.ignoreError) return Q(addons);
- return Q.reject(err);
- });
- });
- }, Q({}));
- });
-};
-
-// Run an operation for a collection fo addons
-var runAddonsOperation = function(operation, options) {
- options = _.defaults(options || {}, {
- failOnError: true
- });
-
- var failedAddons = [];
-
- return function(addons) {
- return Q.all(_.map(addons, function(addon) {
- return Q(operation(addon)).then(function() {
- return addon;
- }, function(err) {
- if (options.failOnError) {
- return Q.reject(err);
- } else {
- failedAddons.push(addon.infos.name);
- return Q();
- }
- });
- })).then(function() {
- return Q(_.omit(addons, failedAddons));
- });
- };
-};
-
-module.exports = {
- loadAddonsInfos: loadAddonsInfos,
- runAddonsOperation: runAddonsOperation
-};
\ No newline at end of file
diff --git a/core/cb.addons/package.json b/core/cb.addons/package.json
deleted file mode 100644
index 2cdf7bd4..00000000
--- a/core/cb.addons/package.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name": "cb.addons",
- "version": "0.0.1",
-
- "main": "./main.js",
- "private": true,
-
- "plugin": {
- "provides": [
- "addons"
- ],
- "consumes": [
- "events", "logger", "server", "hooks"
- ]
- }
-}
\ No newline at end of file
diff --git a/core/cb.addons/registry.js b/core/cb.addons/registry.js
deleted file mode 100644
index dbd142e7..00000000
--- a/core/cb.addons/registry.js
+++ /dev/null
@@ -1,27 +0,0 @@
-var Q = require("q");
-var _ = require("lodash");
-var request = require("request");
-
-// get content from an addons registry
-var get = function(url, options) {
- var d = Q.defer();
- request(_.extend({
- method: "GET",
- url: url+"/api/addons?limit=1000",
- json: true,
- headers: {}
- }, options || {}),
- function(error, response, body) {
- if (!error && response.statusCode == 200) {
- d.resolve(body);
- } else {
- d.reject(error || body.message || body);
- }
- });
-
- return d.promise;
-};
-
-module.exports = {
- 'get': get
-};
\ No newline at end of file
diff --git a/core/cb.addons/require-tools/css/css-builder.js b/core/cb.addons/require-tools/css/css-builder.js
deleted file mode 100755
index e1933c46..00000000
--- a/core/cb.addons/require-tools/css/css-builder.js
+++ /dev/null
@@ -1,162 +0,0 @@
-define(['require', './normalize'], function(req, normalize) {
- var cssAPI = {};
-
- function compress(css) {
- if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
- try {
- var csso = require.nodeRequire('csso');
- var csslen = css.length;
- css = csso.justDoIt(css);
- console.log('Compressed CSS output to ' + Math.round(css.length / csslen * 100) + '%.');
- return css;
- }
- catch(e) {
- console.log('Compression module not installed. Use "npm install csso -g" to enable.');
- return css;
- }
- }
- console.log('Compression not supported outside of nodejs environments.');
- return css;
- }
-
- //load file code - stolen from text plugin
- function loadFile(path) {
- if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
- var fs = require.nodeRequire('fs');
- var file = fs.readFileSync(path, 'utf8');
- if (file.indexOf('\uFEFF') === 0)
- return file.substring(1);
- return file;
- }
- else {
- var file = new java.io.File(path),
- lineSeparator = java.lang.System.getProperty("line.separator"),
- input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), 'utf-8')),
- stringBuffer, line;
- try {
- stringBuffer = new java.lang.StringBuffer();
- line = input.readLine();
- if (line && line.length() && line.charAt(0) === 0xfeff)
- line = line.substring(1);
- stringBuffer.append(line);
- while ((line = input.readLine()) !== null) {
- stringBuffer.append(lineSeparator).append(line);
- }
- return String(stringBuffer.toString());
- }
- finally {
- input.close();
- }
- }
- }
-
-
- function saveFile(path, data) {
- if (typeof process !== "undefined" && process.versions && !!process.versions.node && require.nodeRequire) {
- var fs = require.nodeRequire('fs');
- fs.writeFileSync(path, data, 'utf8');
- }
- else {
- var content = new java.lang.String(data);
- var output = new java.io.BufferedWriter(new java.io.OutputStreamWriter(new java.io.FileOutputStream(path), 'utf-8'));
-
- try {
- output.write(content, 0, content.length());
- output.flush();
- }
- finally {
- output.close();
- }
- }
- }
-
- //when adding to the link buffer, paths are normalised to the baseUrl
- //when removing from the link buffer, paths are normalised to the output file path
- function escape(content) {
- return content.replace(/(["'\\])/g, '\\$1')
- .replace(/[\f]/g, "\\f")
- .replace(/[\b]/g, "\\b")
- .replace(/[\n]/g, "\\n")
- .replace(/[\t]/g, "\\t")
- .replace(/[\r]/g, "\\r");
- }
-
- // NB add @media query support for media imports
- var importRegEx = /@import\s*(url)?\s*(('([^']*)'|"([^"]*)")|\(('([^']*)'|"([^"]*)"|([^\)]*))\))\s*;?/g;
- var absUrlRegEx = /^([^\:\/]+:\/)?\//;
-
-
- var siteRoot;
-
- var baseParts = req.toUrl('base_url').split('/');
- baseParts[baseParts.length - 1] = '';
- var baseUrl = baseParts.join('/');
-
- var curModule = 0;
- var config;
-
- var layerBuffer = [];
- var cssBuffer = {};
-
- cssAPI.load = function(name, req, load, _config) {
-
- //store config
- config = config || _config;
-
- siteRoot = siteRoot || path.resolve(config.dir || path.dirname(config.out), config.siteRoot || '.') + '/';
-
- //external URLS don't get added (just like JS requires)
- if (name.match(absUrlRegEx))
- return load();
-
- var fileUrl = req.toUrl(name + '.css');
-
- //add to the buffer
- cssBuffer[name] = normalize(loadFile(fileUrl), fileUrl, siteRoot);
-
- load();
- }
-
- cssAPI.normalize = function(name, normalize) {
- if (name.substr(name.length - 4, 4) == '.css')
- name = name.substr(0, name.length - 4);
- return normalize(name);
- }
-
- cssAPI.write = function(pluginName, moduleName, write, parse) {
- //external URLS don't get added (just like JS requires)
- if (moduleName.match(absUrlRegEx))
- return;
-
- layerBuffer.push(cssBuffer[moduleName]);
-
- if (config.buildCSS != false)
- write.asModule(pluginName + '!' + moduleName, 'define(function(){})');
- }
-
- cssAPI.onLayerEnd = function(write, data) {
- //calculate layer css
- var css = layerBuffer.join('');
-
- if (config.separateCSS) {
- console.log('Writing CSS! file: ' + data.name + '\n');
-
- var outPath = config.appDir ? config.baseUrl + data.name + '.css' : config.out.replace(/\.js$/, '.css');
-
- saveFile(outPath, compress(css));
- }
- else if (config.buildCSS != false) {
- if (css == '')
- return;
- write(
- "(function(c){var d=document,a='appendChild',i='styleSheet',s=d.createElement('style');s.type='text/css';d.getElementsByTagName('head')[0][a](s);s[i]?s[i].cssText=c:s[a](d.createTextNode(c));})\n"
- + "('" + escape(compress(css)) + "');\n"
- );
- }
-
- //clear layer buffer for next layer
- layerBuffer = [];
- }
-
- return cssAPI;
-});
diff --git a/core/cb.addons/require-tools/css/css.js b/core/cb.addons/require-tools/css/css.js
deleted file mode 100755
index 5630c093..00000000
--- a/core/cb.addons/require-tools/css/css.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Require-CSS RequireJS css! loader plugin
- * 0.0.8
- * Guy Bedford 2013
- * MIT
- */
-
-/*
- *
- * Usage:
- * require(['css!./mycssFile']);
- *
- * Tested and working in (up to latest versions as of March 2013):
- * Android
- * iOS 6
- * IE 6 - 10
- * Chome 3 - 26
- * Firefox 3.5 - 19
- * Opera 10 - 12
- *
- * browserling.com used for virtual testing environment
- *
- * Credit to B Cavalier & J Hann for the IE 6 - 9 method,
- * refined with help from Martin Cermak
- *
- * Sources that helped along the way:
- * - https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
- * - http://www.phpied.com/when-is-a-stylesheet-really-loaded/
- * - https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js
- *
- */
-
-define(function() {
- if (typeof window == 'undefined')
- return { load: function(n, r, load){ load() } };
-
- var head = document.getElementsByTagName('head')[0];
-
- var engine = window.navigator.userAgent.match(/Trident\/([^ ;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ ;]*)|MSIE\s([^ ;]*)/) || 0;
-
- // use