You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ed...@apache.org on 2006/11/11 17:44:48 UTC
svn commit: r473755 [32/43] - in /jackrabbit/trunk/contrib/jcr-browser: ./
src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/jackrabbit/
src/main/java/org/apache/jackrabbit/browser/ src/main/resources/ ...
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Parse.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Parse.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Parse.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Parse.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,336 @@
+dojo.provide("dojo.widget.Parse");
+dojo.require("dojo.widget.Manager");
+dojo.require("dojo.dom");
+
+//
+// dojoML parser should be moved out of 'widget', codifying the difference between a 'component'
+// and a 'widget'. A 'component' being anything that can be generated from a tag.
+//
+// a particular dojoML tag would be handled by a registered tagHandler with a hook for a default handler
+// if the widget system is loaded, a widget builder would be attach itself as the default handler
+//
+// widget tags are no longer registered themselves:
+// they are now arbitrarily namespaced, so we cannot register them all, and the non-prefixed portions
+// are no longer guaranteed unique
+//
+// therefore dojo.widget.tags should go with this parser code out of the widget module
+//
+
+dojo.widget.Parse = function(fragment){
+ this.propertySetsList = [];
+ this.fragment = fragment;
+
+ this.createComponents = function(frag, parentComp){
+ var comps = [];
+ var built = false;
+ // if we have items to parse/create at this level, do it!
+ try{
+ if((frag)&&(frag["tagName"])&&(frag!=frag["nodeRef"])){
+
+ // these are in fact, not ever for widgets per-se anymore,
+ // but for other markup elements (aka components)
+ var djTags = dojo.widget.tags;
+
+ // we split so that you can declare multiple
+ // non-destructive components from the same ctor node
+ var tna = String(frag["tagName"]).split(";");
+ for(var x=0; x<tna.length; x++){
+ var ltn = (tna[x].replace(/^\s+|\s+$/g, "")).toLowerCase();
+ // FIXME: unsure what this does
+ frag.tagName = ltn;
+ if(djTags[ltn]){
+ built = true;
+ var ret = djTags[ltn](frag, this, parentComp, frag["index"]);
+ comps.push(ret);
+ } else {
+ // we require a namespace prefix, default to dojo:
+ if (ltn.indexOf(":") == -1){
+ ltn = "dojo:"+ltn;
+ }
+ // FIXME: handling failure condition correctly?
+ //var ret = djTags[ltn](frag, this, parentComp, frag["index"]);
+ var ret = dojo.widget.buildWidgetFromParseTree(ltn, frag, this, parentComp, frag["index"]);
+ if (ret) {
+ built = true;
+ comps.push(ret);
+ }
+ }
+ }
+ }
+ }catch(e){
+ dojo.debug("dojo.widget.Parse: error:" + e);
+ // note, commenting out the next line is breaking several widgets for me
+ // throw e;
+ // IE is such a bitch sometimes
+ }
+ // if there's a sub-frag, build widgets from that too
+ if(!built){
+ comps = comps.concat(this.createSubComponents(frag, parentComp));
+ }
+ return comps;
+ }
+
+ /* createSubComponents recurses over a raw JavaScript object structure,
+ and calls the corresponding handler for its normalized tagName if it exists
+ */
+ this.createSubComponents = function(fragment, parentComp){
+ var frag, comps = [];
+ for(var item in fragment){
+ frag = fragment[item];
+ if ((frag)&&(typeof frag == "object")&&(frag!=fragment.nodeRef)&&(frag!=fragment["tagName"])){
+ comps = comps.concat(this.createComponents(frag, parentComp));
+ }
+ }
+ return comps;
+ }
+
+ /* parsePropertySets checks the top level of a raw JavaScript object
+ structure for any propertySets. It stores an array of references to
+ propertySets that it finds.
+ */
+ this.parsePropertySets = function(fragment){
+ return [];
+ /*
+ var propertySets = [];
+ for(var item in fragment){
+ if((fragment[item]["tagName"] == "dojo:propertyset")){
+ propertySets.push(fragment[item]);
+ }
+ }
+ // FIXME: should we store these propertySets somewhere for later retrieval
+ this.propertySetsList.push(propertySets);
+ return propertySets;
+ */
+ }
+
+ /* parseProperties checks a raw JavaScript object structure for
+ properties, and returns an array of properties that it finds.
+ */
+ this.parseProperties = function(fragment){
+ var properties = {};
+ for(var item in fragment){
+ // FIXME: need to check for undefined?
+ // case: its a tagName or nodeRef
+ if((fragment[item] == fragment["tagName"])||(fragment[item] == fragment.nodeRef)){
+ // do nothing
+ }else{
+ if((fragment[item]["tagName"])&&
+ (dojo.widget.tags[fragment[item].tagName.toLowerCase()])){
+ // TODO: it isn't a property or property set, it's a fragment,
+ // so do something else
+ // FIXME: needs to be a better/stricter check
+ // TODO: handle xlink:href for external property sets
+ }else if((fragment[item][0])&&(fragment[item][0].value!="")&&(fragment[item][0].value!=null)){
+ try{
+ // FIXME: need to allow more than one provider
+ if(item.toLowerCase() == "dataprovider") {
+ var _this = this;
+ this.getDataProvider(_this, fragment[item][0].value);
+ properties.dataProvider = this.dataProvider;
+ }
+ properties[item] = fragment[item][0].value;
+ var nestedProperties = this.parseProperties(fragment[item]);
+ // FIXME: this kind of copying is expensive and inefficient!
+ for(var property in nestedProperties){
+ properties[property] = nestedProperties[property];
+ }
+ }catch(e){ dojo.debug(e); }
+ }
+ switch(item.toLowerCase()){
+ case "checked":
+ case "disabled":
+ if (typeof properties[item] != "boolean"){
+ properties[item] = true;
+ }
+ break;
+ }
+ }
+ }
+ return properties;
+ }
+
+ /* getPropertySetById returns the propertySet that matches the provided id
+ */
+
+ this.getDataProvider = function(objRef, dataUrl){
+ // FIXME: this is currently sync. To make this async, we made need to move
+ //this step into the widget ctor, so that it is loaded when it is needed
+ // to populate the widget
+ dojo.io.bind({
+ url: dataUrl,
+ load: function(type, evaldObj){
+ if(type=="load"){
+ objRef.dataProvider = evaldObj;
+ }
+ },
+ mimetype: "text/javascript",
+ sync: true
+ });
+ }
+
+
+ this.getPropertySetById = function(propertySetId){
+ for(var x = 0; x < this.propertySetsList.length; x++){
+ if(propertySetId == this.propertySetsList[x]["id"][0].value){
+ return this.propertySetsList[x];
+ }
+ }
+ return "";
+ }
+
+ /* getPropertySetsByType returns the propertySet(s) that match(es) the
+ * provided componentClass
+ */
+ this.getPropertySetsByType = function(componentType){
+ var propertySets = [];
+ for(var x=0; x < this.propertySetsList.length; x++){
+ var cpl = this.propertySetsList[x];
+ var cpcc = cpl["componentClass"]||cpl["componentType"]||null;
+ var propertySetId = this.propertySetsList[x]["id"][0].value;
+ if((cpcc)&&(propertySetId == cpcc[0].value)){
+ propertySets.push(cpl);
+ }
+ }
+ return propertySets;
+ }
+
+ /* getPropertySets returns the propertySet for a given component fragment
+ */
+ this.getPropertySets = function(fragment){
+ var ppl = "dojo:propertyproviderlist";
+ var propertySets = [];
+ var tagname = fragment["tagName"];
+ if(fragment[ppl]){
+ var propertyProviderIds = fragment[ppl].value.split(" ");
+ // FIXME: should the propertyProviderList attribute contain #
+ // syntax for reference to ids or not?
+ // FIXME: need a better test to see if this is local or external
+ // FIXME: doesn't handle nested propertySets, or propertySets that
+ // just contain information about css documents, etc.
+ for(var propertySetId in propertyProviderIds){
+ if((propertySetId.indexOf("..")==-1)&&(propertySetId.indexOf("://")==-1)){
+ // get a reference to a propertySet within the current parsed structure
+ var propertySet = this.getPropertySetById(propertySetId);
+ if(propertySet != ""){
+ propertySets.push(propertySet);
+ }
+ }else{
+ // FIXME: add code to parse and return a propertySet from
+ // another document
+ // alex: is this even necessaray? Do we care? If so, why?
+ }
+ }
+ }
+ // we put the typed ones first so that the parsed ones override when
+ // iteration happens.
+ return (this.getPropertySetsByType(tagname)).concat(propertySets);
+ }
+
+ /*
+ nodeRef is the node to be replaced... in the future, we might want to add
+ an alternative way to specify an insertion point
+
+ componentName is the expected dojo widget name, i.e. Button of ContextMenu
+
+ properties is an object of name value pairs
+ ns is the namespace of the widget. Defaults to "dojo"
+ */
+ this.createComponentFromScript = function(nodeRef, componentName, properties, ns){
+ properties.fastMixIn = true;
+ // FIXME: we pulled it apart and now we put it back together ...
+ var ltn = (ns || "dojo") + ":" + componentName.toLowerCase();
+ if(dojo.widget.tags[ltn]){
+ return [dojo.widget.tags[ltn](properties, this, null, null, properties)];
+ }
+ return [dojo.widget.buildWidgetFromParseTree(ltn, properties, this, null, null, properties)];
+ }
+}
+
+dojo.widget._parser_collection = {"dojo": new dojo.widget.Parse() };
+dojo.widget.getParser = function(name){
+ if(!name){ name = "dojo"; }
+ if(!this._parser_collection[name]){
+ this._parser_collection[name] = new dojo.widget.Parse();
+ }
+ return this._parser_collection[name];
+}
+
+/**
+ * Creates widget.
+ *
+ * @param name The name of the widget to create with optional namespace prefix,
+ * e.g."ns:widget", namespace defaults to "dojo".
+ * @param props Key-Value pairs of properties of the widget
+ * @param refNode If the position argument is specified, this node is used as
+ * a reference for inserting this node into a DOM tree; else
+ * the widget becomes the domNode
+ * @param position The position to insert this widget's node relative to the
+ * refNode argument
+ * @return The new Widget object
+ */
+
+dojo.widget.createWidget = function(name, props, refNode, position){
+ var isNode = false;
+ var isNameStr = (typeof name == "string");
+ if(isNameStr){
+ var pos = name.indexOf(":");
+ var ns = (pos > -1) ? name.substring(0,pos) : "dojo";
+ if(pos > -1){ name = name.substring(pos+1); }
+ var lowerCaseName = name.toLowerCase();
+ var namespacedName = ns + ":" + lowerCaseName;
+ isNode = (dojo.byId(name) && (!dojo.widget.tags[namespacedName]));
+ }
+
+ if((arguments.length == 1) && ((isNode)||(!isNameStr))){
+ // we got a DOM node
+ var xp = new dojo.xml.Parse();
+ // FIXME: we should try to find the parent!
+ var tn = (isNode) ? dojo.byId(name) : name;
+ return dojo.widget.getParser().createComponents(xp.parseElement(tn, null, true))[0];
+ }
+
+ function fromScript(placeKeeperNode, name, props, ns){
+ props[namespacedName] = {
+ dojotype: [{value: lowerCaseName}],
+ nodeRef: placeKeeperNode,
+ fastMixIn: true
+ };
+ props.ns = ns;
+ return dojo.widget.getParser().createComponentFromScript(placeKeeperNode, name, props, ns);
+ }
+
+ props = props||{};
+ var notRef = false;
+ var tn = null;
+ var h = dojo.render.html.capable;
+ if(h){
+ tn = document.createElement("span");
+ }
+ if(!refNode){
+ notRef = true;
+ refNode = tn;
+ if(h){
+ dojo.body().appendChild(refNode);
+ }
+ }else if(position){
+ dojo.dom.insertAtPosition(tn, refNode, position);
+ }else{ // otherwise don't replace, but build in-place
+ tn = refNode;
+ }
+ var widgetArray = fromScript(tn, name.toLowerCase(), props, ns);
+ if( (!widgetArray)||(!widgetArray[0])||
+ (typeof widgetArray[0].widgetType == "undefined") ){
+ throw new Error("createWidget: Creation of \"" + name + "\" widget failed.");
+ }
+ try{
+ if(notRef){
+ if(widgetArray[0].domNode.parentNode){
+ widgetArray[0].domNode.parentNode.removeChild(widgetArray[0].domNode);
+ }
+ }
+ }catch(e){
+ /* squelch for Safari */
+ dojo.debug(e);
+ }
+ return widgetArray[0]; // just return the widget
+}
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Parse.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/PopupContainer.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/PopupContainer.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/PopupContainer.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/PopupContainer.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,442 @@
+dojo.provide("dojo.widget.PopupContainer");
+
+dojo.require("dojo.html.style");
+dojo.require("dojo.html.layout");
+dojo.require("dojo.html.selection");
+dojo.require("dojo.html.iframe");
+dojo.require("dojo.event.*");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+
+// summary:
+// PopupContainerBase is the mixin class which provide popup behaviors:
+// it can open in a given position x,y or around a given node.
+// In addition, it handles animation and IE bleed through workaround.
+// description:
+// This class can not be used standalone: it should be mixed-in to a
+// dojo.widget.HtmlWidget. Use PopupContainer instead if you want a
+// a standalone popup widget
+dojo.declare(
+ "dojo.widget.PopupContainerBase",
+ null,
+ function(){
+ this.queueOnAnimationFinish = [];
+ },
+{
+ isContainer: true,
+ templateString: '<div dojoAttachPoint="containerNode" style="display:none;position:absolute;" class="dojoPopupContainer" ></div>',
+
+ // Boolean: whether this popup is shown
+ isShowingNow: false,
+
+ // Widget: the shown sub popup if any
+ currentSubpopup: null,
+
+ // Int: the minimal popup zIndex
+ beginZIndex: 1000,
+
+ // Widget: parent popup widget
+ parentPopup: null,
+ // Widget: parent Widget
+ parent: null,
+ // Int: level of sub popup
+ popupIndex: 0,
+
+ // dojo.html.boxSizing: which bounding box to use for open aroundNode. By default use BORDER box of the aroundNode
+ aroundBox: dojo.html.boxSizing.BORDER_BOX,
+
+ // Object: in which window, the open() is triggered
+ openedForWindow: null,
+
+ processKey: function(/*Event*/evt){
+ // summary: key event handler
+ return false;
+ },
+
+ applyPopupBasicStyle: function(){
+ // summary: apply necessary css rules to the top domNode
+ // description:
+ // this function should be called in sub class where a custom
+ // templateString/templateStringPath is used (see Tooltip widget)
+ with(this.domNode.style){
+ display = 'none';
+ position = 'absolute';
+ }
+ },
+
+ aboutToShow: function() {
+ // summary: connect to this stub to modify the content of the popup
+ },
+
+ open: function(/*Integer*/x, /*Integer*/y, /*DomNode*/parent, /*Object*/explodeSrc, /*String?*/orient, /*Array?*/padding){
+ // summary:
+ // Open the popup at position (x,y), relative to dojo.body()
+ // Or open(node, parent, explodeSrc, aroundOrient) to open
+ // around node
+ if (this.isShowingNow){ return; }
+
+ this.aboutToShow();
+
+ // if I click right button and menu is opened, then it gets 2 commands: close -> open
+ // so close enables animation and next "open" is put to queue to occur at new location
+ if(this.animationInProgress){
+ this.queueOnAnimationFinish.push(this.open, arguments);
+ return;
+ }
+
+ // save this so that the focus can be returned
+ this.parent = parent;
+
+ var around = false, node, aroundOrient;
+ if(typeof x == 'object'){
+ node = x;
+ aroundOrient = explodeSrc;
+ explodeSrc = parent;
+ parent = y;
+ around = true;
+ }
+
+ // for unknown reasons even if the domNode is attached to the body in postCreate(),
+ // it's not attached here, so have to attach it here.
+ dojo.body().appendChild(this.domNode);
+
+ // if explodeSrc isn't specified then explode from my parent widget
+ explodeSrc = explodeSrc || parent["domNode"] || [];
+
+ //keep track of parent popup to decided whether this is a top level popup
+ var parentPopup = null;
+ this.isTopLevel = true;
+ while(parent){
+ if(parent !== this && (parent.setOpenedSubpopup != undefined && parent.applyPopupBasicStyle != undefined)){
+ parentPopup = parent;
+ this.isTopLevel = false;
+ parentPopup.setOpenedSubpopup(this);
+ break;
+ }
+ parent = parent.parent;
+ }
+
+ this.parentPopup = parentPopup;
+ this.popupIndex = parentPopup ? parentPopup.popupIndex + 1 : 1;
+
+ if(this.isTopLevel){
+ var button = dojo.html.isNode(explodeSrc) ? explodeSrc : null;
+ dojo.widget.PopupManager.opened(this, button);
+ }
+
+ //Store the current selection and restore it before the action for a menu item
+ //is executed. This is required as clicking on an menu item deselects current selection
+ if(this.isTopLevel && !dojo.withGlobal(this.openedForWindow||dojo.global(), dojo.html.selection.isCollapsed)){
+ this._bookmark = dojo.withGlobal(this.openedForWindow||dojo.global(), dojo.html.selection.getBookmark);
+ }else{
+ this._bookmark = null;
+ }
+
+ //convert explodeSrc from format [x, y] to
+ //{left: x, top: y, width: 0, height: 0} which is the new
+ //format required by dojo.html.toCoordinateObject
+ if(explodeSrc instanceof Array){
+ explodeSrc = {left: explodeSrc[0], top: explodeSrc[1], width: 0, height: 0};
+ }
+
+ // display temporarily, and move into position, then hide again
+ with(this.domNode.style){
+ display="";
+ zIndex = this.beginZIndex + this.popupIndex;
+ }
+
+ if(around){
+ this.move(node, padding, aroundOrient);
+ }else{
+ this.move(x, y, padding, orient);
+ }
+ this.domNode.style.display="none";
+
+ this.explodeSrc = explodeSrc;
+
+ // then use the user defined method to display it
+ this.show();
+
+ this.isShowingNow = true;
+ },
+
+ // TODOC: move(node, padding, aroundOrient) how to do this?
+ move: function(/*Int*/x, /*Int*/y, /*Integer?*/padding, /*String?*/orient){
+ // summary: calculate where to place the popup
+
+ var around = (typeof x == "object");
+ if(around){
+ var aroundOrient=padding;
+ var node=x;
+ padding=y;
+ if(!aroundOrient){ //By default, attempt to open above the aroundNode, or below
+ aroundOrient = {'BL': 'TL', 'TL': 'BL'};
+ }
+ dojo.html.placeOnScreenAroundElement(this.domNode, node, padding, this.aroundBox, aroundOrient);
+ }else{
+ if(!orient){ orient = 'TL,TR,BL,BR';}
+ dojo.html.placeOnScreen(this.domNode, x, y, padding, true, orient);
+ }
+ },
+
+ close: function(/*Boolean?*/force){
+ // summary: hide the popup
+ if(force){
+ this.domNode.style.display="none";
+ }
+
+ // If we are in the process of opening the menu and we are asked to close it
+ if(this.animationInProgress){
+ this.queueOnAnimationFinish.push(this.close, []);
+ return;
+ }
+
+ this.closeSubpopup(force);
+ this.hide();
+ if(this.bgIframe){
+ this.bgIframe.hide();
+ this.bgIframe.size({left: 0, top: 0, width: 0, height: 0});
+ }
+ if(this.isTopLevel){
+ dojo.widget.PopupManager.closed(this);
+ }
+ this.isShowingNow = false;
+ // return focus to the widget that opened the menu
+ try {
+ this.parent.domNode.focus();
+ } catch(e) {}
+
+ //do not need to restore if current selection is not empty
+ //(use keyboard to select a menu item)
+ if(this._bookmark && dojo.withGlobal(this.openedForWindow||dojo.global(), dojo.html.selection.isCollapsed)){
+ if(this.openedForWindow){
+ this.openedForWindow.focus()
+ }
+ dojo.withGlobal(this.openedForWindow||dojo.global(), "moveToBookmark", dojo.html.selection, [this._bookmark]);
+ }
+ this._bookmark = null;
+ },
+
+ closeAll: function(/*Boolean?*/force){
+ // summary: hide all popups including sub ones
+ if (this.parentPopup){
+ this.parentPopup.closeAll(force);
+ }else{
+ this.close(force);
+ }
+ },
+
+ setOpenedSubpopup: function(/*Widget*/popup) {
+ // summary: used by sub popup to set currentSubpopup in the parent popup
+ this.currentSubpopup = popup;
+ },
+
+ closeSubpopup: function(/*Boolean?*/force) {
+ // summary: close opened sub popup
+ if(this.currentSubpopup == null){ return; }
+
+ this.currentSubpopup.close(force);
+ this.currentSubpopup = null;
+ },
+
+ onShow: function() {
+ dojo.widget.PopupContainer.superclass.onShow.apply(this, arguments);
+ // With some animation (wipe), after close, the size of the domnode is 0
+ // and next time when shown, the open() function can not determine
+ // the correct place to popup, so we store the opened size here and
+ // set it after close (in function onHide())
+ this.openedSize={w: this.domNode.style.width, h: this.domNode.style.height};
+ // prevent IE bleed through
+ if(dojo.render.html.ie){
+ if(!this.bgIframe){
+ this.bgIframe = new dojo.html.BackgroundIframe();
+ this.bgIframe.setZIndex(this.domNode);
+ }
+
+ this.bgIframe.size(this.domNode);
+ this.bgIframe.show();
+ }
+ this.processQueue();
+ },
+
+ processQueue: function() {
+ // summary: do events from queue
+ if (!this.queueOnAnimationFinish.length) return;
+
+ var func = this.queueOnAnimationFinish.shift();
+ var args = this.queueOnAnimationFinish.shift();
+
+ func.apply(this, args);
+ },
+
+ onHide: function() {
+ dojo.widget.HtmlWidget.prototype.onHide.call(this);
+
+ //restore size of the domnode, see comment in
+ //function onShow()
+ if(this.openedSize){
+ with(this.domNode.style){
+ width=this.openedSize.w;
+ height=this.openedSize.h;
+ }
+ }
+
+ this.processQueue();
+ }
+});
+
+// summary: dojo.widget.PopupContainer is the widget version of dojo.widget.PopupContainerBase
+dojo.widget.defineWidget(
+ "dojo.widget.PopupContainer",
+ [dojo.widget.HtmlWidget, dojo.widget.PopupContainerBase], {});
+
+
+// summary:
+// the popup manager makes sure we don't have several popups
+// open at once. the root popup in an opening sequence calls
+// opened(). when a root menu closes it calls closed(). then
+// everything works. lovely.
+dojo.widget.PopupManager = new function(){
+ this.currentMenu = null;
+ this.currentButton = null; // button that opened current menu (if any)
+ this.currentFocusMenu = null; // the (sub)menu which receives key events
+ this.focusNode = null;
+ this.registeredWindows = [];
+
+ this.registerWin = function(/*Window*/win){
+ // summary: register a window so that when clicks/scroll in it, the popup can be closed automatically
+ if(!win.__PopupManagerRegistered)
+ {
+ dojo.event.connect(win.document, 'onmousedown', this, 'onClick');
+ dojo.event.connect(win, "onscroll", this, "onClick");
+ dojo.event.connect(win.document, "onkey", this, 'onKey');
+ win.__PopupManagerRegistered = true;
+ this.registeredWindows.push(win);
+ }
+ };
+
+ /*
+
+ */
+ this.registerAllWindows = function(/*Window*/targetWindow){
+ // summary:
+ // This function register all the iframes and the top window,
+ // so that whereever the user clicks in the page, the popup
+ // menu will be closed
+ // In case you add an iframe after onload event, please call
+ // dojo.widget.PopupManager.registerWin manually
+
+ //starting from window.top, clicking everywhere in this page
+ //should close popup menus
+ if(!targetWindow) { //see comment below
+ targetWindow = dojo.html.getDocumentWindow(window.top && window.top.document || window.document);
+ }
+
+ this.registerWin(targetWindow);
+
+ for (var i = 0; i < targetWindow.frames.length; i++){
+ try{
+ //do not remove dojo.html.getDocumentWindow, see comment in it
+ var win = dojo.html.getDocumentWindow(targetWindow.frames[i].document);
+ if(win){
+ this.registerAllWindows(win);
+ }
+ }catch(e){ /* squelch error for cross domain iframes */ }
+ }
+ };
+
+ this.unRegisterWin = function(/*Window*/win){
+ // summary: remove listeners on the registered window
+ if(win.__PopupManagerRegistered)
+ {
+ dojo.event.disconnect(win.document, 'onmousedown', this, 'onClick');
+ dojo.event.disconnect(win, "onscroll", this, "onClick");
+ dojo.event.disconnect(win.document, "onkey", this, 'onKey');
+ win.__PopupManagerRegistered = false;
+ }
+ };
+
+ this.unRegisterAllWindows = function(){
+ // summary: remove listeners on all the registered windows
+ for(var i=0;i<this.registeredWindows.length;++i){
+ this.unRegisterWin(this.registeredWindows[i]);
+ }
+ this.registeredWindows = [];
+ };
+
+ dojo.addOnLoad(this, "registerAllWindows");
+ dojo.addOnUnload(this, "unRegisterAllWindows");
+
+ this.closed = function(/*Widget*/menu){
+ // summary: notify the manager that menu is closed
+ if (this.currentMenu == menu){
+ this.currentMenu = null;
+ this.currentButton = null;
+ this.currentFocusMenu = null;
+ }
+ };
+
+ this.opened = function(/*Widget*/menu, /*DomNode*/button){
+ // summary: sets the current opened popup
+ if (menu == this.currentMenu){ return; }
+
+ if (this.currentMenu){
+ this.currentMenu.close();
+ }
+
+ this.currentMenu = menu;
+ this.currentFocusMenu = menu;
+ this.currentButton = button;
+ };
+
+ this.setFocusedMenu = function(/*Widget*/menu){
+ // summary:
+ // Set the current focused popup, This is used by popups which supports keyboard navigation
+ this.currentFocusMenu = menu;
+ };
+
+ this.onKey = function(/*Event*/e){
+ if (!e.key) { return; }
+ if(!this.currentMenu || !this.currentMenu.isShowingNow){ return; }
+
+ var m = this.currentFocusMenu;
+ while (m){
+ if(m.processKey(e)){
+ e.preventDefault();
+ e.stopPropagation();
+ break;
+ }
+ m = m.parentPopup;
+ }
+ },
+
+ this.onClick = function(/*Event*/e){
+ if (!this.currentMenu){ return; }
+
+ var scrolloffset = dojo.html.getScroll().offset;
+
+ // starting from the base menu, perform a hit test
+ // and exit when one succeeds
+
+ var m = this.currentMenu;
+
+ while (m){
+ if(dojo.html.overElement(m.domNode, e) || dojo.html.isDescendantOf(e.target, m.domNode)){
+ return;
+ }
+ m = m.currentSubpopup;
+ }
+
+ // Also, if user clicked the button that opened this menu, then
+ // that button will send the menu a close() command, so this code
+ // shouldn't try to close the menu. Closing twice messes up animation.
+ if (this.currentButton && dojo.html.overElement(this.currentButton, e)){
+ return;
+ }
+
+ // the click didn't fall within the open menu tree
+ // so close it
+
+ this.currentMenu.close();
+ };
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/PopupContainer.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ProgressBar.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ProgressBar.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ProgressBar.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ProgressBar.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,279 @@
+dojo.provide("dojo.widget.ProgressBar");
+
+// requires here
+dojo.require("dojo.widget.*"); // necessary
+dojo.require("dojo.event");
+dojo.require("dojo.dom.*");
+dojo.require("dojo.html.style");
+dojo.require("dojo.string.*");
+dojo.require("dojo.lfx.*");
+
+dojo.widget.defineWidget(
+ "dojo.widget.ProgressBar",
+ dojo.widget.HtmlWidget,
+ {
+ // Constructor arguments
+ progressValue: "0",
+ maxProgressValue: 100,
+ width: 300,
+ height: 30,
+ frontPercentClass: "frontPercent",
+ backPercentClass: "backPercent",
+ frontBarClass: "frontBar",
+ backBarClass: "backBar",
+ hasText: "false",
+ isVertical:"false",
+ showOnlyIntegers: "false",
+ dataSource: "",
+ pollInterval: "3000",
+ duration: "1000",
+// leftImage: null,
+// centerImage: null,
+// rightImage: null,
+ templatePath: dojo.uri.dojoUri("src/widget/templates/ProgressBar.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/ProgressBar.css"),
+
+
+ // attach points
+ containerNode: null,
+ internalProgress: null,
+
+ // private members
+ _pixelUnitRatio: 0.0,
+ // _pixelRatio := width/100
+ _pixelPercentRatio: 0.0,
+ _unitPercentRatio: 0.0,
+ _unitPixelRatio: 0.0,
+ _floatDimension: 0.0,
+ _intDimension: 0,
+ _progressPercentValue: "0%",
+ _floatMaxProgressValue: 0.0,
+ _dimension: "width",
+ _pixelValue: 0,
+ _oInterval: null,
+ _animation: null,
+ _animationStopped: true,
+ _progressValueBak: false,
+ _hasTextBak: false,
+ // public functions
+ fillInTemplate: function(args, frag){
+ this.internalProgress.className = this.frontBarClass;
+ this.containerNode.className = this.backBarClass;
+ if (this.isVertical == "true"){
+ this.internalProgress.style.bottom="0px";
+ this.internalProgress.style.left="0px";
+ this._dimension = "height";
+ } else {
+ this.internalProgress.style.top="0px";
+ this.internalProgress.style.left="0px";
+ this._dimension = "width";
+ }
+ this.frontPercentLabel.className = this.frontPercentClass;
+ this.backPercentLabel.className = this.backPercentClass;
+ this.progressValue = "" + this.progressValue;
+ this.domNode.style.height = this.height;
+ this.domNode.style.width = this.width;
+ this._intDimension = parseInt("0" + eval("this." + this._dimension));
+ this._floatDimension = parseFloat("0" + eval("this."+this._dimension));
+ this._pixelPercentRatio = this._floatDimension/100;
+ this.setMaxProgressValue(this.maxProgressValue, true);
+ this.setProgressValue(dojo.string.trim(this.progressValue), true);
+ dojo.debug("float dimension: " + this._floatDimension);
+ dojo.debug("this._unitPixelRatio: " + this._unitPixelRatio);
+ this.showText(this.hasText);
+ },
+ showText: function(visible){
+ if (visible == "true"){
+ this.backPercentLabel.style.display="block";
+ this.frontPercentLabel.style.display="block";
+ } else {
+ this.backPercentLabel.style.display="none";
+ this.frontPercentLabel.style.display="none";
+ }
+ this.hasText = visible;
+ },
+ postCreate: function(args, frag){
+ // labels position
+ this.render();
+ },
+ _backupValues: function(){
+ this._progressValueBak = this.progressValue;
+ this._hasTextBak = this.hasText;
+ },
+ _restoreValues: function(){
+ this.setProgressValue(this._progressValueBak);
+ this.showText(this._hasTextBak);
+ },
+ _setupAnimation: function(){
+ var _self = this;
+ dojo.debug("internalProgress width: " + this.internalProgress.style.width);
+ this._animation = dojo.lfx.html.slideTo(this.internalProgress,
+ {top: 0, left: this.width-parseInt(this.internalProgress.style.width)}, parseInt(this.duration), null,
+ function(){
+ var _backAnim = dojo.lfx.html.slideTo(_self.internalProgress,
+ { top: 0, left: 0 }, parseInt(_self.duration));
+ dojo.event.connect(_backAnim, "onEnd", function(){
+ if (!_self._animationStopped){
+ _self._animation.play();
+ }
+ });
+ if (!_self._animationStopped){
+ _backAnim.play();
+ }
+ _backAnim = null; // <-- to avoid memory leaks in IE
+ }
+ );
+ },
+ getMaxProgressValue: function(){
+ return this.maxProgressValue;
+ },
+ setMaxProgressValue: function(maxValue, noRender){
+ if (!this._animationStopped){
+ return;
+ }
+ this.maxProgressValue = maxValue;
+ this._floatMaxProgressValue = parseFloat("0" + this.maxProgressValue);
+ this._pixelUnitRatio = this._floatDimension/this.maxProgressValue;
+ this._unitPercentRatio = this._floatMaxProgressValue/100;
+ this._unitPixelRatio = this._floatMaxProgressValue/this._floatDimension;
+ this.setProgressValue(this.progressValue, true);
+ if (!noRender){
+ this.render();
+ }
+ },
+ setProgressValue: function(value, noRender){
+ if (!this._animationStopped){
+ return;
+ }
+ // transformations here
+ this._progressPercentValue = "0%";
+ var _value=dojo.string.trim("" + value);
+ var _floatValue = parseFloat("0" + _value);
+ var _intValue = parseInt("0" + _value);
+ var _pixelValue = 0;
+ if (dojo.string.endsWith(_value, "%", false)){
+ this._progressPercentValue = Math.min(_floatValue.toFixed(1), 100) + "%";
+ _value = Math.min((_floatValue)*this._unitPercentRatio, this.maxProgressValue);
+ _pixelValue = Math.min((_floatValue)*this._pixelPercentRatio, eval("this."+this._dimension));
+ } else {
+ this.progressValue = Math.min(_floatValue, this.maxProgressValue);
+ this._progressPercentValue = Math.min((_floatValue/this._unitPercentRatio).toFixed(1), 100) + "%";
+ _pixelValue = Math.min(_floatValue/this._unitPixelRatio, eval("this."+this._dimension));
+ }
+ this.progressValue = dojo.string.trim(_value);
+ this._pixelValue = _pixelValue;
+ if (!noRender){
+ this.render();
+ }
+ },
+ setCurrentPercentProgress: function(percentProgress){
+ this._setCurrentPixelProgress(percentProgress);
+ },
+ getProgressValue: function(){
+ return this.progressValue;
+ },
+ getProgressPercentValue: function(){
+ return this._progressPercentValue;
+ },
+ setDataSource: function(dataSource){
+ this.dataSource = dataSource;
+ },
+ setPollInterval: function(pollInterval){
+ this.pollInterval = pollInterval;
+ },
+ start: function(){
+ var _showFunction = dojo.lang.hitch(this, this._showRemoteProgress);
+ this._oInterval = setInterval(_showFunction, this.pollInterval);
+ },
+ startAnimation: function(){
+ if (this._animationStopped) {
+ this._backupValues();
+ this.setProgressValue("10%");
+ this._animationStopped = false;
+ this._setupAnimation();
+ this.showText(false);
+ this.internalProgress.style.height="105%";
+ this._animation.play();
+ }
+ },
+ stopAnimation: function(){
+ if (this._animation) {
+ this._animationStopped = true;
+ this._animation.stop();
+ this.internalProgress.style.height="100%";
+ this.internalProgress.style.left = "0px";
+ this._restoreValues();
+ this._setLabelPosition();
+ }
+ },
+ _showRemoteProgress: function(){
+ var _self = this;
+// dojo.debug("getMax: "+this.getMaxProgressValue()+" getprval: "+this.getProgressValue());
+ if ( (this.getMaxProgressValue() == this.getProgressValue()) &&
+ this._oInterval){
+ clearInterval(this._oInterval);
+ this._oInterval = null;
+ this.setProgressValue("100%");
+ return;
+ }
+ var bArgs = {
+ url: _self.dataSource,
+ method: "POST",
+ mimetype: "text/json",
+ error: function(type, errorObj){
+ dojo.debug("[ProgressBar] showRemoteProgress error");
+ },
+ load: function(type, data, evt){
+ //dojo.debug(data["progress"]);
+ _self.setProgressValue(
+ (_self._oInterval ? data["progress"] : "100%")
+ );
+// dojo.debug("_oInterval: "+_self._oInterval);
+ }
+ };
+ dojo.io.bind(bArgs);
+ },
+ render: function(){
+ this._setPercentLabel(dojo.string.trim(this._progressPercentValue));
+ this._setPixelValue(this._pixelValue);
+ this._setLabelPosition();
+ },
+ // private functions
+ _setLabelPosition: function(){
+ var _widthFront =
+ dojo.html.getContentBox(this.frontPercentLabel).width;
+ var _heightFront =
+ dojo.html.getContentBox(this.frontPercentLabel).height;
+ var _widthBack =
+ dojo.html.getContentBox(this.backPercentLabel).width;
+ var _heightBack =
+ dojo.html.getContentBox(this.backPercentLabel).height;
+ var _leftFront = (this.width - _widthFront)/2 + "px";
+ var _bottomFront = (parseInt(this.height) - parseInt(_heightFront))/2 + "px";
+ var _leftBack = (this.width - _widthBack)/2 + "px";
+ var _bottomBack = (parseInt(this.height) - parseInt(_heightBack))/2 + "px";
+ this.frontPercentLabel.style.left = _leftFront;
+ this.backPercentLabel.style.left = _leftBack;
+ this.frontPercentLabel.style.bottom = _bottomFront;
+ this.backPercentLabel.style.bottom = _bottomBack;
+// dojo.debug("bottom: "+this.backPercentLabel.style.bottom);
+// dojo.debug("BOTTOM: "+_bottom);
+ },
+ _setPercentLabel: function(percentValue){
+ dojo.dom.removeChildren(this.frontPercentLabel);
+ dojo.dom.removeChildren(this.backPercentLabel);
+ var _percentValue = this.showOnlyIntegers == "false" ?
+ percentValue : parseInt(percentValue) + "%";
+ this.frontPercentLabel.
+ appendChild(document.createTextNode(_percentValue));
+ this.backPercentLabel.
+ appendChild(document.createTextNode(_percentValue));
+ },
+ _setPixelValue: function(value){
+ eval("this.internalProgress.style." + this._dimension + " = " + value + " + 'px'");
+ this.onChange();
+ },
+ onChange: function(){
+ }
+ });
+
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ProgressBar.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RadioGroup.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RadioGroup.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RadioGroup.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RadioGroup.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,184 @@
+dojo.provide("dojo.widget.RadioGroup");
+
+dojo.require("dojo.lang.common");
+dojo.require("dojo.event.browser");
+dojo.require("dojo.html.selection");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+
+// Widget that provides useful/common functionality that may be desirable
+// when interacting with ul/ol html lists.
+//
+// This widget was mostly developed under supervision/guidance from Tom Trenka.
+dojo.widget.defineWidget(
+ "dojo.widget.RadioGroup",
+ dojo.widget.HtmlWidget,
+ function(){
+ this.selectedItem=null; //currently selected li, if any
+ this.listNode=null; //the containing ul or ol
+ this.items=[]; //the individual li's
+ this.selected=[];
+
+ // CSS classes as attributes.
+ this.groupCssClass="radioGroup";
+ this.selectedCssClass="selected";
+ this.itemContentCssClass="itemContent";
+ },
+ {
+ isContainer:false,
+ templatePath: null,
+ templateCssPath: null,
+
+ // overridden from HtmlWidget
+ postCreate:function(){
+ this.parseStructure();
+ dojo.html.addClass(this.listNode, this.groupCssClass);
+ this.setupChildren();
+ dojo.event.browser.addListener(this.listNode, "onclick", dojo.lang.hitch(this, "onSelect"));
+ if (this.selectedItem){
+ this.selectItem(this.selectedItem);
+ }
+ },
+
+ /*
+ * Sets local radioGroup and items properties, also validates
+ * that domNode contains an expected list.
+ *
+ * exception: If a ul or ol node can't be found in this widgets domNode
+ */
+ parseStructure:function() {
+ var listNode = dojo.dom.firstElement(this.domNode, "ul");
+ if (!listNode) { listNode = dojo.dom.firstElement(this.domNode, "ol");}
+
+ if (listNode) {
+ this.listNode = listNode;
+ this.items=[]; // reset the items.
+ var nl=listNode.getElementsByTagName("li");
+ for (var i=0; i<nl.length; i++){
+ if(nl[i].parentNode==listNode){
+ this.items.push(nl[i]);
+ }
+ }
+ return;
+ }
+ dojo.raise("RadioGroup: Expected ul or ol content.");
+ },
+
+ /*
+ * Allows the app to add a node on the fly, finishing up
+ * the setup so that we don't need to deal with it on a
+ * widget-wide basis.
+ */
+ add:function(node){
+ if(node.parentNode!=this.listNode){
+ this.listNode.appendChild(node);
+ }
+ this.items.push(node);
+ this.setup(node);
+ },
+
+ // removes the specified node from this group, if it exists
+ remove:function(node){
+ var idx=-1;
+ for(var i=0; i<this.items.length; i++){
+ if(this.items[i]==node){
+ idx=i;
+ break;
+ }
+ }
+ if(idx<0) {return;}
+ this.items.splice(idx,1);
+ node.parentNode.removeChild(node);
+ },
+
+ // removes all items in this list
+ clear:function(){
+ for(var i=0; i<this.items.length; i++){
+ this.listNode.removeChild(this.items[i]);
+ }
+ this.items=[];
+ },
+
+ // clears any selected items from being selected
+ clearSelections:function(){
+ for(var i=0; i<this.items.length; i++){
+ dojo.html.removeClass(this.items[i], this.selectedCssClass);
+ }
+ this.selectedItem=null;
+ },
+
+ setup:function(node){
+ var span = document.createElement("span");
+ dojo.html.disableSelection(span);
+ dojo.html.addClass(span, this.itemContentCssClass);
+ dojo.dom.moveChildren(node, span);
+ node.appendChild(span);
+
+ if (this.selected.length > 0) {
+ var uid = dojo.html.getAttribute(node, "id");
+ if (uid && uid == this.selected){
+ this.selectedItem = node;
+ }
+ }
+ dojo.event.browser.addListener(node, "onclick", dojo.lang.hitch(this, "onItemSelect"));
+ if (dojo.html.hasAttribute(node, "onitemselect")) {
+ var tn = dojo.lang.nameAnonFunc(new Function(dojo.html.getAttribute(node, "onitemselect")),
+ this);
+ dojo.event.browser.addListener(node, "onclick", dojo.lang.hitch(this, tn));
+ }
+ },
+
+ /*
+ * Iterates over the items li nodes and manipulates their
+ * dom structures to handle things like span tag insertion
+ * and selecting a default item.
+ */
+ setupChildren:function(){
+ for (var i=0; i<this.items.length; i++){
+ this.setup(this.items[i]);
+ }
+ },
+
+ // Sets the selectedItem to passed in node, applies
+ // css selection class on new item
+ selectItem:function(node, event, nofire){
+ if(this.selectedItem){
+ dojo.html.removeClass(this.selectedItem, this.selectedCssClass);
+ }
+
+ this.selectedItem = node;
+ dojo.html.addClass(this.selectedItem, this.selectedCssClass);
+
+ // if this is the result of an event, stop here.
+ if (!dj_undef("currentTarget", event)){
+ return;
+ }
+
+ // if there's no nofire flag, passed when this is nailed internally.
+ if(!nofire){
+ if(dojo.render.html.ie){
+ this.selectedItem.fireEvent("onclick");
+ }else{
+ var e = document.createEvent("MouseEvents");
+ e.initEvent("click", true, false);
+ this.selectedItem.dispatchEvent(e);
+ }
+ }
+ },
+
+ // gets the currently selected item
+ getValue:function() {
+ return this.selectedItem;
+ },
+
+ // when the ul or ol contained by this widget is selected
+ onSelect:function(e) { },
+
+ // when an individual li is selected
+ onItemSelect:function(e) {
+ if (!dj_undef("currentTarget", e)){
+ this.selectItem(e.currentTarget, e);
+ }
+ }
+ }
+);
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RadioGroup.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RealNumberTextbox.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RealNumberTextbox.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RealNumberTextbox.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RealNumberTextbox.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,63 @@
+dojo.provide("dojo.widget.RealNumberTextbox");
+
+dojo.require("dojo.widget.IntegerTextbox");
+dojo.require("dojo.validate.common");
+
+/*
+ ****** RealNumberTextbox ******
+
+ A subclass that extends IntegerTextbox.
+ Over-rides isValid/isInRange to test for real number input.
+ Has 5 new properties that can be specified as attributes in the markup.
+
+ @attr places The exact number of decimal places. If omitted, it's unlimited and optional.
+ @attr exponent Can be true or false. If omitted the exponential part is optional.
+ @attr eSigned Is the exponent signed? Can be true or false, if omitted the sign is optional.
+ @attr min Minimum signed value. Default is -Infinity
+ @attr max Maximum signed value. Default is +Infinity
+*/
+dojo.widget.defineWidget(
+ "dojo.widget.RealNumberTextbox",
+ dojo.widget.IntegerTextbox,
+ {
+ mixInProperties: function(localProperties, frag){
+ // First initialize properties in super-class.
+ dojo.widget.RealNumberTextbox.superclass.mixInProperties.apply(this, arguments);
+
+ // Get properties from markup attributes, and assign to flags object.
+ if (localProperties.places){
+ this.flags.places = Number(localProperties.places);
+ }
+ if((localProperties.exponent == "true")||
+ (localProperties.exponent == "always")){
+ this.flags.exponent = true;
+ }else if((localProperties.exponent == "false")||(localProperties.exponent == "never")){
+ this.flags.exponent = false;
+ }else{
+ this.flags.exponent = [ true, false ]; // optional
+ }
+ if((localProperties.esigned == "true")||(localProperties.esigned == "always")){
+ this.flags.eSigned = true;
+ }else if((localProperties.esigned == "false")||(localProperties.esigned == "never")){
+ this.flags.eSigned = false;
+ }else{
+ this.flags.eSigned = [ true, false ]; // optional
+ }
+ if(localProperties.min){
+ this.flags.min = parseFloat(localProperties.min);
+ }
+ if(localProperties.max){
+ this.flags.max = parseFloat(localProperties.max);
+ }
+ },
+
+ // Over-ride for real number validation
+ isValid: function(){
+ return dojo.validate.isRealNumber(this.textbox.value, this.flags);
+ },
+ isInRange: function(){
+ return dojo.validate.isInRange(this.textbox.value, this.flags);
+ }
+
+ }
+);
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RealNumberTextbox.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RegexpTextbox.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RegexpTextbox.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RegexpTextbox.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RegexpTextbox.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,38 @@
+dojo.provide("dojo.widget.RegexpTextbox");
+
+dojo.require("dojo.widget.ValidationTextbox");
+
+/*
+ ****** RegexpTextbox ******
+
+ A subclass of ValidationTextbox.
+ Over-rides isValid to test input based on a regular expression.
+ Has a new property that can be specified as attributes in the markup.
+
+ @attr regexp The regular expression string to use
+ @attr flags Flags to pass to the regular expression (e.g. 'i', 'g', etc)
+*/
+dojo.widget.defineWidget(
+ "dojo.widget.RegexpTextbox",
+ dojo.widget.ValidationTextbox,
+ {
+ mixInProperties: function(localProperties, frag){
+ // First initialize properties in super-class.
+ dojo.widget.RegexpTextbox.superclass.mixInProperties.apply(this, arguments);
+
+ // Get properties from markup attibutes, and assign to flags object.
+ if(localProperties.regexp){
+ this.flags.regexp = localProperties.regexp;
+ }
+ if(localProperties.flags){
+ this.flags.flags = localProperties.flags;
+ }
+ },
+
+ // Over-ride for integer validation
+ isValid: function(){
+ var regexp = new RegExp(this.flags.regexp, this.flags.flags);
+ return regexp.test(this.textbox.value);
+ }
+ }
+);
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RegexpTextbox.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RemoteTabController.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RemoteTabController.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RemoteTabController.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RemoteTabController.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,40 @@
+dojo.provide("dojo.widget.RemoteTabController");
+
+//Summary
+//Remote Tab Controller widget. Can be located independently of a tab
+//container and control the selection of its tabs
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.TabContainer");
+dojo.require("dojo.event.*");
+
+dojo.deprecated("dojo.widget.RemoteTabController is slated for removal in 0.5; use PageController or TabController instead.", "0.5");
+
+dojo.widget.defineWidget(
+ "dojo.widget.RemoteTabController",
+ dojo.widget.TabController,
+ {
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/RemoteTabControl.css"),
+ templateString: '<div dojoAttachPoint="domNode" wairole="tablist"></div>',
+
+ "class": "dojoRemoteTabController",
+
+ // String
+ // ID of page container that I connect to
+ tabContainer: "",
+
+ postMixInProperties: function(){
+ this.containerId = this.tabContainer;
+ dojo.widget.RemoteTabController.superclass.postMixInProperties.apply(this, arguments);
+ },
+
+ fillInTemplate: function() {
+ dojo.html.addClass(this.domNode, this["class"]); // "class" is a reserved word in JS
+
+ if (this.tabContainer) {
+ dojo.addOnLoad(dojo.lang.hitch(this, "setupTabs"));
+ }
+
+ dojo.widget.RemoteTabController.superclass.fillInTemplate.apply(this, arguments);
+ }
+ }
+);
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/RemoteTabController.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Repeater.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Repeater.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Repeater.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Repeater.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,130 @@
+dojo.provide("dojo.widget.Repeater");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.string");
+dojo.require("dojo.event.*");
+dojo.require("dojo.experimental");
+dojo.experimental("dojo.widget.Repeater");
+
+dojo.widget.defineWidget("dojo.widget.Repeater", dojo.widget.HtmlWidget,
+ {
+ name: "",
+ rowTemplate: "",
+ myObject: null,
+ pattern: "",
+ useDnd: false,
+ isContainer: true,
+
+ initialize: function(args,frag) {
+ var node = this.getFragNodeRef(frag);
+ node.removeAttribute("dojotype");
+ this.setRow(dojo.string.trim(node.innerHTML), {});
+ node.innerHTML="";
+ frag=null;
+ },
+
+ postCreate: function(args,frag){
+ if (this.useDnd) {
+ dojo.require("dojo.dnd.*");
+ var dnd = new dojo.dnd.HtmlDropTarget(this.domNode, [this.widgetId]);
+ }
+ },
+
+ reIndexRows: function() {
+ for(var i=0,len=this.domNode.childNodes.length; i<len;i++) {
+ var elems = ["INPUT", "SELECT", "TEXTAREA"];
+ for (var k=0; k < elems.length; k++) {
+ var list = this.domNode.childNodes[i].getElementsByTagName(elems[k]);
+ for (var j=0,len2=list.length; j<len2; j++) {
+ var name = list[j].name;
+ var index=dojo.string.escape("regexp", this.pattern);
+ index = index.replace(/%\\{index\\}/g,"%{index}");
+ var nameRegexp = dojo.string.substituteParams(index, {"index": "[0-9]*"});
+ var newName= dojo.string.substituteParams(this.pattern, {"index": "" + i});
+ var re=new RegExp(nameRegexp,"g");
+ list[j].name = name.replace(re,newName);
+ }
+ }
+ }
+ },
+
+ onDeleteRow: function(e) {
+ var index=dojo.string.escape("regexp", this.pattern);
+ index = index.replace(/%\\{index\\}/g,"%{index}");
+ var nameRegexp = dojo.string.substituteParams(index, {"index": "([0-9]*)"});
+ var re=new RegExp(nameRegexp,"g");
+ this.deleteRow(re.exec(e.target.name)[1]);
+ },
+ hasRows: function() {
+ if (this.domNode.childNodes.length > 0) {
+ return true;
+ }
+ return false;
+ },
+
+ getRowCount: function() {
+ return this.domNode.childNodes.length;
+ },
+
+ deleteRow: function(idx) {
+ this.domNode.removeChild(this.domNode.childNodes[idx]);
+ this.reIndexRows();
+ },
+
+ changeRowPosition: function(e) {
+ if (e.dragStatus == "dropFailure") {
+ this.domNode.removeChild(e["dragSource"].domNode);
+ } else if (e.dragStatus == "dropSuccess") {
+ // nothing to do
+ } // else-if
+ this.reIndexRows();
+ },
+ setRow: function(template, myObject) {
+ template = dojo.string.substituteParams(template, {"index": "0"});
+ this.rowTemplate=template;
+ this.myObject = myObject;
+ },
+ getRow: function() {
+ return this.rowTemplate;
+ },
+ onAddRow: function(e) {
+ },
+ addRow: function() {
+ var node = document.createElement('span');
+ node.innerHTML=this.getRow();
+ if (node.childNodes.length == 1) {
+ node=node.childNodes[0];
+ }
+ this.domNode.appendChild(node);
+ var parser = new dojo.xml.Parse();
+ var frag = parser.parseElement(node, null, true);
+ dojo.widget.getParser().createSubComponents(frag, this);
+ var elems = ["INPUT", "SELECT", "IMG"];
+ for (var k=0; k < elems.length; k++) {
+ var list = node.getElementsByTagName(elems[k]);
+ for(var i=0, len=list.length; i<len; i++) {
+ var child = list[i];
+ if(child.nodeType != 1) {continue};
+ if (child.getAttribute("rowFunction") != null) {
+ if(typeof(this.myObject[child.getAttribute("rowFunction")]) == "undefined") {
+ dojo.debug("Function " + child.getAttribute("rowFunction") + " not found");
+ } else {
+ this.myObject[child.getAttribute("rowFunction")](child);
+ }
+ } else if (child.getAttribute("rowAction") != null) {
+ if(child.getAttribute("rowAction") == "delete") {
+ child.name=dojo.string.substituteParams(this.pattern, {"index": "0"});
+ dojo.event.connect(child, "onclick", this, "onDeleteRow");
+ } // if
+ } // else-if
+ } // for
+ } // for
+ this.reIndexRows();
+ if (this.useDnd) { // bind to DND
+ node=new dojo.dnd.HtmlDragSource(node, this.widgetId);
+ dojo.event.connect(node, "onDragEnd", this, "changeRowPosition");
+ }
+ this.onAddRow();
+ }
+});
+
+
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/Repeater.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizableTextarea.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizableTextarea.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizableTextarea.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizableTextarea.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,92 @@
+dojo.provide("dojo.widget.ResizableTextarea");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.LayoutContainer");
+dojo.require("dojo.widget.ResizeHandle");
+
+dojo.widget.defineWidget(
+ "dojo.widget.ResizableTextarea",
+ dojo.widget.HtmlWidget,
+{
+ templatePath: dojo.uri.dojoUri("src/widget/templates/ResizableTextarea.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/ResizableTextarea.css"),
+ isContainer: false,
+ textAreaNode: null,
+ textAreaContainer: null,
+ textAreaContainerNode: null,
+ statusBar: null,
+ statusBarContainerNode: null,
+ statusLabelNode: null,
+ statusLabel: null,
+ rootLayoutNode: null,
+ resizeHandleNode: null,
+ resizeHandle: null,
+
+ fillInTemplate: function(args, frag){
+ this.textAreaNode = this.getFragNodeRef(frag).cloneNode(true);
+
+ // FIXME: Safari apparently needs this!
+ dojo.body().appendChild(this.domNode);
+
+ this.rootLayout = dojo.widget.createWidget(
+ "LayoutContainer",
+ {
+ minHeight: 50,
+ minWidth: 100
+ },
+ this.rootLayoutNode
+ );
+
+
+ this.textAreaContainer = dojo.widget.createWidget(
+ "LayoutContainer",
+ { layoutAlign: "client" },
+ this.textAreaContainerNode
+ );
+ this.rootLayout.addChild(this.textAreaContainer);
+
+ this.textAreaContainer.domNode.appendChild(this.textAreaNode);
+ with(this.textAreaNode.style){
+ width="100%";
+ height="100%";
+ }
+
+ this.statusBar = dojo.widget.createWidget(
+ "LayoutContainer",
+ {
+ layoutAlign: "bottom",
+ minHeight: 28
+ },
+ this.statusBarContainerNode
+ );
+ this.rootLayout.addChild(this.statusBar);
+
+ this.statusLabel = dojo.widget.createWidget(
+ "LayoutContainer",
+ {
+ layoutAlign: "client",
+ minWidth: 50
+ },
+ this.statusLabelNode
+ );
+ this.statusBar.addChild(this.statusLabel);
+
+ this.resizeHandle = dojo.widget.createWidget(
+ "ResizeHandle",
+ { targetElmId: this.rootLayout.widgetId },
+ this.resizeHandleNode
+ );
+ this.statusBar.addChild(this.resizeHandle);
+ // dojo.debug(this.rootLayout.widgetId);
+
+ // dojo.event.connect(this.resizeHandle, "beginSizing", this, "hideContent");
+ // dojo.event.connect(this.resizeHandle, "endSizing", this, "showContent");
+ },
+
+ hideContent: function(){
+ this.textAreaNode.style.display = "none";
+ },
+
+ showContent: function(){
+ this.textAreaNode.style.display = "";
+ }
+});
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizableTextarea.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizeHandle.js
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizeHandle.js?view=auto&rev=473755
==============================================================================
--- jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizeHandle.js (added)
+++ jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizeHandle.js Sat Nov 11 08:44:22 2006
@@ -0,0 +1,93 @@
+dojo.provide("dojo.widget.ResizeHandle");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.html.layout");
+dojo.require("dojo.event.*");
+
+dojo.widget.defineWidget(
+ "dojo.widget.ResizeHandle",
+ dojo.widget.HtmlWidget,
+{
+ isSizing: false,
+ startPoint: null,
+ startSize: null,
+ minSize: null,
+
+ targetElmId: '',
+
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/ResizeHandle.css"),
+ templateString: '<div class="dojoHtmlResizeHandle"><div></div></div>',
+
+ postCreate: function(){
+ dojo.event.connect(this.domNode, "onmousedown", this, "beginSizing");
+ },
+
+ beginSizing: function(e){
+ if (this.isSizing){ return false; }
+
+ // get the target dom node to adjust. targetElmId can refer to either a widget or a simple node
+ this.targetWidget = dojo.widget.byId(this.targetElmId);
+ this.targetDomNode = this.targetWidget ? this.targetWidget.domNode : dojo.byId(this.targetElmId);
+ if (!this.targetDomNode){ return; }
+
+ this.isSizing = true;
+ this.startPoint = {'x':e.clientX, 'y':e.clientY};
+ var mb = dojo.html.getMarginBox(this.targetDomNode);
+ this.startSize = {'w':mb.width, 'h':mb.height};
+
+ dojo.event.kwConnect({
+ srcObj: dojo.body(),
+ srcFunc: "onmousemove",
+ targetObj: this,
+ targetFunc: "changeSizing",
+ rate: 25
+ });
+ dojo.event.connect(dojo.body(), "onmouseup", this, "endSizing");
+
+ e.preventDefault();
+ },
+
+ changeSizing: function(e){
+ // On IE, if you move the mouse above/to the left of the object being resized,
+ // sometimes clientX/Y aren't set, apparently. Just ignore the event.
+ try{
+ if(!e.clientX || !e.clientY){ return; }
+ }catch(e){
+ // sometimes you get an exception accessing above fields...
+ return;
+ }
+ var dx = this.startPoint.x - e.clientX;
+ var dy = this.startPoint.y - e.clientY;
+
+ var newW = this.startSize.w - dx;
+ var newH = this.startSize.h - dy;
+
+ // minimum size check
+ if (this.minSize) {
+ var mb = dojo.html.getMarginBox(this.targetDomNode);
+ if (newW < this.minSize.w) {
+ newW = mb.width;
+ }
+ if (newH < this.minSize.h) {
+ newH = mb.height;
+ }
+ }
+
+ if(this.targetWidget){
+ this.targetWidget.resizeTo(newW, newH);
+ }else{
+ dojo.html.setMarginBox(this.targetDomNode, { width: newW, height: newH});
+ }
+
+ e.preventDefault();
+ },
+
+ endSizing: function(e){
+ dojo.event.disconnect(dojo.body(), "onmousemove", this, "changeSizing");
+ dojo.event.disconnect(dojo.body(), "onmouseup", this, "endSizing");
+
+ this.isSizing = false;
+ }
+
+
+});
Propchange: jackrabbit/trunk/contrib/jcr-browser/src/main/webapp/dojo/src/widget/ResizeHandle.js
------------------------------------------------------------------------------
svn:eol-style = native