You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by js...@apache.org on 2009/03/19 12:24:20 UTC

svn commit: r755931 [4/9] - in /camel/trunk/components/camel-web/src/main/webapp/js/bespin: ./ client/ cmd/ editor/ mobwrite/ page/ page/dashboard/ page/editor/ page/index/ syntax/ user/ util/

Added: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/filelist.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/filelist.js?rev=755931&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/filelist.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/filelist.js Thu Mar 19 11:24:18 2009
@@ -0,0 +1,225 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is Bespin.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bespin Team (bespin@mozilla.com)
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+dojo.provide("bespin.editor.filelist");
+
+dojo.declare("bespin.editor.filelist.FilePanel", th.components.Panel, {
+    constructor: function(parms) {
+        if (!parms) parms = {};
+
+        this.fileLabel = new th.components.Label({ text: "Open Sessions", style: { color: "white", font: "8pt Tahoma" } });
+        this.fileLabel.oldPaint = this.fileLabel.paint;
+        this.fileLabel.paint = function(ctx) {
+            var d = this.d();
+
+            ctx.fillStyle = "rgb(51, 50, 46)";
+            ctx.fillRect(0, 0, d.b.w, 1);
+
+            ctx.fillStyle = "black";
+            ctx.fillRect(0, d.b.h - 1, d.b.w, 1);
+
+            var gradient = ctx.createLinearGradient(0, 1, 0, d.b.h - 2);
+            gradient.addColorStop(0, "rgb(39, 38, 33)");
+            gradient.addColorStop(1, "rgb(22, 22, 19)");
+            ctx.fillStyle = gradient;
+            ctx.fillRect(0, 1, d.b.w, d.b.h - 2);
+
+            this.oldPaint(ctx);
+        };
+
+        this.list = new th.components.List({ allowDeselection: false, style: { backgroundColor: "rgb(61, 59, 52)", color: "white", font: "8pt Tahoma" } });
+
+        var renderer = new th.components.Label({ style: { border: new th.borders.EmptyBorder({ size: 3 }) } });
+        renderer.old_paint = renderer.paint;
+        renderer.paint = function(ctx) {
+            var d = this.d();
+
+            if (this.selected) {
+                ctx.fillStyle = "rgb(177, 112, 20)";
+                ctx.fillRect(0, 0, d.b.w, 1);
+
+                var gradient = ctx.createLinearGradient(0, 0, 0, d.b.h);
+                gradient.addColorStop(0, "rgb(172, 102, 1)");
+                gradient.addColorStop(1, "rgb(219, 129, 1)");
+                ctx.fillStyle = gradient;
+                ctx.fillRect(0, 1, d.b.w, d.b.h - 2);
+
+                ctx.fillStyle = "rgb(160, 95, 1)";
+                ctx.fillRect(0, d.b.h - 1, d.b.w, 1);
+            }
+
+            if (this.item.contents) {
+                renderer.styleContext(ctx);
+                var metrics = ctx.measureText(">");
+                ctx.fillText(">", d.b.w - metrics.width - 5, d.b.h / 2 + (metrics.ascent / 2) - 1);
+            }
+
+            this.old_paint(ctx);
+        };
+        var list = this.list;
+        list.renderer = renderer;
+        list.oldGetRenderer = list.getRenderer;
+        list.getRenderer = function(rctx) {
+            var label = list.oldGetRenderer(rctx);
+            label.attributes.text = rctx.item.name;
+            return label;
+        }
+        
+        var splitter = new th.components.Splitter({ attributes: { orientation: th.HORIZONTAL }, scrollbar: new th.components.Scrollbar() });
+        splitter.scrollbar.scrollable = list;
+        splitter.scrollbar.opaque = false;
+        this.splitter = splitter;
+
+        this.add([ this.fileLabel, this.list, this.splitter]);
+
+        this.bus.bind("dragstart", this.splitter, this.ondragstart, this);
+        this.bus.bind("drag", this.splitter, this.ondrag, this);
+        this.bus.bind("dragstop", this.splitter, this.ondragstop, this);
+
+        // this is a closed container
+        delete this.add;
+        delete this.remove;
+    },
+
+    ondragstart: function(e) {
+        this.startWidth = this.prefWidth;
+    },
+
+    ondrag: function(e) {
+        var delta = e.currentPos.x - e.startPos.x;
+        this.prefWidth = this.startWidth + delta;
+        bespin.bootstrap.doResize();
+    },
+
+    ondragstop: function(e) {
+        delete this.startWidth;
+        bespin.get('settings').set('ui:filelist:width', this.prefWidth);
+    },
+
+    getPreferredWidth: function(height) {
+        return this.prefWidth || 150;
+    },
+
+    layout: function() {
+        var d = this.d();
+
+        var y = d.i.t;
+        var lh = this.fileLabel.getPreferredHeight(d.b.w);
+        this.fileLabel.bounds = { y: y, x: d.i.l, height: lh, width: d.b.w };
+        y += lh;
+
+        var sw = this.splitter.getPreferredWidth()
+        this.splitter.bounds = { x: d.b.w - d.i.r - sw, height: d.b.h - d.i.b - y, y: y, width: sw };
+
+        var innerWidth = d.b.w - d.i.w - sw;
+ 
+        this.list.bounds = { x: d.i.l, y: y, width: innerWidth, height: this.splitter.bounds.height };
+    }
+});
+
+dojo.declare("bespin.editor.filelist.UI", null, {
+    constructor: function(container) {
+        this.container = dojo.byId(container);
+
+        dojo.byId(container).innerHTML = "<canvas id='canvas_filelist' moz-opaque='true' tabindex='-1'></canvas>"+dojo.byId(container).innerHTML;        
+        this.canvas = dojo.byId(container).firstChild;
+        while (this.canvas && this.canvas.nodeType != 1) this.canvas = this.canvas.nextSibling;
+        
+        var scene = new th.Scene(dojo.byId("canvas_filelist"));  
+        this.filePanel = new bespin.editor.filelist.FilePanel();
+        scene.root.add(this.filePanel);        
+        this.scene = scene;
+        
+        var _this = this;
+        
+        scene.bus.bind("dblclick", this.filePanel.list, function(e) {
+            var item = _this.filePanel.list.selected;
+            
+            if (!item)  return;
+            
+            bespin.publish("bespin:editor:savefile", {});
+            bespin.publish("bespin:editor:openfile", { filename: item.filename });
+        });
+        
+        this.filePanel.prefWidth = 165;
+                        
+        bespin.subscribe('bespin:settings:loaded', dojo.hitch(this, function() {            
+            bespin.get('server').listOpen(this.displaySessions);
+        }));
+        
+/*      bespin.subscribe('bespin:settings:loaded', dojo.hitch(this, function() {
+            var width = bespin.get('settings').get('ui:filelist:width') || 200;
+            this.filePanel.prefWidth = width;  
+        }));*/
+    },
+    
+    displaySessions: function(sessions) {        
+        var currentProject = bespin.get('editSession').project;
+        var currentFile = bespin.get('editSession').path;
+        var items = new Array();
+        
+        for (var project in sessions) {
+            if (project != currentProject) continue;
+                        
+            for (var file in sessions[project]) {                
+                var lastSlash = file.lastIndexOf("/");
+                var path = (lastSlash == -1) ? "" : file.substring(0, lastSlash);
+                var name = (lastSlash == -1) ? file : file.substring(lastSlash + 1);
+
+                if (currentFile == file) {
+                    currentFile = false;
+                }
+
+                items.push({name: name, filename: file, project: project });                
+            }
+            
+            if (currentFile) {
+                var lastSlash = currentFile.lastIndexOf("/");
+                var path = (lastSlash == -1) ? "" : currentFile.substring(0, lastSlash);
+                var name = (lastSlash == -1) ? currentFile : currentFile.substring(lastSlash + 1);
+                items.push({name: name, filename: file, project: project });                
+            }
+            
+            items.sort(function(a, b) {
+                var x = a.name.toLowerCase();
+                var y = b.name.toLowerCase();
+                return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+            });
+            
+            bespin.get('filelist').filePanel.list.items = items;
+            
+            break;
+        }
+    },
+    
+    fitAndRepaint: function() {
+        dojo.attr(this.canvas, {width: this.filePanel.prefWidth, height: window.innerHeight - 95});
+        this.scene.layout();
+        this.scene.render();
+    },
+    
+    getWidth: function() {
+        return this.filePanel.prefWidth;
+    }
+});

