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:27:44 UTC
svn commit: r755934 [2/2] - in /camel/trunk/components/camel-web/src/main:
java/org/apache/camel/web/resources/ webapp/WEB-INF/
webapp/WEB-INF/decorators/ webapp/js/ webapp/js/th/
webapp/org/apache/camel/web/resources/RouteResource/ webapp/org/apache/c...
Added: camel/trunk/components/camel-web/src/main/webapp/js/th/css.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/th/css.js?rev=755934&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/th/css.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/th/css.js Thu Mar 19 11:27:43 2009
@@ -0,0 +1,132 @@
+/* ***** 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 jquery-css-parser.
+ *
+ * The Initial Developer of the Original Code is Daniel Wachsstock.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bespin Team (bespin@mozilla.com)
+ *
+ * ORIGINAL MIT-licensed CODE LICENSE HEADER FOLLOWS:
+
+// jQuery based CSS parser
+// documentation: http://youngisrael-stl.org/wordpress/2009/01/16/jquery-css-parser/
+// Version: 1.0
+// Copyright (c) 2009 Daniel Wachsstock
+// MIT license:
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+ * ***** END LICENSE BLOCK ***** */
+
+
+dojo.provide("th.css");
+
+dojo.declare("th.css.CSSParser", null, {
+ parse: function(str, ret) {
+ // parses the passed stylesheet into an object with properties containing objects with the attribute names and values
+ if (!ret) ret = {};
+
+ dojo.forEach(this.munge(str, false).split('`b%'), function(css){
+ css = css.split('%b`'); // css[0] is the selector; css[1] is the index in munged for the cssText
+ if (css.length < 2) return; // invalid css
+ css[0] = this.restore(css[0]);
+ var obj = ret[css[0]] || {};
+ ret[css[0]] = dojo.mixin(obj, this.parsedeclarations(css[1]));
+ }, this);
+
+ return ret;
+ },
+
+ // replace strings and brace-surrounded blocks with %s`number`s% and %b`number`b%. By successively taking out the innermost
+ // blocks, we ensure that we're matching braces. No way to do this with just regular expressions. Obviously, this assumes no one
+ // would use %s` in the real world.
+ // Turns out this is similar to the method that Dean Edwards used for his CSS parser in IE7.js (http://code.google.com/p/ie7-js/)
+ REbraces: /{[^{}]*}/,
+
+ REfull: /\[[^\[\]]*\]|{[^{}]*}|\([^()]*\)|function(\s+\w+)?(\s*%b`\d+`b%){2}/, // match pairs of parentheses, brackets, and braces and function definitions.
+
+ REatcomment: /\/\*@((?:[^\*]|\*[^\/])*)\*\//g, // comments of the form /*@ text */ have text parsed
+ // we have to combine the comments and the strings because comments can contain string delimiters and strings can contain comment delimiters
+ // var REcomment = /\/\*(?:[^\*]|\*[^\/])*\*\/|<!--|-->/g; // other comments are stripped. (this is a simplification of real SGML comments (see http://htmlhelp.com/reference/wilbur/misc/comment.html) , but it's what real browsers use)
+ // var REstring = /\\.|"(?:[^\\\"]|\\.|\\\n)*"|'(?:[^\\\']|\\.|\\\n)*'/g; // match escaped characters and strings
+
+ REcomment_string:
+ /(?:\/\*(?:[^\*]|\*[^\/])*\*\/)|(\\.|"(?:[^\\\"]|\\.|\\\n)*"|'(?:[^\\\']|\\.|\\\n)*')/g,
+
+ REmunged: /%\w`(\d+)`\w%/,
+
+ uid: 0, // unique id number
+
+ munged: {}, // strings that were removed by the parser so they don't mess up searching for specific characters
+
+ munge: function(str, full) {
+ str = str
+ .replace(this.REatcomment, '$1') // strip /*@ comments but leave the text (to let invalid CSS through)
+ .replace(this.REcomment_string, dojo.hitch(this, function (s, string) { // strip strings and escaped characters, leaving munged markers, and strip comments
+ if (!string) return '';
+ var replacement = '%s`'+(++this.uid)+'`s%';
+ this.munged[this.uid] = string.replace(/^\\/, ''); // strip the backslash now
+ return replacement;
+ }));
+
+ // need a loop here rather than .replace since we need to replace nested braces
+ var RE = full ? this.REfull : this.REbraces;
+ while (match = RE.exec(str)) {
+ replacement = '%b`'+(++this.uid)+'`b%';
+ this.munged[this.uid] = match[0];
+ str = str.replace(RE, replacement);
+ }
+ return str;
+ },
+
+ restore: function(str) {
+ if (str === undefined) return str;
+ while (match = this.REmunged.exec(str)) {
+ str = str.replace(this.REmunged, this.munged[match[1]]);
+ }
+ return dojo.trim(str);
+ },
+
+ parsedeclarations: function(index){ // take a string from the munged array and parse it into an object of property: value pairs
+ var str = this.munged[index].replace(/(?:^\s*[{'"]\s*)|(?:\s*([^\\])[}'"]\s*$)/g, '$1'); // find the string and remove the surrounding braces or quotes
+ str = this.munge(str); // make sure any internal braces or strings are escaped
+ var parsed = {};
+ dojo.forEach(str.split(';'), function (decl) {
+ decl = decl.split(':');
+ if (decl.length < 2) return;
+ parsed[this.restore(decl[0])] = this.restore(decl[1]);
+ }, this);
+ return parsed;
+ }
+});
\ No newline at end of file
Propchange: camel/trunk/components/camel-web/src/main/webapp/js/th/css.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/components/camel-web/src/main/webapp/js/th/docs.txt
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/th/docs.txt?rev=755934&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/th/docs.txt (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/th/docs.txt Thu Mar 19 11:27:43 2009
@@ -0,0 +1,29 @@
+style (anything that could affect painting)
+- backgroundColor
+* backgroundImage
+* color
+- font
+- noClip
+- display (show, block, inline, none; not laid out and not painted)
+- visibility (visible, hidden; laid out but not painted)
+- defaultSize (used by SplitPanel, HorizontalTree)
+- border
+- backgroundColorOdd (used by List, HorizontalTree)
+- scrollTopImage (used by ScrollBar)
+- scrollMiddleImage (used by ScrollBar)
+- scrollBottomImage (used by ScrollBar)
+- scrollHandleTopImage (used by ScrollBar)
+- scrollHandleMiddleImage (used by ScrollBar)
+- scrollHandleBottomImage (used by ScrollBar)
+
+attributes (not related to painting)
+- regions (used by SplitPanel)
+ - size (% or px)
+ - contents (component)
+- orientation (TH.HORIZONTAL, TH.VERTICAL; used by SplitPanel, Splitter)
+- text (used by Label)
+
+events
+- dragstart (fired by ResizeNib, Splitter; start position)
+- dragstop (fired by ResizeNib, Splitter; startPos, currentPos)
+- drag (fired by ResizeNib, Splitter; startPos, currentPos)
\ No newline at end of file
Propchange: camel/trunk/components/camel-web/src/main/webapp/js/th/docs.txt
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: camel/trunk/components/camel-web/src/main/webapp/js/th/helpers.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/th/helpers.js?rev=755934&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/th/helpers.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/th/helpers.js Thu Mar 19 11:27:43 2009
@@ -0,0 +1,139 @@
+// ***** 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):
+//
+// ***** END LICENSE BLOCK *****
+//
+
+dojo.provide("th.helpers");
+
+dojo.mixin(th.helpers, {
+ isPercentage: function(str){ // TODO: make more robust
+ return (str.indexOf && str.indexOf("%") != -1);
+ }
+});
+
+dojo.declare("th.helpers.EventHelpers", null, {
+ // only works on a Scene at the moment as it uses
+ wrapEvent: function(e, root) {
+ // compute the canvas-local coordinates
+ var coords = dojo.coords(this.canvas, true);
+ var x = e.clientX - coords.x;
+ var y = e.clientY - coords.y;
+
+ var component = root.getComponentForPosition(x, y, true);
+ e.thComponent = component;
+
+ this.addComponentXY(e, root, component);
+ },
+
+ // changes clientX and clientY from space of source to space of dest; no change wraught if dest incompatible with source
+ addComponentXY: function(e, source, dest) {
+ if (!dest.bounds) {
+ console.log("No dest bounds - " + dest.declaredClass);
+ console.log(dest.bounds);
+ console.log(dest);
+ return;
+ }
+
+ // compute the canvas-local coordinates
+ var coords = dojo.coords(this.canvas, true);
+ var x = e.clientX - coords.x;
+ var y = e.clientY - coords.y;
+
+ var nxy = { x: x, y: y };
+
+ var c = dest;
+ while (c) {
+ nxy.x -= c.bounds.x;
+ nxy.y -= c.bounds.y;
+ c = c.parent;
+
+ if (c == source) {
+ e.componentX = nxy.x;
+ e.componentY = nxy.y;
+ return;
+ }
+ }
+ }
+});
+
+dojo.declare("th.helpers.ComponentHelpers", null, {
+ // returns hash with some handy short-cuts for painting
+ d: function() {
+ return {
+ b: (this.bounds) ? { x: this.bounds.x, y: this.bounds.y, w: this.bounds.width, h: this.bounds.height,
+ iw: this.bounds.width - this.getInsets().left - this.getInsets().right,
+ ih: this.bounds.height - this.getInsets().top - this.getInsets().bottom } : {},
+ i: { l: this.getInsets().left, r: this.getInsets().right, t: this.getInsets().top, b: this.getInsets().bottom,
+ w: this.getInsets().left + this.getInsets().right, h: this.getInsets().top + this.getInsets().bottom }
+ }
+ },
+
+ shouldPaint: function() {
+ return (this.shouldLayout() && this.style.visibility != "hidden");
+ },
+
+ shouldLayout: function() {
+ return (this.style.display != "none");
+ },
+
+ emptyInsets: function() {
+ return { left: 0, right: 0, bottom: 0, top: 0 };
+ }
+});
+
+dojo.declare("th.helpers.ContainerHelpers", null, {
+ getScene: function() {
+ var container = this;
+ while (!container.scene && container.parent) container = container.parent;
+ return container.scene;
+ },
+
+ getChildById: function(id) {
+ for (var i = 0; i < this.children.length; i++) {
+ if (this.children[i].id == id) return this.children[i];
+ }
+ },
+
+ getComponentForPosition: function(x, y, recurse) {
+ for (var i = 0; i < this.children.length; i++) {
+ if (!this.children[i].bounds) continue;
+
+ if (this.children[i].bounds.x <= x && this.children[i].bounds.y <= y
+ && (this.children[i].bounds.x + this.children[i].bounds.width) >= x
+ && (this.children[i].bounds.y + this.children[i].bounds.height) >= y) {
+ if (!recurse) return this.children[i];
+ return (this.children[i].getComponentForPosition) ?
+ this.children[i].getComponentForPosition(x - this.children[i].bounds.x, y - this.children[i].bounds.y, recurse) :
+ this.children[i];
+ }
+ }
+ return this;
+ },
+
+ removeAll: function() {
+ this.remove(this.children);
+ }
+});
\ No newline at end of file
Propchange: camel/trunk/components/camel-web/src/main/webapp/js/th/helpers.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/components/camel-web/src/main/webapp/js/th/models.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/th/models.js?rev=755934&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/th/models.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/th/models.js Thu Mar 19 11:27:43 2009
@@ -0,0 +1,50 @@
+// ***** 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):
+//
+// ***** END LICENSE BLOCK *****
+//
+
+dojo.provide("th.models");
+
+dojo.declare("th.models.LazyTreeModel", null, {
+ placeholder: "(placeholder)",
+
+ loading: "(loading)",
+
+ root: this.placeholder,
+
+ getRoot: function() {
+ return this.root;
+ },
+
+ getChildren: function(parent) {
+ },
+
+ loadChildren: function(parent) {
+ },
+
+ childrenLoaded: function(parent, children) {
+ }
+});
\ No newline at end of file
Propchange: camel/trunk/components/camel-web/src/main/webapp/js/th/models.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/components/camel-web/src/main/webapp/js/th/th.js
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/js/th/th.js?rev=755934&view=auto
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/js/th/th.js (added)
+++ camel/trunk/components/camel-web/src/main/webapp/js/th/th.js Thu Mar 19 11:27:43 2009
@@ -0,0 +1,554 @@
+/* ***** 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("th.th");
+
+/*
+ Constants
+ */
+dojo.mixin(th, {
+ VERTICAL: "v",
+ HORIZONTAL: "h"
+});
+
+/*
+ Event bus; all listeners and events pass through a single global instance of this class.
+ */
+dojo.declare("th.Bus", null, {
+ constructor: function() {
+ // map of event name to listener; listener contains a selector, function, and optional context object
+ this.events = {};
+ },
+
+ // register a listener with an event
+ bind: function(event, selector, listenerFn, listenerContext) {
+ var listeners = this.events[event];
+ if (!listeners) {
+ listeners = [];
+ this.events[event] = listeners;
+ }
+ selector = dojo.isArray(selector) ? selector : [ selector ];
+ for (var z = 0; z < selector.length; z++) {
+ for (var i = 0; i < listeners.length; i++) {
+ if (listeners[i].selector == selector[z] && listeners[i].listenerFn == listenerFn) return;
+ }
+ listeners.push({ selector: selector[z], listenerFn: listenerFn, context: listenerContext });
+ }
+ },
+
+ // removes any listeners whose selectors have the *same identity* as the passed selector
+ unbind: function(selector) {
+ for (var event in this.events) {
+ var listeners = this.events[event];
+
+ for (var i = 0; i < listeners.length; i++) {
+ if (listeners[i].selector === selector) {
+ this.events[event] = dojo.filter(listeners, function(item){ return item != listeners[i]; });
+ listeners = this.events[event];
+ i--;
+ }
+ }
+ }
+ },
+
+ // notify all listeners of an event
+ fire: function(eventName, eventDetails, component) {
+ var listeners = this.events[eventName];
+ if (!listeners || listeners.length == 0) return;
+
+ // go through each listener registered for the fired event and check if the selector matches the component for whom
+ // the event was fired; if there is a match, dispatch the event
+ for (var i = 0; i < listeners.length; i++) {
+ // if the listener selector is a string...
+ if (listeners[i].selector.constructor == String) {
+ // check if the string starts with a hash, indicating that it should match by id
+ if (listeners[i].selector.charAt(0) == "#") {
+ if (component.id == listeners[i].selector.substring(1)) {
+ this.dispatchEvent(eventName, eventDetails, component, listeners[i]);
+ }
+ // otherwise check if it's the name of the component class
+ } else if (listeners[i].selector == component.declaredClass) {
+ this.dispatchEvent(eventName, eventDetails, component, listeners[i]);
+ }
+ // otherwise check if the selector is the current component
+ } else if (listeners[i].selector == component) {
+ this.dispatchEvent(eventName, eventDetails, component, listeners[i]);
+ }
+ }
+ },
+
+ // invokes the listener function
+ dispatchEvent: function(eventName, eventDetails, component, listener) {
+ eventDetails.thComponent = component;
+
+ // check if there is listener context; if so, execute the listener function using that as the context
+ if (listener.context) {
+ listener.listenerFn.apply(listener.context, [ eventDetails ]);
+ } else {
+ listener.listenerFn(eventDetails);
+ }
+ }
+});
+
+// create the global event bus
+th.global_event_bus = new th.Bus();
+
+dojo.declare("th.Scene", th.helpers.EventHelpers, {
+ bus: th.global_event_bus,
+
+ css: {},
+
+ sheetCount: 0,
+ currentSheet: 0,
+ cssLoaded: false,
+ renderRequested: false,
+ renderAllowed: true,
+
+ constructor: function(canvas) {
+ this.canvas = canvas;
+
+ dojo.connect(window, "resize", dojo.hitch(this, function() {
+ this.render();
+ }));
+
+ this.root = new th.components.Panel({ id: "root", style: {
+// backgroundColor: "pink" // for debugging
+ } });
+ this.root.scene = this;
+
+ var testCanvas = document.createElement("canvas");
+ this.scratchContext = testCanvas.getContext("2d");
+ bespin.util.canvas.fix(this.scratchContext);
+
+ dojo.connect(window, "mousedown", dojo.hitch(this, function(e) {
+ this.wrapEvent(e, this.root);
+
+ this.mouseDownComponent = e.thComponent;
+
+ th.global_event_bus.fire("mousedown", e, e.thComponent);
+ }));
+
+ dojo.connect(window, "dblclick", dojo.hitch(this, function(e) {
+ this.wrapEvent(e, this.root);
+
+ th.global_event_bus.fire("dblclick", e, e.thComponent);
+ }));
+
+ dojo.connect(window, "click", dojo.hitch(this, function(e) {
+ this.wrapEvent(e, this.root);
+
+ th.global_event_bus.fire("click", e, e.thComponent);
+ }));
+
+ dojo.connect(window, "mousemove", dojo.hitch(this, function(e) {
+ this.wrapEvent(e, this.root);
+
+ th.global_event_bus.fire("mousemove", e, e.thComponent);
+
+ if (this.mouseDownComponent) {
+ this.addComponentXY(e, this.root, this.mouseDownComponent);
+ th.global_event_bus.fire("mousedrag", e, this.mouseDownComponent);
+ }
+ }));
+
+ dojo.connect(window, "mouseup", dojo.hitch(this, function(e) {
+ if (!this.mouseDownComponent) return;
+
+ this.addComponentXY(e, this.root, this.mouseDownComponent);
+ th.global_event_bus.fire("mouseup", e, this.mouseDownComponent);
+
+ delete this.mouseDownComponent;
+ }));
+
+ this.parseCSS();
+ },
+
+ render: function(forceRendering) {
+ if (!this.renderAllowed && !forceRendering) {
+ return;
+ }
+ if (!this.cssLoaded) {
+ this.renderRequested = true;
+ return;
+ }
+ this.layout();
+ this.paint();
+ },
+
+ layout: function() {
+ if (this.root) {
+ this.root.bounds = { x: 0, y: 0, width: this.canvas.width, height: this.canvas.height };
+ this.root.layoutTree();
+ }
+ },
+
+ paint: function(component) {
+ if (!this.cssLoaded) {
+ this.renderRequested = true;
+ return;
+ }
+
+ if (!component) component = this.root;
+
+ //if (component === this.root) console.log("root paint");
+
+ if (component) {
+ if (!component.opaque && component.parent) {
+ return this.paint(component.parent);
+ }
+
+ var ctx = this.canvas.getContext("2d");
+ bespin.util.canvas.fix(ctx);
+
+ ctx.save();
+
+ var parent = component.parent;
+ var child = component;
+ while (parent) {
+ ctx.translate(child.bounds.x, child.bounds.y);
+ child = parent;
+ parent = parent.parent;
+ }
+
+ ctx.clearRect(0, 0, component.bounds.width, component.bounds.height);
+ ctx.beginPath();
+ ctx.rect(0, 0, component.bounds.width, component.bounds.height);
+ ctx.closePath();
+ ctx.clip();
+ component.paint(ctx);
+
+ ctx.restore();
+ }
+ },
+
+ parseCSS: function() {
+ var links = [];
+ var s, l = document.getElementsByTagName('link');
+ for (var i=0; i < l.length; i++){
+ s = l[i];
+ if (s.rel.toLowerCase().indexOf('stylesheet') >= 0&&s.href) {
+ links.push(s.href);
+ }
+ }
+ if (links.length == 0) {
+ this.cssLoaded = true;
+ return;
+ }
+ this.sheetCount = links.length;
+ dojo.forEach(links, function(link) {
+ dojo.xhrGet({
+ url: link,
+ load: dojo.hitch(this, function(response) {
+ this.processCSS(response);
+ })
+ });
+ }, this);
+ },
+
+ processCSS: function(stylesheet) {
+ this.css = new th.css.CSSParser().parse(stylesheet, this.css);
+
+ if (++this.currentSheet == this.sheetCount) {
+ this.cssLoaded = true;
+ if (this.renderRequested) {
+ this.render();
+ this.renderRequested = false;
+ }
+ }
+ }
+});
+
+dojo.declare("th.Border", th.helpers.ComponentHelpers, {
+ constructor: function(parms) {
+ if (!parms) parms = {};
+ this.style = parms.style || {};
+ this.attributes = parms.attributes || {};
+ },
+
+ getInsets: function() {
+ return this.emptyInsets();
+ },
+
+ paint: function(ctx) {}
+});
+
+dojo.declare("th.Component", th.helpers.ComponentHelpers, {
+ constructor: function(parms) {
+ if (!parms) parms = {};
+ this.bounds = parms.bounds || {};
+ this.style = parms.style || {};
+ this.attributes = parms.attributes || {};
+ this.id = parms.id;
+ this.border = parms.border;
+ this.opaque = parms.opaque || true;
+
+ this.bus = th.global_event_bus;
+ },
+
+ // used to obtain a throw-away canvas context for performing measurements, etc.; may or may not be the same canvas as that used to draw the component
+ getScratchContext: function() {
+ var scene = this.getScene();
+ if (scene) return scene.scratchContext;
+ },
+
+ getPreferredHeight: function(width) {},
+
+ getPreferredWidth: function(height) {},
+
+ getInsets: function() {
+ return (this.border) ? this.border.getInsets() : this.emptyInsets();
+ },
+
+ paint: function(ctx) {
+ console.log("default component paint");
+ },
+
+ repaint: function() {
+ this.getScene().paint(this);
+ }
+});
+
+dojo.declare("th.Container", [th.Component, th.helpers.ContainerHelpers], {
+ constructor: function() {
+ this.children = [];
+ },
+
+ add: function() {
+ for (var z = 0; z < arguments.length; z++) {
+ component = dojo.isArray(arguments[z]) ? arguments[z] : [ arguments[z] ];
+ this.children = this.children.concat(component);
+ for (var i = 0; i < component.length; i++) {
+ component[i].parent = this;
+ }
+ }
+ },
+
+ remove: function() {
+ for (var z = 0; z < arguments.length; z++) {
+ component = dojo.isArray(arguments[z]) ? arguments[z] : [ arguments[z] ];
+ for (var i = 0; i < component.length; i++) {
+ var old_length = this.children.length;
+ this.children = dojo.filter(this.children, function(item){ return item != component[i]; });
+
+ // if the length of the array has changed since I tried to remove the current component, assume it was removed and clear the parent
+ if (old_length != this.children.length) delete component[i].parent;
+ }
+ }
+ },
+
+ replace: function(component, index) {
+ this.bus.unbind(this.children[index]);
+ component.parent = this;
+ this.children[index] = component;
+ },
+
+ paint: function(ctx) {
+ if (this.shouldPaint()) {
+ this.paintSelf(ctx);
+ this.paintChildren(ctx);
+ }
+ },
+
+ paintSelf: function(ctx) {},
+
+ paintChildren: function(ctx) {
+ for (var i = 0; i < this.children.length; i++ ) {
+ if (!this.children[i].shouldPaint()) continue;
+
+ if (!this.children[i].bounds) {
+ // console.log("WARNING: child " + i + " (type: " + this.children[i].declaredClass + ", id: " + this.children[i].id + ") of parent with id " + this.id + " of type " + this.declaredClass + " has no bounds and could not be painted");
+ continue;
+ }
+
+ ctx.save();
+ try {
+ ctx.translate(this.children[i].bounds.x, this.children[i].bounds.y);
+ } catch (error) {
+ // console.log("WARNING: child " + i + " (type: " + this.children[i].declaredClass + ", id: " + this.children[i].id + ") of parent with id " + this.id + " of type " + this.declaredClass + " has malformed bounds and could not be painted");
+ // console.log(this.children[i].bounds);
+ ctx.restore();
+ continue;
+ }
+
+ try {
+ if (!this.children[i].style["noClip"]) {
+ ctx.beginPath();
+ ctx.rect(0, 0, this.children[i].bounds.width, this.children[i].bounds.height);
+ ctx.closePath();
+ ctx.clip();
+ }
+ } catch(ex) {
+ // console.log("Bounds problem");
+ // console.log(this.children[i].declaredClass);
+ // console.log(this.children[i].bounds);
+ }
+
+ ctx.save();
+ this.children[i].paint(ctx);
+ ctx.restore();
+
+ if (this.children[i].style.border) {
+ this.children[i].style.border.component = this.children[i];
+ ctx.save();
+ this.children[i].style.border.paint(ctx);
+ ctx.restore();
+ }
+
+ ctx.restore();
+ }
+ },
+
+ // lays out this container and any sub-containers
+ layoutTree: function() {
+ this.layout();
+ for (var i = 0; i < this.children.length; i++) {
+ if (this.children[i].layoutTree) this.children[i].layoutTree();
+ }
+ },
+
+ layout: function() {
+ var d = this.d();
+ if (this.children.length > 0) {
+ var totalWidth = this.bounds.width - d.i.w;
+ var individualWidth = totalWidth / this.children.length;
+ for (var i = 0; i < this.children.length; i++) {
+ this.children[i].bounds = { x: (i * individualWidth) + d.i.l, y: d.i.t, width: individualWidth, height: this.bounds.height - d.i.h };
+ }
+ }
+ },
+
+ render: function() {
+ this.layoutTree();
+ this.repaint();
+ }
+});
+
+dojo.declare("th.Window", null, {
+ constructor: function(parms) {
+ parms = parms || {};
+
+ this.containerId = parms.containerId || false;
+ this.width = parms.width || 200;
+ this.height = parms.height || 300;
+ this.title = parms.title || 'NO TITLE GIVEN!';
+ this.y = parms.top || 50;
+ this.x = parms.left || 50;
+ this.isVisible = false;
+ this.closeOnClickOutside = !!parms.closeOnClickOutside;
+
+ // some things must be given
+ if(!parms.containerId) {
+ console.error('The "containerId" must be given!');
+ return;
+ }
+
+ if (dojo.byId(this.containerId)) {
+ console.error('There is already a element with the id "'+this.containerId+'"!');
+ return;
+ }
+
+ if (!parms.userPanel) {
+ console.error('The "userPanel" must be given!');
+ return;
+ }
+
+ // insert the HTML to the document for the new window and create the scene
+ dojo.byId('popup_insert_point').innerHTML += '<div id="'+this.containerId+'" class="popupWindow"></div>';
+ this.container = dojo.byId(this.containerId);
+ dojo.attr(this.container, { width: this.width, height: this.height, tabindex: '-1' });
+ this.container['moz-opaque'] = 'true';
+
+ this.container.innerHTML = "<canvas id='"+this.containerId+"_canvas'></canvas>";
+ this.canvas = dojo.byId(this.containerId + '_canvas');
+ dojo.attr(this.canvas, { width: this.width, height: this.height, tabindex: '-1' });
+
+ this.scene = new th.Scene(this.canvas);
+ this.windowPanel = new th.components.WindowPanel(parms.title, parms.userPanel);
+ this.windowPanel.windowBar.parentWindow = this;
+ this.scene.root.add(this.windowPanel);
+
+ this.move(this.x, this.y);
+
+ // add some listeners for closing the window
+
+ // close the window, if the user clicks outside the window
+ dojo.connect(window, "mousedown", dojo.hitch(this, function(e) {
+ if (!this.isVisible || !this.closeOnClickOutside) return;
+
+ var d = dojo.coords(this.container);
+ if (e.clientX < d.l ||Â e.clientX > (d.l + d.w) || e.clientY < d.t || e.clientY > (d.t + d.h)) {
+ this.toggle();
+ } else {
+ dojo.stopEvent(e);
+ }
+ }));
+
+ // close the window, if the user pressed ESCAPE
+ dojo.connect(window, "keydown", dojo.hitch(this, function(e) {
+ if (!this.isVisible) return;
+
+ if(e.keyCode == bespin.util.keys.Key.ESCAPE) {
+ this.toggle();
+ dojo.stopEvent(e);
+ }
+ }));
+ },
+
+ toggle: function() {
+ this.isVisible = !this.isVisible;
+
+ this.scene.bus.fire("toggle", {}, this);
+
+ if (this.isVisible) {
+ this.container.style.display = 'block';
+ this.layoutAndRender();
+ } else {
+ this.container.style.display = 'none';
+ }
+ },
+
+ layoutAndRender: function() {
+ this.scene.layout();
+ this.scene.render();
+ },
+
+ centerUp: function() {
+ this.move(Math.round((window.innerWidth - this.width) * 0.5), Math.round((window.innerHeight - this.height) * 0.25));
+ },
+
+ center: function() {
+ this.move(Math.round((window.innerWidth - this.width) * 0.5), Math.round((window.innerHeight - this.height) * 0.5));
+ },
+
+ move: function(x, y) {
+ this.y = y;
+ this.x = x;
+ this.container.style.top = y + 'px';
+ this.container.style.left = x + 'px';
+ },
+
+ getPosition: function() {
+ return { x: this.x, y: this.y };
+ }
+});
Propchange: camel/trunk/components/camel-web/src/main/webapp/js/th/th.js
------------------------------------------------------------------------------
svn:eol-style = native
Modified: camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp?rev=755934&r1=755933&r2=755934&view=diff
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp (original)
+++ camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp Thu Mar 19 11:27:43 2009
@@ -1,18 +1,36 @@
<html>
<head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>Edit Route ${it.route.id}</title>
+ <script type='text/javascript' src="<c:url value='/js/dojo/dojo.js'/>"></script>
+ <script type='text/javascript' src="<c:url value='/js/bespin/editor/embed.js'/>"></script>
+ <script type='text/javascript' src="<c:url value='/js/route.js'/>"></script>
+
+ <title>Edit ${it.route.id}</title>
</head>
<body>
-<h2>Edit Route ${it.route.id}</h2>
-
-<div class="route">
+<form id="routeForm" action="<c:url value="/routes/${it.route.id}"/>" method="post">
+<table>
+ <tr>
+ <td>
+ <h2>Edit ${it.route.id}</h2>
+ </td>
+ <td>
+ <input type="button" value="Save" onclick="submitRoute()">
+ </td>
+ <td>
+ <textarea id="route" name="route" rows="1" cols="1" style="visibility: hidden;"></textarea>
+ </td>
+ </tr>
+</table>
-<textarea rows="30" cols="80" name="body"><c:out value="${it.routeXml}" escapeXml="true" />
-</textarea>
+<div class="error">${it.error}</div>
+<div id="editor"
+ style="height: 300px; border: 10px solid #ddd; -moz-border-radius: 10px; -webkit-border-radius: 10px;">${it.routeXml}
</div>
+</form>
+
+
</body>
</html>
Copied: camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RoutesResource/create.jsp (from r755542, camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RoutesResource/create.jsp?p2=camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RoutesResource/create.jsp&p1=camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp&r1=755542&r2=755934&rev=755934&view=diff
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp (original)
+++ camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RoutesResource/create.jsp Thu Mar 19 11:27:43 2009
@@ -1,18 +1,40 @@
<html>
<head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>Edit Route ${it.route.id}</title>
+ <script type='text/javascript' src="<c:url value='/js/dojo/dojo.js'/>"></script>
+ <script type='text/javascript' src="<c:url value='/js/bespin/editor/embed.js'/>"></script>
+ <script type='text/javascript' src="<c:url value='/js/route.js'/>"></script>
+
+ <title>Create New Route</title>
</head>
<body>
-<h2>Edit Route ${it.route.id}</h2>
-
-<div class="route">
+<form id="routeForm" action="<c:url value="/routes"/>" method="post">
+<table>
+ <tr>
+ <td>
+ <h2>Create New Route</h2>
+ </td>
+ <td>
+ <input type="button" value="Save" onclick="submitRoute()">
+ </td>
+ <td>
+ <textarea id="route" name="route" rows="1" cols="1" style="visibility: hidden;"></textarea>
+ </td>
+ </tr>
+</table>
-<textarea rows="30" cols="80" name="body"><c:out value="${it.routeXml}" escapeXml="true" />
-</textarea>
+<div class="error">${it.error}</div>
+<div id="editor"
+ style="height: 300px; border: 10px solid #ddd; -moz-border-radius: 10px; -webkit-border-radius: 10px;">
+<route xmlns="http://camel.apache.org/schema/spring">
+ <from uri="seda:Some.Endpoint"/>
+ <to uri="seda:Some.Other.Endpoint"/>
+</route>
</div>
+</form>
+
+
</body>
</html>
Modified: camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RoutesResource/index.jsp
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RoutesResource/index.jsp?rev=755934&r1=755933&r2=755934&view=diff
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RoutesResource/index.jsp (original)
+++ camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RoutesResource/index.jsp Thu Mar 19 11:27:43 2009
@@ -16,7 +16,7 @@
<c:forEach var="i" items="${it.routes}">
<tr>
<td>
- <a href='<c:url value="/routes/${i.id}"/>'>${i.shortName}</a> ${i.description.text}
+ <a href='<c:url value="/routes/${i.id}/edit"/>'>${i.shortName}</a> ${i.description.text}
</td>
<td class="${i.status}">
${i.status}