Propchange: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/filelist.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/model.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/model.js?rev=755931&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/model.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/model.js Thu Mar 19 11:24:18 2009
@@ -0,0 +1,317 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is Bespin.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bespin Team (bespin@mozilla.com)
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+dojo.provide("bespin.editor.model");  
+
+// = Model =
+//
+// The editor has a model of the data that it works with. 
+// This representation is encapsulated in Bespin.Editor.DocumentModel
+dojo.declare("bespin.editor.DocumentModel", null, {
+    constructor: function() {
+        this.rows = [];
+    },
+
+    isEmpty: function() {
+        if (this.rows.length > 1) return false;
+        if (this.rows.length == 1 && this.rows[0].length > 0) return false;
+        return true;
+    },
+
+    getDirtyRows: function() {
+        var dr = (this.dirtyRows) ? this.dirtyRows : [];
+        this.dirtyRows = null;
+        return dr;
+    },
+
+    setRowDirty: function(row) {
+        if (!this.dirtyRows) this.dirtyRows = new Array(this.rows.length);
+        this.dirtyRows[row] = true;
+    },
+
+    isRowDirty: function(row) {
+        if (!this.dirtyRows) return true;
+        return this.dirtyRows[row];
+    },
+
+    setRowArray: function(rowIndex, row) {
+        if (!dojo.isArray(row)) {
+            row = row.split('');
+        }
+        this.rows[rowIndex] = row;
+    },
+
+    // gets the row array for the specified row, creating it and any intermediate rows as necessary
+    getRowArray: function(rowIndex) {
+        while (this.rows.length <= rowIndex) this.rows.push([]);
+        return this.rows[rowIndex];
+    },
+
+    // gets the number of characters in the passed row
+    getRowLength: function(rowIndex) {
+        return this.getRowArray(rowIndex).length;
+    },
+
+    // checks if there is a row at the specified index; useful because getRowArray() creates rows as necessary
+    hasRow: function(rowIndex) {
+        return (this.rows[rowIndex]);
+    },
+
+    // will insert blank spaces if passed col is past the end of passed row
+    insertCharacters: function(pos, string) {
+        var row = this.getRowArray(pos.row);
+        while (row.length < pos.col) row.push(" ");
+
+        var newrow = (pos.col > 0) ? row.splice(0, pos.col) : [];
+        newrow = newrow.concat(string.split(""));
+        this.rows[pos.row] = newrow.concat(row);
+
+        this.setRowDirty(pos.row);
+    },
+
+    getDocument: function() {
+        var file = [];
+        for (var x = 0; x < this.getRowCount(); x++) {
+            file[x] = this.getRowArray(x).join('');
+        }
+        return file.join("\n");
+    },
+
+    insertDocument: function(content) {
+        this.clear();
+        var rows = content.split("\n");
+        for (var x = 0; x < rows.length; x++) {
+            this.insertCharacters({ row: x, col: 0 }, rows[x]);
+        }
+    },
+
+    changeEachRow: function(changeFunction) {
+        for (var x = 0; x < this.getRowCount(); x++) {
+            var row = this.getRowArray(x);
+            row = changeFunction(row);
+            this.setRowArray(x, row);
+        }
+    },
+
+    replace: function(search, replace) {
+      for (var x = 0; x < this.getRowCount(); x++) {
+        var line = this.getRowArray(x).join('');
+
+        if (line.match(search)) {
+          var regex = new RegExp(search, "g");
+          var newline = line.replace(regex, replace);
+          if (newline != line) {
+            this.rows[x] = newline.split('');
+          }
+        }
+      }
+    },
+
+    // will silently adjust the length argument if invalid
+    deleteCharacters: function(pos, length) {
+        var row = this.getRowArray(pos.row);
+        var diff = (pos.col + length - 1) - row.length;
+        if (diff > 0) length -= diff;
+        if (length > 0) {
+            this.setRowDirty(pos.row);
+            return row.splice(pos.col, length).join("");
+        }
+        return "";
+    },
+
+    clear: function() {
+        this.rows = [];
+    },
+
+    deleteRows: function(row, count) {
+        var diff = (row + count - 1) - this.rows.length;
+        if (diff > 0) count -= diff;
+        if (count > 0) this.rows.splice(row, count);
+    },
+
+    // splits the passed row at the col specified, putting the right-half on a new line beneath the pased row
+    splitRow: function(pos, autoindentAmount) {
+        var row = this.getRowArray(pos.row);
+
+        var newRow;
+        if (autoindentAmount > 0) {
+            newRow = bespin.util.makeArray(autoindentAmount);
+        } else {
+            newRow = [];
+        }
+
+        if (pos.col < row.length) {
+            newRow = newRow.concat(row.splice(pos.col));
+        }
+
+        if (pos.row == (this.rows.length - 1)) {
+            this.rows.push(newRow);
+        } else {
+            var newRows = this.rows.splice(0, pos.row + 1);
+            newRows.push(newRow);
+            newRows = newRows.concat(this.rows);
+            this.rows = newRows;
+        }
+    },
+
+    // joins the passed row with the row beneath it
+    joinRow: function(rowIndex) {
+        if (rowIndex >= this.rows.length - 1) return;
+        var row = this.getRowArray(rowIndex);
+        this.rows[rowIndex] = row.concat(this.rows[rowIndex + 1]);
+        this.rows.splice(rowIndex + 1, 1);
+    },
+
+    // returns the number of rows in the model
+    getRowCount: function() {
+        return this.rows.length;
+    },
+
+    // returns a "chunk": a string representing a part of the document with \n characters representing end of line
+    getChunk: function(selection) {
+        var startPos = selection.startPos;
+        var endPos = selection.endPos;
+
+        var startCol, endCol;
+        var chunk = "";
+
+        // get the first line
+        startCol = startPos.col;
+        var row = this.getRowArray(startPos.row);
+        endCol = (endPos.row == startPos.row) ? endPos.col : row.length;
+        if (endCol > row.length) endCol = row.length;
+        chunk += row.join("").substring(startCol, endCol);
+
+        // get middle lines, if any
+        for (var i = startPos.row + 1; i < endPos.row; i++) {
+            chunk += "\n";
+            chunk += this.getRowArray(i).join("");
+        }
+
+        // get the end line
+        if (startPos.row != endPos.row) {
+            startCol = 0;
+            endCol = endPos.col;
+            row = this.getRowArray(endPos.row);
+            if (endCol > row.length) endCol = row.length;
+            chunk += "\n" + row.join("").substring(startCol, endCol);
+        }
+
+        return chunk;
+    },
+
+    // deletes the text between the startPos and endPos, joining as necessary. startPos and endPos are inclusive
+    deleteChunk: function(selection) {
+        var chunk = this.getChunk(selection);
+
+        var startPos = selection.startPos;
+        var endPos = selection.endPos;
+
+        var startCol, endCol;
+
+        // get the first line
+        startCol = startPos.col;
+        var row = this.getRowArray(startPos.row);
+        endCol = (endPos.row == startPos.row) ? endPos.col : row.length;
+        if (endCol > row.length) endCol = row.length;
+        this.deleteCharacters({ row: startPos.row, col: startCol}, endCol - startCol);
+
+        // get the end line
+        if (startPos.row != endPos.row) {
+            startCol = 0;
+            endCol = endPos.col;
+            row = this.getRowArray(endPos.row);
+            if (endCol > row.length) endCol = row.length;
+            this.deleteCharacters({ row: endPos.row, col: startCol}, endCol - startCol);
+        }
+
+        // remove any lines in-between
+        if ((endPos.row - startPos.row) > 1) this.deleteRows(startPos.row + 1, endPos.row - startPos.row - 1);
+
+        // join the rows
+        if (endPos.row != startPos.row) this.joinRow(startPos.row);
+
+        return chunk;
+    },
+
+    // inserts the chunk and returns the ending position
+    insertChunk: function(pos, chunk) {
+        var lines = chunk.split("\n");
+        var cpos = bespin.editor.utils.copyPos(pos);
+        for (var i = 0; i < lines.length; i++) {
+            this.insertCharacters(cpos, lines[i]);
+            cpos.col = cpos.col + lines[i].length;
+
+            if (i < lines.length - 1) {
+                this.splitRow(cpos);
+                cpos.col = 0;
+                cpos.row = cpos.row + 1;
+            }
+        }
+        return cpos;
+    },
+    
+    findBefore: function(row, col, comparator) {
+        var line = this.getRowArray(row);
+        if (!dojo.isFunction(comparator)) comparator = function(letter) { // default to non alpha
+            if (letter.charAt(0) == ' ') return true;
+            var letterCode = letter.charCodeAt(0);
+            return (letterCode < 48) || (letterCode > 122); // alpha only
+        };
+        
+        while (col > 0) {
+            var letter = line[col];
+            if (!letter) continue;
+            
+            if (comparator(letter)) {
+                col++; // move it back
+                break;
+            }
+            
+            col--;
+        }
+        
+        return { row: row, col: col };
+    },
+
+    findAfter: function(row, col, comparator) {
+        var line = this.getRowArray(row);
+        if (!dojo.isFunction(comparator)) comparator = function(letter) { // default to non alpha
+            if (letter.charAt(0) == ' ') return true;
+            var letterCode = letter.charCodeAt(0);
+            return (letterCode < 48) || (letterCode > 122); // alpha only
+        };
+        
+        while (col < line.length) {
+            col++;
+            
+            var letter = line[col];
+            if (!letter) continue;
+
+            if (comparator(letter)) break;
+        }
+        
+        return { row: row, col: col };
+    }
+});
\ No newline at end of file

Propchange: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/model.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/quickopen.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/quickopen.js?rev=755931&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/quickopen.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/quickopen.js Thu Mar 19 11:24:18 2009
@@ -0,0 +1,284 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is Bespin.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bespin Team (bespin@mozilla.com)
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+dojo.provide("bespin.editor.quickopen");
+
+dojo.declare("bespin.editor.quickopen.Panel", th.components.Panel, {
+    constructor: function(parms) {
+        if (!parms) parms = {};
+
+        this.list = new th.components.List({ allowDeselection: false, style: { backgroundColor: "#D5D0C0", color: "black", font: "8pt Tahoma" } });
+
+        var renderer = new th.components.Label({ style: { border: new th.borders.EmptyBorder({ size: 3 }) } });
+        renderer.old_paint = renderer.paint;
+        renderer.paint = function(ctx) {
+            var d = this.d();
+
+            if (this.selected) {
+                ctx.fillStyle = "#DDAC7C";
+                ctx.fillRect(0, 0, d.b.w, d.b.h);
+            }
+
+            this.old_paint(ctx);
+        };
+        var list = this.list;
+        list.renderer = renderer;
+        list.oldGetRenderer = list.getRenderer;
+        list.getRenderer = function(rctx) {
+            var label = list.oldGetRenderer(rctx);
+            label.attributes.text = rctx.item.name;
+            return label;
+        }
+        
+        this.scrollbar = new th.components.Scrollbar({ attributes: { orientation: th.HORIZONTAL } });
+        this.scrollbar.style.backgroundColor = "#413D35";
+        this.scrollbar.loadImages('../images/','dash_vscroll');
+        this.scrollbar.scrollable = list;
+
+        this.pathLabel = new th.components.Label({ style: { backgroundColor: "#D5D0C0", color: "black", font: "8pt Tahoma" }, text: "Select item!" });
+        this.add([ this.list, this.scrollbar, this.pathLabel]);
+
+        // this is a closed container
+        delete this.add;
+        delete this.remove;
+    },
+
+    layout: function() {
+        var d = this.d();
+
+        var y = d.i.t;
+
+        lh = this.pathLabel.getPreferredHeight(d.b.w);
+
+        y = 28;
+        var sw = 14;
+        var sh = d.b.h - d.i.b - y - lh;
+        var innerWidth = d.b.w - d.i.w - sw;
+        
+        this.list.bounds = { x: d.i.l, y: y, width: innerWidth + sw, height: sh - 1 };
+        this.pathLabel.bounds = { x: d.i.l, y: y + sh, width: innerWidth + sw, height: lh };
+    },
+    
+    paintSelf: function(ctx) {        
+        ctx.fillStyle = "#86857F";
+        ctx.fillRect(0, 0, 220, 28);
+        
+        ctx.lineWidth = 2;
+        ctx.strokeStyle = "black";
+        ctx.beginPath();              
+        ctx.moveTo(0, 28);
+        ctx.lineTo(220, 28);
+        var y = this.list.bounds.y + this.list.bounds.height + 1;
+        ctx.moveTo(0, y);
+        ctx.lineTo(220, y);
+        ctx.closePath();
+        ctx.stroke();
+    }
+});
+
+dojo.declare("bespin.editor.quickopen.API", null, {
+    constructor: function() {                
+        this.lastText = '';
+        this.requestFinished = true;
+        this.preformNewRequest = false;
+        
+        // create the Window!
+        this.panel = new bespin.editor.quickopen.Panel();
+        this.window = new th.Window({
+            title: 'Find Files', 
+            top: 100, 
+            left: 200, 
+            width: 220, 
+            height: 270, 
+            userPanel: this.panel,
+            containerId: 'quickopen',
+            closeOnClickOutside: true, 
+        });
+        this.window.centerUp(); // center the window, but more a "human" center
+
+        // add the input field to the window
+        var input = document.createElement("input");
+        input.type = "text";
+        input.id = 'quickopen_text';
+        this.window.container.appendChild(input);
+        this.input = input;
+        
+        // item selected in the list => show full path in label
+        this.window.scene.bus.bind("itemselected", this.panel.list, dojo.hitch(this, function(e) {
+            this.panel.pathLabel.attributes.text = e.item.filename;
+            this.window.layoutAndRender();
+        }));
+        
+        // item double clicked => load this file
+        this.window.scene.bus.bind("dblclick", this.panel.list, dojo.hitch(this, function(e) {
+            var item = this.panel.list.selected;
+            if (!item)  return;
+            
+            // save the current file and load up the new one
+            bespin.publish("bespin:editor:savefile", {});
+            bespin.publish("bespin:editor:openfile", { filename: item.filename });
+            
+            // adds the new opened file to the top of the openSessionFiles
+            if (this.openSessionFiles.indexOf(item.filename) != -1) {
+                this.openSessionFiles.splice(this.openSessionFiles.indexOf(item.filename), 1)
+            }                
+            this.openSessionFiles.unshift(item.filename);
+            
+            this.toggle();
+        }));
+                
+        // handle ARROW_UP and ARROW_DOWN to select items in the list and other stuff
+        dojo.connect(window, "keydown", dojo.hitch(this, function(e) {
+            if (!this.window.isVisible) return;
+            
+            var key = bespin.util.keys.Key;
+            
+            if (e.keyCode == key.ARROW_UP) {
+                this.panel.list.moveSelectionUp();
+                dojo.stopEvent(e);
+            } else if (e.keyCode == key.ARROW_DOWN) {
+                this.panel.list.moveSelectionDown();
+                dojo.stopEvent(e);
+            } else if (e.keyCode == key.ENTER) {
+                this.window.scene.bus.fire("dblclick", {}, this.panel.list);     
+            } else if (e.keyCode == 'O'.charCodeAt() && e.altKey) {
+                this.toggle();
+                dojo.stopEvent(e);
+            }
+        }));
+        
+        // look at the seachinput => has it changed?
+        dojo.connect(this.input, "keyup", dojo.hitch(this, function() {            
+            if (this.lastText != this.input.value) {
+                // the text has changed!
+                if (this.requestFinished) {
+                    this.requestFinished = false;
+                    bespin.get('server').searchFiles(bespin.get('editSession').project, this.input.value, this.displayResult);
+                } else {
+                    this.preformNewRequest = true;
+                }
+                
+                this.lastText = this.input.value;
+            }
+        }));
+        
+        // load the current opend files at startup
+        bespin.subscribe('bespin:settings:loaded', function() {            
+            bespin.get('server').listOpen(bespin.get('quickopen').displaySessions);
+        });
+    },
+    
+    toggle: function() {
+        var quickopen = bespin.get('quickopen');
+        quickopen.window.toggle();
+        
+        if (quickopen.window.isVisible) {
+            quickopen.showFiles(quickopen.openSessionFiles);
+            quickopen.input.value = '';
+            quickopen.input.focus();
+        } else {
+            quickopen.lastText = '';
+            quickopen.input.blur();
+        }
+    },
+    
+    showFiles: function(files, sortFiles) {
+        var items = new Array();
+        var quickopen = bespin.get('quickopen'); 
+        var file;
+        sortFiles = sortFiles || false;
+                
+        files = files.slice(0, 12);
+                
+        for (var x = 0; x < files.length; x++) {                
+            file = files[x];
+            var lastSlash = file.lastIndexOf("/");
+            var path = (lastSlash == -1) ? "" : file.substring(0, lastSlash);
+            var name = (lastSlash == -1) ? file : file.substring(lastSlash + 1);
+
+            items.push({name: name, filename: file});                
+        }
+        
+        if (sortFiles) {
+            items.sort(function(a, b) {
+                var x = a.name.toLowerCase();
+                var y = b.name.toLowerCase();
+                return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+            });
+        }
+        
+        quickopen.panel.list.items = items;
+        if (items.length != 0) {
+            quickopen.panel.list.selectItemByText(items[0].name);
+            quickopen.panel.pathLabel.attributes.text = items[0].filename;
+        }
+        quickopen.window.layoutAndRender();
+    },
+    
+    displayResult: function(files) {
+        var quickopen = bespin.get('quickopen');
+        quickopen.showFiles(files);
+        
+        quickopen.requestFinished = true;
+        
+        if (quickopen.preformNewRequest) {
+            quickopen.requestFinished = false;
+            quickopen.preformNewRequest = false;
+            bespin.get('server').searchFiles(bespin.get('editSession').project, quickopen.input.value, quickopen.displayResult);
+        }
+    },
+    
+    displaySessions: function(sessions) {
+        var quickopen =  bespin.get('quickopen');        
+        var currentProject = bespin.get('editSession').project;
+        var currentFile = bespin.get('editSession').path;
+        var items = new Array();
+
+        var files = sessions[currentProject];
+        for (var file in files) {
+            if (currentFile == file) {
+                currentFile = false;
+            }
+            items.push(file);
+        }
+        
+        if (currentFile) {
+            items.push(currentFile);
+        }
+        
+        quickopen.showFiles(items, true);
+        quickopen.openSessionFiles = items;                        
+    },
+    
+    handleKeys: function(e) {
+        if (this.window.isVisible) return true; // in the command line!
+
+        if (e.keyCode == 'O'.charCodeAt() && e.altKey) { // send to command line
+            bespin.get('quickopen').toggle();
+
+            dojo.stopEvent(e);
+            return true;
+        }
+    }
+});

Propchange: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/quickopen.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/themes.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/themes.js?rev=755931&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/themes.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/themes.js Thu Mar 19 11:24:18 2009
@@ -0,0 +1,191 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is Bespin.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bespin Team (bespin@mozilla.com)
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+dojo.provide("bespin.editor.themes");  
+
+// = Themes =
+//
+// The editor can be styled with Themes. This will become CSS soon, but for now is JSON
+
+// ** Coffee Theme **
+bespin.editor.themes.coffee = {
+    backgroundStyle: "#2A211C",
+    gutterStyle: "#4c4a41",
+    lineNumberColor: "#e5c138",
+    lineNumberFont: "10pt Monaco, Lucida Console, monospace",
+    zebraStripeColor: "#2A211C",
+    editorTextColor: "rgb(230, 230, 230)",
+    editorSelectedTextColor: "rgb(240, 240, 240)",
+    editorSelectedTextBackground: "#526DA5",
+    cursorStyle: "#879aff",
+    cursorType: "ibeam",       // one of "underline" or "ibeam"
+    unfocusedCursorStrokeStyle: "#FF0033",
+    unfocusedCursorFillStyle: "#73171E",
+    partialNibStyle: "rgba(100, 100, 100, 0.3)",
+    partialNibArrowStyle: "rgba(255, 255, 255, 0.3)",
+    partialNibStrokeStyle: "rgba(150, 150, 150, 0.3)",
+    fullNibStyle: "rgb(100, 100, 100)",
+    fullNibArrowStyle: "rgb(255, 255, 255)",
+    fullNibStrokeStyle: "rgb(150, 150, 150)",
+    scrollTrackFillStyle: "rgba(50, 50, 50, 0.8)",
+    scrollTrackStrokeStyle: "rgb(150, 150, 150)",
+    scrollBarFillStyle: "rgba(0, 0, 0, %a)",
+    scrollBarFillGradientTopStart: "rgba(90, 90, 90, %a)",
+    scrollBarFillGradientTopStop: "rgba(40, 40, 40, %a)",
+    scrollBarFillGradientBottomStart: "rgba(22, 22, 22, %a)",
+    scrollBarFillGradientBottomStop: "rgba(44, 44, 44, %a)",
+
+    // syntax definitions
+    plain: "#bdae9d",
+    keyword: "#42a8ed",
+    string: "#039a0a",
+    comment: "#666666",
+    'c-comment': "#666666",
+    punctuation: "#888888",
+    attribute: "#BF9464",
+    test: "rgb(255,0,0)",
+    cdata: "#bdae9d",
+    "attribute-value": "#039a0a",
+    tag: "#46a8ed",
+    color: "#c4646b",
+    "tag-name": "#46a8ed",
+    value: "#039a0a",
+    important: "#990000",
+    sizes: "#990000",
+    cssclass: "#BF9464",
+    cssid: "#46a8ed"
+};
+
+// ** Coffee Zebra Theme **
+bespin.editor.themes.coffeezebra = {};
+dojo.mixin(bespin.editor.themes.coffeezebra, bespin.editor.themes.coffee);
+bespin.editor.themes.coffeezebra.zebraStripeColor = '#FFFFFF';
+
+// ** White Theme **
+bespin.editor.themes.white = {
+    backgroundStyle: "#FFFFFF",
+    gutterStyle: "#d2d2d2",
+    lineNumberColor: "#888888",
+    lineNumberFont: "10pt Monaco, Lucida Console, monospace",
+    zebraStripeColor: "#FFFFFF",
+    editorTextColor: "#000000",
+    editorSelectedTextColor: "rgb(240, 240, 240)",
+    editorSelectedTextBackground: "#4d97ff",
+    cursorStyle: "#879aff",
+    cursorType: "ibeam",       // one of "underline" or "ibeam"
+    unfocusedCursorStrokeStyle: "#FF0033",
+    unfocusedCursorFillStyle: "#73171E",
+    partialNibStyle: "rgba(100, 100, 100, 0.3)",
+    partialNibArrowStyle: "rgba(255, 255, 255, 0.3)",
+    partialNibStrokeStyle: "rgba(150, 150, 150, 0.3)",
+    fullNibStyle: "rgb(100, 100, 100)",
+    fullNibArrowStyle: "rgb(255, 255, 255)",
+    fullNibStrokeStyle: "rgb(150, 150, 150)",
+    scrollTrackFillStyle: "rgba(50, 50, 50, 0.8)",
+    scrollTrackStrokeStyle: "rgb(150, 150, 150)",
+    scrollBarFillStyle: "rgba(0, 0, 0, %a)",
+    scrollBarFillGradientTopStart: "rgba(90, 90, 90, %a)",
+    scrollBarFillGradientTopStop: "rgba(40, 40, 40, %a)",
+    scrollBarFillGradientBottomStart: "rgba(22, 22, 22, %a)",
+    scrollBarFillGradientBottomStop: "rgba(44, 44, 44, %a)",
+
+    // syntax definitions
+    plain: "#bdae9d",
+    keyword: "#0000ff",
+    string: "#036907",
+    comment: "#0066ff",
+    'c-comment': "#0066ff",
+    punctuation: "#888888",
+    attribute: "#BF9464",
+    test: "rgb(255,0,0)",
+    cdata: "#bdae9d",
+    "attribute-value": "#BF9464",
+    tag: "#bdae9d",
+    "tag-name": "#bdae9d",
+    value: "#BF9464",
+    important: "#990000",
+    cssclass: "#BF9464",
+    cssid: "#bdae9d"
+};
+
+// ** White Zebra Theme **
+bespin.editor.themes.whitezebra = {};
+dojo.mixin(bespin.editor.themes.whitezebra, bespin.editor.themes.white); 
+bespin.editor.themes.whitezebra.zebraStripeColor = '#EAEAEA';
+
+// ** Black Theme **
+bespin.editor.themes.black = {
+    backgroundStyle: "#000000",
+    gutterStyle: "#d2d2d2",
+    lineNumberColor: "#888888",
+    lineNumberFont: "10pt Monaco, Lucida Console, monospace",
+    zebraStripeColor: "#000000", //"#111111",
+    editorTextColor: "rgb(230, 230, 230)",
+    editorSelectedTextColor: "rgb(240, 240, 240)",
+    editorSelectedTextBackground: "#243b75",
+    cursorStyle: "#879aff",
+    cursorType: "ibeam",       // one of "underline" or "ibeam"
+    unfocusedCursorStrokeStyle: "#FF0033",
+    unfocusedCursorFillStyle: "#73171E",
+    partialNibStyle: "rgba(100, 100, 100, 0.3)",
+    partialNibArrowStyle: "rgba(255, 255, 255, 0.3)",
+    partialNibStrokeStyle: "rgba(150, 150, 150, 0.3)",
+    fullNibStyle: "rgb(100, 100, 100)",
+    fullNibArrowStyle: "rgb(255, 255, 255)",
+    fullNibStrokeStyle: "rgb(150, 150, 150)",
+    scrollTrackFillStyle: "rgba(50, 50, 50, 0.8)",
+    scrollTrackStrokeStyle: "rgb(150, 150, 150)",
+    scrollBarFillStyle: "rgba(0, 0, 0, %a)",
+    scrollBarFillGradientTopStart: "rgba(90, 90, 90, %a)",
+    scrollBarFillGradientTopStop: "rgba(40, 40, 40, %a)",
+    scrollBarFillGradientBottomStart: "rgba(22, 22, 22, %a)",
+    scrollBarFillGradientBottomStop: "rgba(44, 44, 44, %a)",
+
+    // syntax definitions
+    plain: "#bdae9d",
+    preprocessor: "rgb(100,100,100)",
+    keyword: "#42a8ed",
+    string: "#039a0a",
+    comment: "#666666",
+    'c-comment': "#666666",
+    punctuation: "#888888",
+    attribute: "#BF9464",
+    test: "rgb(255,0,0)",
+    cdata: "#bdae9d",
+    "attribute-value": "#BF9464",
+    tag: "#bdae9d",
+    "tag-name": "#bdae9d",
+    value: "#BF9464",
+    important: "#990000",
+    cssclass: "#BF9464",
+    cssid: "#bdae9d"
+};
+
+// ** Black Zebra Theme **
+bespin.editor.themes.blackzebra = {};
+dojo.mixin(bespin.editor.themes.blackzebra, bespin.editor.themes.black); 
+bespin.editor.themes.blackzebra.zebraStripeColor = '#111111';
+
+// ** Setup the default **
+bespin.editor.themes['default'] = bespin.editor.themes.coffee;

Propchange: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/themes.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/toolbar.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/toolbar.js?rev=755931&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/toolbar.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/toolbar.js Thu Mar 19 11:24:18 2009
@@ -0,0 +1,229 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is Bespin.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bespin Team (bespin@mozilla.com)
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+dojo.provide("bespin.editor.toolbar");
+
+// = Toolbar =
+//
+// The editor has the notion of a toolbar which are components that can drive the editor from outside of itself
+// Such examples are collaboration views, file browser, undo/redo, cut/copy/paste and more.
+
+dojo.declare("bespin.editor.Toolbar", null, {
+    DEFAULT_TOOLBAR: ["collaboration", "files", "dashboard", "target_browsers", "save",
+                      "close", "undo", "redo", "preview", "fontsize"],
+    FONT_SIZES: {
+        1: 8,  // small
+        2: 10, // medium
+        3: 14  // large
+    },
+
+    showCollab: false,
+    showFiles: false,
+    showTarget: false,
+
+    showCollabHotCounter: 0,
+
+    constructor: function(editor, opts) {
+        this.editor = editor || bespin.get('editor');
+        this.currentFontSize = 2;
+
+        if (opts.setupDefault) this.setupDefault();
+    },
+
+    setup: function(type, el) {
+        if (dojo.isFunction(this.components[type])) this.components[type](this, el);
+    },
+
+    /*
+     * Go through the default list and try to hitch onto the DOM element
+     */
+    setupDefault: function() {
+        dojo.forEach(this.DEFAULT_TOOLBAR, dojo.hitch(this, function(item) {
+            var item_el = dojo.byId("toolbar_" + item);
+            if (item_el) {
+                this.setup(item, item_el);
+            }
+        }));
+    },
+
+    components: {
+        collaboration: function(toolbar, el) {
+            var collab = dojo.byId(el) || dojo.byId("toolbar_collaboration");
+            dojo.connect(collab, 'click', function() {
+                toolbar.showCollab = !toolbar.showCollab;
+                collab.src = "images/" + ( (toolbar.showCollab) ? "icn_collab_on.png" : (toolbar.showCollabHotCounter == 0) ? "icn_collab_off.png" : "icn_collab_watching.png" );
+                bespin.page.editor.recalcLayout();
+            });
+            dojo.connect(collab, 'mouseover', function() {
+                collab.style.cursor = "pointer";
+                collab.src = "images/icn_collab_on.png";
+            });
+            dojo.connect(collab, 'mouseout', function() {
+                collab.style.cursor = "default";
+                collab.src = "images/icn_collab_off.png";
+            });
+        },
+
+        files: function(toolbar, el) {
+            var files = dojo.byId(el) || dojo.byId("toolbar_files");
+            dojo.connect(files, 'click', function() {
+                toolbar._showFiles = !toolbar._showFiles;
+                files.src = "images/" + ( (toolbar._showFiles) ? "icn_files_on.png" : "icn_files_off.png" );
+                bespin.page.editor.recalcLayout();
+            });
+            dojo.connect(files, 'mouseover', function() {
+                files.style.cursor = "pointer";
+                files.src = "images/icn_files_on.png";
+            });
+            dojo.connect(files, 'mouseout', function() {
+                files.style.cursor = "default";
+                files.src = "images/icn_files_off.png";
+            });
+        },
+
+        dashboard: function(toolbar, el) {
+            var dashboard = dojo.byId(el) || dojo.byId("toolbar_dashboard");
+            dojo.connect(dashboard, 'mouseover', function() {
+                dashboard.style.cursor = "pointer";
+                dashboard.src = "images/icn_dashboard_on.png";
+            });
+            dojo.connect(dashboard, 'mouseout', function() {
+                dashboard.style.cursor = "default";
+                dashboard.src = "images/icn_dashboard_off.png";
+            });
+        },
+
+        target_browsers: function(toolbar, el) {
+            var target = dojo.byId(el) || dojo.byId("toolbar_target_browsers");
+            dojo.connect(target, 'click', function() {
+                toolbar._showTarget = !toolbar._showTarget;
+                target.src = "images/" + ( (toolbar._showTarget) ? "icn_target_on.png" : "icn_target_off.png" );
+                bespin.page.editor.recalcLayout();
+            });
+            dojo.connect(target, 'mouseover', function() {
+                target.style.cursor = "pointer";
+                target.src = "images/icn_target_on.png";
+            });
+            dojo.connect(target, 'mouseout', function() {
+                target.style.cursor = "default";
+                target.src = "images/icn_target_off.png";
+            });
+        },
+
+        save: function(toolbar, el) {
+            var save = dojo.byId(el) || dojo.byId("toolbar_save");
+            dojo.connect(save, 'mouseover', function() {
+                save.src = "images/icn_save_on.png";
+            });
+
+            dojo.connect(save, 'mouseout', function() {
+                save.src = "images/icn_save.png";
+            });
+
+            dojo.connect(save, 'click', function() {
+                bespin.publish("bespin:editor:savefile");
+            });
+        },
+
+        close: function(toolbar, el) {
+            var close = dojo.byId(el) || dojo.byId("toolbar_close");
+            dojo.connect(close, 'mouseover', function() {
+                close.src = "images/icn_close_on.png";
+            });
+
+            dojo.connect(close, 'mouseout', function() {
+                close.src = "images/icn_close.png";
+            });
+
+            dojo.connect(close, 'click', function() {
+                bespin.publish("bespin:editor:closefile");
+            });
+        },
+
+        undo: function(toolbar, el) {
+            var undo = dojo.byId(el) || dojo.byId("toolbar_undo");
+            dojo.connect(undo, 'mouseover', function() {
+                undo.src = "images/icn_undo_on.png";
+            });
+
+            dojo.connect(undo, 'mouseout', function() {
+                undo.src = "images/icn_undo.png";
+            });
+
+            dojo.connect(undo, 'click', function() {
+                toolbar.editor.ui.actions.undo();
+            });
+        },
+
+        redo: function(toolbar, el) {
+            var redo = dojo.byId(el) || dojo.byId("toolbar_undo");
+
+            dojo.connect(redo, 'mouseover', function() {
+                redo.src = "images/icn_redo_on.png";
+            });
+
+            dojo.connect(redo, 'mouseout', function() {
+                redo.src = "images/icn_redo.png";
+            });
+
+            dojo.connect(redo, 'click', function() {
+                toolbar.editor.ui.actions.redo();
+            });
+        },
+
+        preview: function(toolbar, el) {
+            var preview = dojo.byId(el) || dojo.byId("toolbar_preview");
+
+            dojo.connect(preview, 'mouseover', function() {
+                preview.src = "images/icn_preview_on.png";
+            });
+
+            dojo.connect(preview, 'mouseout', function() {
+                preview.src = "images/icn_preview.png";
+            });
+
+            dojo.connect(preview, 'click', function() {
+                bespin.publish("bespin:editor:preview"); // use default file
+            });
+        },
+
+        fontsize: function(toolbar, el) {
+            var fontsize = dojo.byId(el) || dojo.byId("toolbar_fontsize");
+
+            dojo.connect(fontsize, 'mouseover', function() {
+                fontsize.src = "images/icn_fontsize_on.png";
+            });
+
+            dojo.connect(fontsize, 'mouseout', function() {
+                fontsize.src = "images/icn_fontsize.png";
+            });
+
+            // Change the font size between the small, medium, and large settings
+            dojo.connect(fontsize, 'click', function() {
+                toolbar.currentFontSize = (toolbar.currentFontSize > 2) ? 1 : toolbar.currentFontSize + 1;
+                bespin.publish("bespin:settings:set:fontsize", [{ value: toolbar.FONT_SIZES[toolbar.currentFontSize] }]);
+            });
+        }
+    }
+});
\ No newline at end of file

Propchange: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/toolbar.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/undo.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/undo.js?rev=755931&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/undo.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/undo.js Thu Mar 19 11:24:18 2009
@@ -0,0 +1,105 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is Bespin.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bespin Team (bespin@mozilla.com)
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+dojo.provide("bespin.editor.undo");
+
+// = Undo Handling =
+//
+// Handle the undo/redo queues for the editor
+
+// ** {{{ bespin.editor.UndoManager }}} **
+//
+// Run the undo/redo stack
+dojo.declare("bespin.editor.UndoManager", null, {  
+    constructor: function(editor) {
+        this.editor = editor;
+        this.undoStack = [];
+        this.redoStack = [];
+        this.syncHelper = undefined;
+    },
+
+    maxUndoLength: 100,
+
+    canUndo: function() {
+        return this.undoStack.length > 0;
+    },
+
+    undo: function() {
+        if (this.undoStack.length == 0) return;
+        var item = this.undoStack.pop();
+
+        this.editor.cursorManager.moveCursor(item.undoOp.pos);
+        item.undo();
+        this.redoStack.push(item);
+
+        if (this.syncHelper) this.syncHelper.undo();
+    },
+
+    redo: function() {
+        if (this.redoStack.length == 0) return;
+        var item = this.redoStack.pop();
+
+        this.editor.cursorManager.moveCursor(item.redoOp.pos);
+        item.redo();
+        this.undoStack.push(item);
+
+        if (this.syncHelper) this.syncHelper.redo();
+    },
+
+    addUndoOperation: function(item) {
+        if (item.undoOp.queued) return;
+
+        if (this.redoStack.length > 0) this.redoStack = [];
+
+        while (this.undoStack.length + 1 > this.maxUndoLength) {
+            this.undoStack.shift();
+        }
+        this.undoStack.push(item);
+        item.editor = this.editor;
+
+        // prevent undo operations from placing themselves back in the undo stack
+        item.undoOp.queued = true;
+        item.redoOp.queued = true;
+
+        if (this.syncHelper) this.syncHelper.queueUndoOp(item);
+    }
+});
+
+// ** {{{ bespin.editor.UndoManager }}} **
+//
+// The core operation contains two edit operations; one for undoing an operation, and the other for redoing it 
+dojo.declare("bespin.editor.UndoItem", null, {
+    constructor: function(undoOp, redoOp) {
+        this.undoOp = undoOp;
+        this.redoOp = redoOp;
+    },
+
+    undo: function() {
+        this.editor.ui.actions[this.undoOp.action](this.undoOp);
+    },
+
+    redo: function() {
+        this.editor.ui.actions[this.redoOp.action](this.redoOp);
+    }
+});
\ No newline at end of file

Propchange: camel/trunk/components/camel-web/src/main/webapp/js/bespin/editor/undo.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-web/src/main/webapp/js/bespin/events.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/bespin/events.js?rev=755931&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/bespin/events.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/bespin/events.js Thu Mar 19 11:24:18 2009
@@ -0,0 +1,516 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is Bespin.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bespin Team (bespin@mozilla.com)
+ *
+ * ***** END LICENSE BLOCK ***** */
+ 
+dojo.provide("bespin.events");
+
+dojo.require("bespin.util.util");
+
+// = Event Bus =
+//
+// Global home for event watching where it doesn't fit using the pattern
+// of custom events tied to components themselves such as:
+//
+// * {{{bespin.cmd.commandline.Events}}}
+// * {{{bespin.client.settings.Events}}}
+
+// ** {{{ Event: bespin:editor:titlechange }}} **
+// 
+// Observe a title change event and then... change the document.title!
+bespin.subscribe("bespin:editor:titlechange", function(event) {
+    var title;
+    if (event.filename) title = event.filename + ' - editing with Bespin';
+    else if (event.title) title = event.title;
+    else title = 'Bespin &raquo; Code in the Cloud';
+
+    document.title = title;
+});
+
+// ** {{{ Event: bespin:editor:evalfile }}} **
+// 
+// Load up the given file and try to run it
+bespin.subscribe("bespin:editor:evalfile", function(event) {
+    var project  = event.project;
+    var filename = event.filename;
+    var scope    = event.scope || bespin.events.defaultScope();
+
+    if (!project || !filename) {
+        bespin.get('commandLine').showInfo("Please, I need a project and filename to evaulate");
+        return;
+    }
+
+    bespin.get('files').loadFile(project, filename, function(file) {
+        with (scope) { // wow, using with. crazy.
+            try {
+                bespin.publish("bespin:cmdline:suppressinfo");
+                eval(file.content);
+                bespin.publish("bespin:cmdline:unsuppressinfo");
+            } catch (e) {
+                bespin.get('commandLine').showInfo("There is a error trying to run " + filename + " in project " + project + ":<br><br>" + e);
+            }
+        }
+    }, true);
+});
+
+// ** {{{ Event: bespin:editor:preview }}} **
+// 
+// Preview the given file in a browser context
+bespin.subscribe("bespin:editor:preview", function(event) {
+    var editSession = bespin.get('editSession');
+    var filename = event.filename || editSession.path;  // default to current page
+    var project  = event.project  || editSession.project; 
+
+    // Make sure to save the file first
+    bespin.publish("bespin:editor:savefile", {
+        filename: filename
+    });
+
+    if (filename) {
+        window.open(bespin.util.path.combine("preview/at", project, filename));
+    }
+});
+
+// ** {{{ Event: bespin:editor:closefile }}} **
+// 
+// Close the given file (wrt the session)
+bespin.subscribe("bespin:editor:closefile", function(event) {
+    var editSession = bespin.get('editSession');
+    var filename = event.filename || editSession.path;  // default to current page
+    var project  = event.project  || editSession.project;   
+    
+    bespin.get('files').closeFile(project, filename, function() {
+        bespin.publish("bespin:editor:closedfile", { filename: filename }); 
+        
+        // if the current file, move on to a new one
+        if (filename == editSession.path) bespin.publish("bespin:editor:newfile");    
+
+        bespin.publish("bespin:cmdline:showinfo", { msg: 'Closed file: ' + filename });
+    });
+});
+
+// ** {{{ Event: bespin:editor:config:run }}} **
+//
+// Load and execute the user's config file
+bespin.subscribe("bespin:editor:config:run", function(event) {
+    bespin.publish("bespin:editor:evalfile", {
+        project: bespin.userSettingsProject,
+        filename: "config.js"
+    });
+});
+
+// ** {{{ Event: bespin:editor:config:edit }}} **
+// 
+// Open the users special config file
+bespin.subscribe("bespin:editor:config:edit", function(event) {
+    if (!bespin.userSettingsProject) {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "You don't seem to have a user project. Sorry." });
+        return;
+    }
+
+    bespin.publish("bespin:editor:openfile", {
+        project: bespin.userSettingsProject,
+        filename: "config.js"
+    });
+});
+
+// ** {{{ Event: bespin:cmdline:executed }}} **
+// 
+// Set the last command in the status window
+bespin.subscribe("bespin:cmdline:executed", function(event) {
+    var commandname = event.command.name;
+    var args        = event.args;
+
+    dojo.byId('message').innerHTML = "last cmd: <span title='" + commandname + " " + args + "'>" + commandname + "</span>"; // set the status message area
+});
+
+// ** {{{ Event: bespin:commands:load }}} **
+// 
+// Create a new command in your special command directory
+bespin.subscribe("bespin:commands:load", function(event) {
+    var commandname = event.commandname;
+    
+    if (!commandname) {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "Please pass me a command name to load." });
+        return;
+    }
+
+    bespin.get('files').loadFile(bespin.userSettingsProject, "commands/" + commandname + ".js", function(file) {
+        try {
+            eval('bespin.get("commandLine").addCommands([' + file.content + '])');
+        } catch (e) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Something is wrong about the command:<br><br>" + e });
+        }
+    }, true);
+});
+
+// ** {{{ Event: bespin:commands:edit }}} **
+// 
+// Edit the given command
+bespin.subscribe("bespin:commands:edit", function(event) {
+    var commandname = event.commandname;
+    
+    if (!bespin.userSettingsProject) {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "You don't seem to have a user project. Sorry." });
+        return;
+    }
+
+    if (!commandname) {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "Please pass me a command name to edit." });
+        return;
+    }
+    
+    bespin.publish("bespin:editor:forceopenfile", {
+        project: bespin.userSettingsProject,
+        filename: "commands/" + commandname + ".js",
+        content: "{\n    name: '" + commandname + "',\n    takes: [YOUR_ARGUMENTS_HERE],\n    preview: 'execute any editor action',\n    execute: function(self, args) {\n\n    }\n}"
+    });
+});
+
+// ** {{{ Event: bespin:commands:list }}} **
+// 
+// List the custom commands that a user has
+bespin.subscribe("bespin:commands:list", function(event) {
+    if (!bespin.userSettingsProject) {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "You don't seem to have a user project. Sorry." });
+        return;
+    }
+
+    bespin.get('server').list(bespin.userSettingsProject, 'commands/', function(commands) {
+        var output;
+        
+        if (!commands || commands.length < 1) {
+            output = "You haven't installed any custom commands.<br>Want to <a href='https://wiki.mozilla.org/Labs/Bespin/Roadmap/Commands'>learn how?</a>";
+        } else {
+            output = "<u>Your Custom Commands</u><br/><br/>";
+            
+            output += dojo.map(dojo.filter(commands, function(file) {
+                return bespin.util.endsWith(file.name, '\\.js');
+            }), function(c) { return c.name.replace(/\.js$/, ''); }).join("<br>");
+        }
+        
+        bespin.publish("bespin:cmdline:showinfo", { msg: output });
+    });
+});
+
+// ** {{{ Event: bespin:commands:delete }}} **
+// 
+// Delete the named command
+bespin.subscribe("bespin:commands:delete", function(event) {
+    var commandname = event.commandname;
+    
+    var editSession = bespin.get('editSession');
+    var files = bespin.get('files');
+
+    if (!bespin.userSettingsProject) {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "You don't seem to have a user project. Sorry." });
+        return;
+    }
+
+    if (!commandname) {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "Please pass me a command name to delete." });
+        return;
+    }
+
+    var commandpath = "commands/" + commandname + ".js";
+    
+    files.removeFile(bespin.userSettingsProject, commandpath, function() {
+        if (editSession.checkSameFile(bespin.userSettingsProject, commandpath)) bespin.get('editor').model.clear(); // only clear if deleting the same file
+        bespin.publish("bespin:cmdline:showinfo", { msg: 'Removed command: ' + commandname, autohide: true });
+    }, function(xhr) {
+        bespin.publish("bespin:cmdline:showinfo", { 
+            msg: "Wasn't able to remove the command <b>" + commandname + "</b><br/><em>Error</em> (probably doesn't exist): " + xhr.responseText, 
+            autohide: true 
+        });
+    });
+});
+
+// ** {{{ Event: bespin:directory:create }}} **
+// 
+// Create a new directory
+bespin.subscribe("bespin:directory:create", function(event) {
+    var editSession = bespin.get('editSession');
+    var files = bespin.get('files');
+
+    var project = event.project || editSession.project;
+    var path = event.path || '';
+    
+    files.makeDirectory(project, path, function() {
+        if (path == '') bespin.publish("bespin:project:set", { project: project });
+        bespin.publish("bespin:cmdline:showinfo", { 
+            msg: 'Successfully created directory: [project=' + project + ', path=' + path + ']', autohide: true });
+    }, function() {
+        bespin.publish("bespin:cmdline:showinfo", {
+            msg: 'Unable to delete directory: [project=' + project + ', path=' + path + ']' + project, autohide: true });
+    });
+});
+
+// ** {{{ Event: bespin:directory:delete }}} **
+// 
+// Delete a directory
+bespin.subscribe("bespin:directory:delete", function(event) {
+    var editSession = bespin.get('editSession');
+    var files = bespin.get('files');
+
+    var project = event.project || editSession.project;
+    var path = event.path || '';
+    
+    if (project == bespin.userSettingsProject && path == '/') return; // don't delete the settings project
+    
+    files.removeDirectory(project, path, function() {
+        if (path == '/') bespin.publish("bespin:project:set", { project: '' }); // reset
+        bespin.publish("bespin:cmdline:showinfo", { 
+            msg: 'Successfully deleted directory: [project=' + project + ', path=' + path + ']', autohide: true });
+    }, function() {
+        bespin.publish("bespin:cmdline:showinfo", {
+            msg: 'Unable to delete directory: [project=' + project + ', path=' + path + ']', autohide: true });
+    });
+});
+
+// ** {{{ Event: bespin:project:create }}} **
+// 
+// Create a new project
+bespin.subscribe("bespin:project:create", function(event) {
+    var project = event.project || bespin.get('editSession').project;
+    
+    bespin.publish("bespin:directory:create", { project: project });
+});
+
+// ** {{{ Event: bespin:project:delete }}} **
+// 
+// Delete a project
+bespin.subscribe("bespin:project:delete", function(event) {
+    var project = event.project;
+    if (!project || project == bespin.userSettingsProject) return; // don't delete the settings project
+    
+    bespin.publish("bespin:directory:delete", { project: project });
+});
+
+// ** {{{ Event: bespin:project:rename }}} **
+// 
+// Rename a project
+bespin.subscribe("bespin:project:rename", function(event) {
+    var currentProject = event.currentProject;
+    var newProject = event.newProject;
+    if ( (!currentProject || !newProject) || (currentProject == newProject) ) return;
+    
+    bespin.get('server').renameProject(currentProject, newProject, {
+        call: function() {
+            bespin.publish("bespin:project:set", { project: newProject });
+        },
+        onFailure: function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: 'Unable to rename project from ' + currentProject + " to " + newProject + "<br><br><em>Are you sure that the " + currentProject + " project exists?</em>", autohide: true });
+        }
+    });
+});
+
+
+// ** {{{ Event: bespin:project:import }}} **
+// 
+// Import a project
+bespin.subscribe("bespin:project:import", function(event) {
+    var project = event.project;
+    var url = event.url;
+
+    bespin.get('server').importProject(project, url, { call: function() {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "Project " + project + " imported from:<br><br>" + url, autohide: true });
+    }, onFailure: function(xhr) {
+        bespin.publish("bespin:cmdline:showinfo", { msg: "Unable to import " + project + " from:<br><br>" + url + ".<br><br>Maybe due to: " + xhr.responseText });
+    }});
+});
+
+
+
+// == Events
+// 
+// ** {{{ bespin.events }}} **
+//
+// Helpers for the event subsystem
+
+// ** {{{ bespin.events.toFire }}} **
+//
+// Given an {{{eventString}}} parse out the arguments and configure an event object
+//
+// Example events:
+//
+// * {{{bespin:cmdline:execute;name=ls,args=bespin}}}
+// * {{{bespin:cmdline:execute}}} 
+    
+dojo.mixin(bespin.events, {
+    toFire: function(eventString) {
+        var event = {};
+        if (!eventString.indexOf(';')) { // just a plain command with no args
+            event.name = eventString;
+        } else { // split up the args
+            var pieces = eventString.split(';');
+            event.name = pieces[0];
+            event.args = bespin.util.queryToObject(pieces[1], ',');
+        }
+        return event;
+    }
+});
+
+// ** {{{ bespin.events.defaultScope }}} **
+//
+// Return a default scope to be used for evaluation files
+bespin.events.defaultScope = function() {
+    if (bespin.events._defaultScope) return bespin.events._defaultScope;
+    
+    var scope = {
+        bespin: bespin,
+        include: function(file) {
+            bespin.publish("bespin:editor:evalfile", {
+                project: bespin.userSettingsProject,
+                filename: file
+            });
+        },
+        tryTocopyComponent: function(id) {
+            bespin.withComponent(id, dojo.hitch(this, function(component) {
+                this.id = component;
+            }));
+        },
+        require: dojo.require,
+        publish: bespin.publish,
+        subscribe: bespin.subscribe
+    };
+
+    bespin.withComponent('commandLine', function(commandLine) {
+        scope.commandLine = commandLine;
+        scope.execute = function(cmd) {
+            commandLine.executeCommand(cmd);
+        };
+    });
+
+    scope.tryTocopyComponent('editor');
+    scope.tryTocopyComponent('editSession');
+    scope.tryTocopyComponent('files');
+    scope.tryTocopyComponent('server');
+    scope.tryTocopyComponent('toolbar');
+
+    bespin.events._defaultScope = scope; // setup the short circuit
+
+    return bespin.events._defaultScope;
+};
+
+// ** {{{ Event: bespin:network:followers }}} **
+// Get a list of our followers
+bespin.subscribe("bespin:network:followers", function() {
+    bespin.get('server').followers({
+        call:function(data) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Following " + data });
+        },
+        onFailure:function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Failed to retrieve followers. Maybe due to: " + xhr.responseText });
+        }
+    });
+});
+
+// ** {{{ Event: bespin:network:follow }}} **
+// Add to the list of users that we follow
+bespin.subscribe("bespin:network:follow", function(usernames) {
+    bespin.get('server').follow(usernames, {
+        call:function(data) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Following " + data });
+        },
+        onFailure:function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Failed to retrieve followers. Maybe due to: " + xhr.responseText });
+        }
+    });
+});
+
+// ** {{{ Event: bespin:network:unfollow }}} **
+// Remove users from the list that we follow
+bespin.subscribe("bespin:network:unfollow", function(usernames) {
+    bespin.get('server').unfollow(usernames, {
+        call:function(data) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Following " + data });
+        },
+        onFailure:function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Failed to retrieve followers. Maybe due to: " + xhr.responseText });
+        }
+    });
+});
+
+// ** {{{ Event: bespin:groups:list:all }}} **
+// Get a list of our groups
+bespin.subscribe("bespin:groups:list:all", function() {
+    bespin.get('server').groupListAll({
+        call:function(data) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Known groups " + data });
+        },
+        onFailure:function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Failed to retrieve groups. Maybe due to: " + xhr.responseText });
+        }
+    });
+});
+
+// ** {{{ Event: bespin:groups:list }}} **
+// Get a list of group members
+bespin.subscribe("bespin:groups:list", function(group) {
+    bespin.get('server').groupList(group, {
+        call:function(data) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Members of " + group + ": " + data });
+        },
+        onFailure:function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Failed to retrieve group members. Maybe due to: " + xhr.responseText });
+        }
+    });
+});
+
+// ** {{{ Event: bespin:groups:remove:all }}} **
+// Remove a group and all its members
+bespin.subscribe("bespin:groups:remove:all", function(group) {
+    bespin.get('server').groupRemoveAll(group, {
+        call:function(data) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Removed group " + group });
+        },
+        onFailure:function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Failed to retrieve group members. Maybe due to: " + xhr.responseText });
+        }
+    });
+});
+
+// ** {{{ Event: bespin:groups:add }}} **
+// Add to members of a group
+bespin.subscribe("bespin:groups:add", function(group, users) {
+    bespin.get('server').groupAdd(group, users, {
+        call:function(data) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Members of " + group + ": " + data });
+        },
+        onFailure:function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Failed to add to group members. Maybe due to: " + xhr.responseText });
+        }
+    });
+});
+
+// ** {{{ Event: bespin:groups:remove }}} **
+// Add to members of a group
+bespin.subscribe("bespin:groups:remove", function(group, users) {
+    bespin.get('server').groupRemove(group, users, {
+        call:function(data) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Members of " + group + ": " + data });
+        },
+        onFailure:function(xhr) {
+            bespin.publish("bespin:cmdline:showinfo", { msg: "Failed to remove to group members. Maybe due to: " + xhr.responseText });
+        }
+    });
+});

Propchange: camel/trunk/components/camel-web/src/main/webapp/js/bespin/events.js
------------------------------------------------------------------------------
    svn:eol-style = native