Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Menu2.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Menu2.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Menu2.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Menu2.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,766 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.Menu2"); + +dojo.require("dojo.widget.PopupContainer"); + +dojo.widget.defineWidget( + "dojo.widget.PopupMenu2", + dojo.widget.PopupContainer, + function(){ + // summary + // provides a menu that can be used as a context menu (typically shown by right-click), + // or as the drop down on a DropDownButton, ComboButton, etc. + + // targetNodeIds: String[] + // Array of dom node ids of nodes to attach to. + // Fill this with nodeIds upon widget creation and it becomes context menu for those nodes. + this.targetNodeIds = []; + + this.eventNames = { + open: "" + }; + }, +{ + snarfChildDomOutput: true, + + // eventNaming: String + // if "default" event names are based on widget id, otherwise user must define + // TODO: write real documentation about the events + eventNaming: "default", + + templateString: '<table class="dojoPopupMenu2" border=0 cellspacing=0 cellpadding=0 style="display: none;"><tbody dojoAttachPoint="containerNode"></tbody></table>', + templateCssPath: dojo.uri.dojoUri("src/widget/templates/Menu2.css"), + templateCssString: "", + + // submenuDelay: Integer + // number of milliseconds before hovering (without clicking) causes the submenu to automatically open + submenuDelay: 500, + + // submenuOverlap: Integer + // a submenu usually appears to the right, but slightly overlapping, it's parent menu; + // this controls the number of pixels the two menus overlap. + submenuOverlap: 5, + + // contextMenuForWindow: Boolean + // if true, right clicking anywhere on the window will cause this context menu to open; + // if false, must specify targetNodeIds + contextMenuForWindow: false, + + initialize: function(args, frag) { + if (this.eventNaming == "default") { + for (var eventName in this.eventNames) { + this.eventNames[eventName] = this.widgetId+"/"+eventName; + } + } + }, + + postCreate: function(){ + if (this.contextMenuForWindow){ + var doc = dojo.body(); + this.bindDomNode(doc); + } else if ( this.targetNodeIds.length > 0 ){ + dojo.lang.forEach(this.targetNodeIds, this.bindDomNode, this); + } + + this._subscribeSubitemsOnOpen(); + }, + + _subscribeSubitemsOnOpen: function() { + var subItems = this.getChildrenOfType(dojo.widget.MenuItem2); + + for(var i=0; i<subItems.length; i++) { + dojo.event.topic.subscribe(this.eventNames.open, subItems[i], "menuOpen") + } + }, + + getTopOpenEvent: function() { + // summary: get event that initially caused current chain of menus to open + var menu = this; + while (menu.parentPopup){ menu = menu.parentPopup; } + return menu.openEvent; // Event + }, + + bindDomNode: function(/*String|DomNode*/ node){ + // summary: attach menu to given node + node = dojo.byId(node); + + var win = dojo.html.getElementWindow(node); + if(dojo.html.isTag(node,'iframe') == 'iframe'){ + win = dojo.html.iframeContentWindow(node); + node = dojo.withGlobal(win, dojo.body); + } + // fixes node so that it supports oncontextmenu if not natively supported, Konqueror, Opera more? + dojo.widget.Menu2.OperaAndKonqFixer.fixNode(node); + + dojo.event.kwConnect({ + srcObj: node, + srcFunc: "oncontextmenu", + targetObj: this, + targetFunc: "onOpen", + once: true + }); + + //normal connect does not work if document.designMode is on in FF, use addListener instead + if(dojo.render.html.moz && win.document.designMode.toLowerCase() == 'on'){ + dojo.event.browser.addListener(node, "contextmenu", dojo.lang.hitch(this, "onOpen")); + } + dojo.widget.PopupManager.registerWin(win); + }, + + unBindDomNode: function(/*String|DomNode*/ nodeName){ + // summary: detach menu from given node + var node = dojo.byId(nodeName); + dojo.event.kwDisconnect({ + srcObj: node, + srcFunc: "oncontextmenu", + targetObj: this, + targetFunc: "onOpen", + once: true + }); + + // cleans a fixed node, konqueror and opera + dojo.widget.Menu2.OperaAndKonqFixer.cleanNode(node); + }, + + _moveToNext: function(/*Event*/ evt){ + this._highlightOption(1); + return true; //do not pass to parent menu + }, + + _moveToPrevious: function(/*Event*/ evt){ + this._highlightOption(-1); + return true; //do not pass to parent menu + }, + + _moveToParentMenu: function(/*Event*/ evt){ + if(this._highlighted_option && this.parentPopup){ + //only process event in the focused menu + //and its immediate parentPopup to support + //MenuBar2 + if(evt._menu2UpKeyProcessed){ + return true; //do not pass to parent menu + }else{ + this._highlighted_option.onUnhover(); + this.closeSubpopup(); + evt._menu2UpKeyProcessed = true; + } + } + return false; + }, + + _moveToChildMenu: function(/*Event*/ evt){ + if(this._highlighted_option && this._highlighted_option.submenuId){ + this._highlighted_option._onClick(true); + return true; //do not pass to parent menu + } + return false; + }, + + _selectCurrentItem: function(/*Event*/ evt){ + if(this._highlighted_option){ + this._highlighted_option._onClick(); + return true; + } + return false; + }, + + processKey: function(/*Event*/ evt){ + // summary + // callback to process key strokes + // return true to stop the event being processed by the + // parent popupmenu + + if(evt.ctrlKey || evt.altKey || !evt.key){ return false; } + + var rval = false; + switch(evt.key){ + case evt.KEY_DOWN_ARROW: + rval = this._moveToNext(evt); + break; + case evt.KEY_UP_ARROW: + rval = this._moveToPrevious(evt); + break; + case evt.KEY_RIGHT_ARROW: + rval = this._moveToChildMenu(evt); + break; + case evt.KEY_LEFT_ARROW: + rval = this._moveToParentMenu(evt); + break; + case " ": //fall through + case evt.KEY_ENTER: + if(rval = this._selectCurrentItem(evt)){ + break; + } + //fall through + case evt.KEY_ESCAPE: + dojo.widget.PopupManager.currentMenu.close(); + rval = true; + break; + } + + return rval; + }, + + _findValidItem: function(dir, curItem){ + if(curItem){ + curItem = dir>0 ? curItem.getNextSibling() : curItem.getPreviousSibling(); + } + + for(var i=0; i < this.children.length; ++i){ + if(!curItem){ + curItem = dir>0 ? this.children[0] : this.children[this.children.length-1]; + } + //find next/previous visible menu item, not including separators + if(curItem.onHover && curItem.isShowing()){ + return curItem; + } + curItem = dir>0 ? curItem.getNextSibling() : curItem.getPreviousSibling(); + } + }, + + _highlightOption: function(dir){ + var item; + // || !this._highlighted_option.parentNode + if((!this._highlighted_option)){ + item = this._findValidItem(dir); + }else{ + item = this._findValidItem(dir, this._highlighted_option); + } + if(item){ + if(this._highlighted_option) { + this._highlighted_option.onUnhover(); + } + item.onHover(); + dojo.html.scrollIntoView(item.domNode); + // navigate into the item table and select the first caption tag + try { + var node = dojo.html.getElementsByClass("dojoMenuItem2Label", item.domNode)[0]; + node.focus(); + } catch(e) { } + } + }, + + onItemClick: function(/*Widget*/ item) { + // summary: user defined function to handle clicks on an item + }, + + close: function(/*Boolean*/ force){ + // summary: close the menu + if(this.animationInProgress){ + dojo.widget.PopupMenu2.superclass.close.apply(this, arguments); + return; + } + + if(this._highlighted_option){ + this._highlighted_option.onUnhover(); + } + + dojo.widget.PopupMenu2.superclass.close.apply(this, arguments); + }, + + closeSubpopup: function(force){ + // summary: close the currently displayed submenu + if (this.currentSubpopup == null){ return; } + + this.currentSubpopup.close(force); + this.currentSubpopup = null; + + this.currentSubmenuTrigger.is_open = false; + this.currentSubmenuTrigger._closedSubmenu(force); + this.currentSubmenuTrigger = null; + }, + + _openSubmenu: function(submenu, from_item){ + // summary: open the menu to the right of the current menu item + var fromPos = dojo.html.getAbsolutePosition(from_item.domNode, true); + var our_w = dojo.html.getMarginBox(this.domNode).width; + var x = fromPos.x + our_w - this.submenuOverlap; + var y = fromPos.y; + + //the following is set in open, so we do not need it + //this.currentSubpopup = submenu; + submenu.open(x, y, this, from_item.domNode); + + this.currentSubmenuTrigger = from_item; + this.currentSubmenuTrigger.is_open = true; + }, + + onOpen: function(/*Event*/ e){ + // summary: callback when menu is opened + this.openEvent = e; + if(e["target"]){ + this.openedForWindow = dojo.html.getElementWindow(e.target); + }else{ + this.openedForWindow = null; + } + var x = e.pageX, y = e.pageY; + + var win = dojo.html.getElementWindow(e.target); + var iframe = win._frameElement || win.frameElement; + if(iframe){ + var cood = dojo.html.abs(iframe, true); + x += cood.x - dojo.withGlobal(win, dojo.html.getScroll).left; + y += cood.y - dojo.withGlobal(win, dojo.html.getScroll).top; + } + this.open(x, y, null, [x, y]); + + e.preventDefault(); + e.stopPropagation(); + } +}); + +// summary +// A line item in a Menu2 +dojo.widget.defineWidget( + "dojo.widget.MenuItem2", + dojo.widget.HtmlWidget, + function(){ + this.eventNames = { + engage: "" + }; + }, +{ + // Make 4 columns + // icon, label, accelerator-key, and right-arrow indicating sub-menu + templateString: + '<tr class="dojoMenuItem2" dojoAttachEvent="onMouseOver: onHover; onMouseOut: onUnhover; onClick: _onClick; onKey:onKey;">' + +'<td><div class="${this.iconClass}" style="${this.iconStyle}"></div></td>' + +'<td tabIndex="-1" class="dojoMenuItem2Label">${this.caption}</td>' + +'<td class="dojoMenuItem2Accel">${this.accelKey}</td>' + +'<td><div class="dojoMenuItem2Submenu" style="display:${this.arrowDisplay};"></div></td>' + +'</tr>', + + // + // internal settings + // + + is_hovering: false, + hover_timer: null, + is_open: false, + topPosition: 0, + + // + // options + // + + // caption: String + // text of the menu item + caption: 'Untitled', + + // accelKey: String + // accelerator key (not supported yet!) + accelKey: '', + + // iconSrc: String + // path to icon to display to the left of the menu text + iconSrc: '', + + // disabledClass: String + // CSS class for disabled nodes + disabledClass: 'dojoMenuItem2Disabled', + + // iconClass: String + // CSS class name to use for menu item (if CSS class specifies a background image then iconSrc is not necessary) + iconClass: 'dojoMenuItem2Icon', + + // submenuId: String + // widget ID of Menu2 widget to open when this menu item is clicked + submenuId: '', + + // eventNaming: String + // event names for announcing when menu item is clicked. + // if "default", then use the default name, based on the widget ID + eventNaming: "default", + + // highlightClass: String + // CSS class for menu item when it's hovered over + highlightClass: 'dojoMenuItem2Hover', + + postMixInProperties: function(){ + this.iconStyle=""; + if (this.iconSrc){ + if ((this.iconSrc.toLowerCase().substring(this.iconSrc.length-4) == ".png") && (dojo.render.html.ie55 || dojo.render.html.ie60)){ + this.iconStyle="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.iconSrc+"', sizingMethod='image')"; + }else{ + this.iconStyle="background-image: url("+this.iconSrc+")"; + } + } + this.arrowDisplay = this.submenuId ? 'block' : 'none'; + dojo.widget.MenuItem2.superclass.postMixInProperties.apply(this, arguments); + }, + + fillInTemplate: function(){ + dojo.html.disableSelection(this.domNode); + + if (this.disabled){ + this.setDisabled(true); + } + + if (this.eventNaming == "default") { + for (var eventName in this.eventNames) { + this.eventNames[eventName] = this.widgetId+"/"+eventName; + } + } + }, + + onHover: function(){ + // summary: callback when mouse is moved onto menu item + + //this is to prevent some annoying behavior when both mouse and keyboard are used + this.onUnhover(); + + if (this.is_hovering){ return; } + if (this.is_open){ return; } + + if(this.parent._highlighted_option){ + this.parent._highlighted_option.onUnhover(); + } + this.parent.closeSubpopup(); + this.parent._highlighted_option = this; + dojo.widget.PopupManager.setFocusedMenu(this.parent); + + this._highlightItem(); + + if (this.is_hovering){ this._stopSubmenuTimer(); } + this.is_hovering = true; + this._startSubmenuTimer(); + }, + + onUnhover: function(){ + // summary: callback when mouse is moved off of menu item + if(!this.is_open){ this._unhighlightItem(); } + + this.is_hovering = false; + + this.parent._highlighted_option = null; + + if(this.parent.parentPopup){ + dojo.widget.PopupManager.setFocusedMenu(this.parent.parentPopup); + } + + this._stopSubmenuTimer(); + }, + + _onClick: function(focus){ + // summary: internal function for clicks + var displayingSubMenu = false; + if (this.disabled){ return false; } + + if (this.submenuId){ + if (!this.is_open){ + this._stopSubmenuTimer(); + this._openSubmenu(); + } + displayingSubMenu = true; + }else{ + // for some browsers the onMouseOut doesn't get called (?), so call it manually + this.onUnhover(); //only onUnhover when no submenu is available + this.parent.closeAll(true); + } + + // user defined handler for click + this.onClick(); + + dojo.event.topic.publish(this.eventNames.engage, this); + + if(displayingSubMenu && focus){ + dojo.widget.getWidgetById(this.submenuId)._highlightOption(1); + } + return; + }, + + onClick: function() { + // summary + // User defined function to handle clicks + // this default function call the parent + // menu's onItemClick + this.parent.onItemClick(this); + }, + + _highlightItem: function(){ + dojo.html.addClass(this.domNode, this.highlightClass); + }, + + _unhighlightItem: function(){ + dojo.html.removeClass(this.domNode, this.highlightClass); + }, + + _startSubmenuTimer: function(){ + this._stopSubmenuTimer(); + + if (this.disabled){ return; } + + var self = this; + var closure = function(){ return function(){ self._openSubmenu(); } }(); + + this.hover_timer = dojo.lang.setTimeout(closure, this.parent.submenuDelay); + }, + + _stopSubmenuTimer: function(){ + if (this.hover_timer){ + dojo.lang.clearTimeout(this.hover_timer); + this.hover_timer = null; + } + }, + + _openSubmenu: function(){ + if (this.disabled){ return; } + + // first close any other open submenu + this.parent.closeSubpopup(); + + var submenu = dojo.widget.getWidgetById(this.submenuId); + if (submenu){ + this.parent._openSubmenu(submenu, this); + } + }, + + _closedSubmenu: function(){ + this.onUnhover(); + }, + + setDisabled: function(/*Boolean*/ value){ + // summary: enable or disable this menu item + this.disabled = value; + + if (this.disabled){ + dojo.html.addClass(this.domNode, this.disabledClass); + }else{ + dojo.html.removeClass(this.domNode, this.disabledClass); + } + }, + + enable: function(){ + // summary: enable this menu item so user can click it + this.setDisabled(false); + }, + + disable: function(){ + // summary: disable this menu item so user can't click it + this.setDisabled(true); + }, + + menuOpen: function(message) { + // summary: callback when menu is opened + // TODO: I don't see anyone calling this menu item + } + +}); + +// summary +// A line between two menu items +dojo.widget.defineWidget( + "dojo.widget.MenuSeparator2", + dojo.widget.HtmlWidget, +{ + templateString: '<tr class="dojoMenuSeparator2"><td colspan=4>' + +'<div class="dojoMenuSeparator2Top"></div>' + +'<div class="dojoMenuSeparator2Bottom"></div>' + +'</td></tr>', + + postCreate: function(){ + dojo.html.disableSelection(this.domNode); + } +}); + +// summary +// A menu bar, listing menu choices horizontally, like the "File" menu in most desktop applications +dojo.widget.defineWidget( + "dojo.widget.MenuBar2", + dojo.widget.PopupMenu2, +{ + menuOverlap: 2, + + templateString: '<div class="dojoMenuBar2" tabIndex="0"><table class="dojoMenuBar2Client"><tr dojoAttachPoint="containerNode"></tr></table></div>', + + close: function(force){ + if(this._highlighted_option){ + this._highlighted_option.onUnhover(); + } + + this.closeSubpopup(force); + }, + + processKey: function(/*Event*/ evt){ + if(evt.ctrlKey || evt.altKey){ return false; } + + if (!dojo.html.hasClass(evt.target,"dojoMenuBar2")) { return false; } + var rval = false; + + switch(evt.key){ + case evt.KEY_DOWN_ARROW: + rval = this._moveToChildMenu(evt); + break; + case evt.KEY_UP_ARROW: + rval = this._moveToParentMenu(evt); + break; + case evt.KEY_RIGHT_ARROW: + rval = this._moveToNext(evt); + break; + case evt.KEY_LEFT_ARROW: + rval = this._moveToPrevious(evt); + break; + default: + rval = dojo.widget.MenuBar2.superclass.processKey.apply(this, arguments); + break; + } + + return rval; + }, + + postCreate: function(){ + dojo.widget.MenuBar2.superclass.postCreate.apply(this, arguments); + dojo.widget.PopupManager.opened(this); + this.isShowingNow = true; + }, + + /* + * override PopupMenu2 to open the submenu below us rather than to our right + */ + _openSubmenu: function(submenu, from_item){ + var fromPos = dojo.html.getAbsolutePosition(from_item.domNode, true); + var ourPos = dojo.html.getAbsolutePosition(this.domNode, true); + var our_h = dojo.html.getBorderBox(this.domNode).height; + var x = fromPos.x; + var y = ourPos.y + our_h - this.menuOverlap; + + submenu.open(x, y, this, from_item.domNode); + + this.currentSubmenuTrigger = from_item; + this.currentSubmenuTrigger.is_open = true; + } +}); + +// summary +// Item in a Menu2Bar +dojo.widget.defineWidget( + "dojo.widget.MenuBarItem2", + dojo.widget.MenuItem2, +{ + templateString: + '<td class="dojoMenuBarItem2" dojoAttachEvent="onMouseOver: onHover; onMouseOut: onUnhover; onClick: _onClick;">' + +'<span>${this.caption}</span>' + +'</td>', + + highlightClass: 'dojoMenuBarItem2Hover', + + setDisabled: function(value){ + this.disabled = value; + if (this.disabled){ + dojo.html.addClass(this.domNode, 'dojoMenuBarItem2Disabled'); + }else{ + dojo.html.removeClass(this.domNode, 'dojoMenuBarItem2Disabled'); + } + } +}); + + +// summary +// Internal class to make contextmenu work in konqueror and opera +dojo.widget.Menu2.OperaAndKonqFixer = new function(){ + var implement = true; + var delfunc = false; + + /** dom event check + * + * make a event and dispatch it and se if it calls function below, + * if it indeed is supported and we dont need to implement our own + */ + + // gets called if we have support for oncontextmenu + if (!dojo.lang.isFunction(dojo.doc().oncontextmenu)){ + dojo.doc().oncontextmenu = function(){ + implement = false; + delfunc = true; + } + } + + if (dojo.doc().createEvent){ // moz, safari has contextmenu event, need to do livecheck on this env. + try { + var e = dojo.doc().createEvent("MouseEvents"); + e.initMouseEvent("contextmenu", 1, 1, dojo.global(), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null); + dojo.doc().dispatchEvent(e); + } catch (e) {/* assume not supported */} + } else { + // IE no need to implement custom contextmenu + implement = false; + } + + // clear this one if it wasn't there before + if (delfunc){ + delete dojo.doc().oncontextmenu; + } + /***** end dom event check *****/ + + + /** + * this fixes a dom node by attaching a custom oncontextmenu function that gets called when apropriate + * @param node a dom node + * + * no returns + */ + this.fixNode = function(node){ + if (implement){ + // attach stub oncontextmenu function + if (!dojo.lang.isFunction(node.oncontextmenu)){ + node.oncontextmenu = function(e){/*stub*/} + } + + // attach control function for oncontextmenu + if (dojo.render.html.opera){ + // opera + // listen to ctrl-click events + node._menufixer_opera = function(e){ + if (e.ctrlKey){ + this.oncontextmenu(e); + } + }; + + dojo.event.connect(node, "onclick", node, "_menufixer_opera"); + + } else { + // konqueror + // rightclick, listen to mousedown events + node._menufixer_konq = function(e){ + if (e.button==2 ){ + e.preventDefault(); // need to prevent browsers menu + this.oncontextmenu(e); + } + }; + + dojo.event.connect(node, "onmousedown", node, "_menufixer_konq"); + } + } + } + + /** + * this cleans up a fixed node, prevent memoryleak? + * @param node node to clean + * + * no returns + */ + this.cleanNode = function(node){ + if (implement){ + // checks needed if we gets a non fixed node + if (node._menufixer_opera){ + dojo.event.disconnect(node, "onclick", node, "_menufixer_opera"); + delete node._menufixer_opera; + } else if(node._menufixer_konq){ + dojo.event.disconnect(node, "onmousedown", node, "_menufixer_konq"); + delete node._menufixer_konq; + } + if (node.oncontextmenu){ + delete node.oncontextmenu; + } + } + } +}; \ No newline at end of file Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Menu2.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Menu2.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Menu2.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/MonthlyCalendar.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/MonthlyCalendar.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/MonthlyCalendar.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/MonthlyCalendar.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,188 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.MonthlyCalendar"); +dojo.require("dojo.date.common"); +dojo.require("dojo.date.format"); +dojo.require("dojo.widget.*"); +dojo.require("dojo.widget.DatePicker"); +dojo.require("dojo.event.*"); +dojo.require("dojo.html.*"); +dojo.require("dojo.experimental"); + +dojo.experimental("dojo.widget.MonthlyCalendar"); + +dojo.widget.defineWidget( + "dojo.widget.MonthlyCalendar", + dojo.widget.DatePicker, + { + dayWidth: 'wide', + + templatePath: dojo.uri.dojoUri("src/widget/templates/MonthlyCalendar.html"), + templateCssPath: dojo.uri.dojoUri("src/widget/templates/MonthlyCalendar.css"), + + initializer: function(){ + this.iCalendars = []; + }, + + /* + cache: function(){ + }, + */ + + addCalendar: function(/* dojo.iCalendar */ cal) { + dojo.debug("Adding Calendar"); + this.iCalendars.push(cal); + dojo.debug("Starting init"); + this.initUI(); + dojo.debug("done init"); + }, + + createDayContents: function(node,mydate) { + dojo.html.removeChildren(node); + node.appendChild(document.createTextNode(mydate.getDate())); + for(var x=0; x<this.iCalendars.length; x++) { + var evts = this.iCalendars[x].getEvents(mydate); + if ((dojo.lang.isArray(evts)) && (evts.length>0)) { + for(var y=0;y<evts.length;y++) { + var el = document.createElement("div"); + dojo.html.addClass(el, "dojoMonthlyCalendarEvent"); + el.appendChild(document.createTextNode(evts[y].summary.value)); + el.width = dojo.html.getContentBox(node).width; + node.appendChild(el); + } + } + } + }, + + initUI: function() { + var dayLabels = dojo.date.getNames('days', this.dayWidth, 'standAlone', this.lang); + var dayLabelNodes = this.dayLabelsRow.getElementsByTagName("td"); + for(var i=0; i<7; i++) { + dayLabelNodes.item(i).innerHTML = dayLabels[i]; + } + + this.selectedIsUsed = false; + this.currentIsUsed = false; + var currentClassName = ""; + var previousDate = new Date(); + var calendarNodes = this.calendarDatesContainerNode.getElementsByTagName("td"); + var currentCalendarNode; + // set hours of date such that there is no chance of rounding error due to + // time change in local time zones + previousDate.setHours(8); + var nextDate = new Date(this.firstSaturday.year, this.firstSaturday.month, this.firstSaturday.date, 8); + var lastDay = new Date(this.firstSaturday.year, this.firstSaturday.month, this.firstSaturday.date + 42, 8); + + if (this.iCalendars.length > 0) { + for (var x=0; x<this.iCalendars.length;x++) { + this.iCalendars[x].preComputeRecurringEvents(lastDay); + } + } + + if(this.firstSaturday.date < 7) { + // this means there are days to show from the previous month + var dayInWeek = 6; + for (var i=this.firstSaturday.date; i>0; i--) { + currentCalendarNode = calendarNodes.item(dayInWeek); + this.createDayContents(currentCalendarNode, nextDate); + + dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current")); + dayInWeek--; + previousDate = nextDate; + nextDate = this.incrementDate(nextDate, false); + } + for(var i=dayInWeek; i>-1; i--) { + currentCalendarNode = calendarNodes.item(i); + + this.createDayContents(currentCalendarNode, nextDate); + + dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "previous")); + previousDate = nextDate; + nextDate = this.incrementDate(nextDate, false); + } + } else { + nextDate.setDate(1); + for(var i=0; i<7; i++) { + currentCalendarNode = calendarNodes.item(i); + this.createDayContents(currentCalendarNode, nextDate); + dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current")); + previousDate = nextDate; + nextDate = this.incrementDate(nextDate, true); + } + } + previousDate.setDate(this.firstSaturday.date); + previousDate.setMonth(this.firstSaturday.month); + previousDate.setFullYear(this.firstSaturday.year); + nextDate = this.incrementDate(previousDate, true); + var count = 7; + currentCalendarNode = calendarNodes.item(count); + while((nextDate.getMonth() == previousDate.getMonth()) && (count<42)) { + this.createDayContents(currentCalendarNode, nextDate); + dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current")); + currentCalendarNode = calendarNodes.item(++count); + previousDate = nextDate; + nextDate = this.incrementDate(nextDate, true); + } + + while(count < 42) { + this.createDayContents(currentCalendarNode, nextDate); + dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "next")); + currentCalendarNode = calendarNodes.item(++count); + previousDate = nextDate; + nextDate = this.incrementDate(nextDate, true); + } + this.setMonthLabel(this.firstSaturday.month); + this.setYearLabels(this.firstSaturday.year); + } + } +); + +dojo.widget.MonthlyCalendar.util= new function() { + + this.toRfcDate = function(jsDate) { + if(!jsDate) { + jsDate = this.today; + } + var year = jsDate.getFullYear(); + var month = jsDate.getMonth() + 1; + if (month < 10) { + month = "0" + month.toString(); + } + var date = jsDate.getDate(); + if (date < 10) { + date = "0" + date.toString(); + } + // because this is a date picker and not a time picker, we treat time + // as zero + return year + "-" + month + "-" + date + "T00:00:00+00:00"; + } + + this.fromRfcDate = function(rfcDate) { + var tempDate = rfcDate.split("-"); + if(tempDate.length < 3) { + return new Date(); + } + // fullYear, month, date + return new Date(parseInt(tempDate[0]), (parseInt(tempDate[1], 10) - 1), parseInt(tempDate[2].substr(0,2), 10)); + } + +//Note: redundant with dojo.widget.DatePicker.util + this.initFirstSaturday = function(month, year) { + if(!month) { + month = this.date.getMonth(); + } + if(!year) { + year = this.date.getFullYear(); + } + var firstOfMonth = new Date(year, month, 1); + return {year: year, month: month, date: 7 - firstOfMonth.getDay()}; + } +} Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/MonthlyCalendar.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/MonthlyCalendar.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/MonthlyCalendar.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PageContainer.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PageContainer.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PageContainer.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PageContainer.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,414 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.PageContainer"); + +dojo.require("dojo.lang.func"); +dojo.require("dojo.widget.*"); +dojo.require("dojo.event.*"); +dojo.require("dojo.html.selection"); + +dojo.widget.defineWidget("dojo.widget.PageContainer", dojo.widget.HtmlWidget, { + // summary + // A container that has multiple children, but shows only + // one child at a time (like looking at the pages in a book one by one). + // + // Publishes topics <widgetId>-addChild, <widgetId>-removeChild, and <widgetId>-selectChild + // + // Can be base class for container, Wizard, Show, etc. + + isContainer: true, + + // doLayout: Boolean + // if true, change the size of my currently displayed child to match my size + doLayout: true, + + templateString: "<div dojoAttachPoint='containerNode'></div>", + + // selectedChild: String + // id of the currently shown page + selectedChild: "", + + fillInTemplate: function(args, frag) { + // Copy style info from input node to output node + var source = this.getFragNodeRef(frag); + dojo.html.copyStyle(this.domNode, source); + dojo.widget.PageContainer.superclass.fillInTemplate.apply(this, arguments); + }, + + postCreate: function(args, frag) { + if(this.children.length){ + // Setup each page panel + dojo.lang.forEach(this.children, this._setupChild, this); + + // Figure out which child to initially display + var initialChild; + if(this.selectedChild){ + this.selectChild(this.selectedChild); + }else{ + for(var i=0; i<this.children.length; i++){ + if(this.children[i].selected){ + this.selectChild(this.children[i]); + break; + } + } + if(!this.selectedChildWidget){ + this.selectChild(this.children[0]); + } + } + } + }, + + addChild: function(child){ + dojo.widget.PageContainer.superclass.addChild.apply(this, arguments); + this._setupChild(child); + + // in case the tab labels have overflowed from one line to two lines + this.onResized(); + + // if this is the first child, then select it + if(!this.selectedChildWidget){ + this.selectChild(child); + } + }, + + _setupChild: function(/*Widget*/ page){ + // Summary: Add the given child to this page container + + page.hide(); + + // since we are setting the width/height of the child elements, they need + // to be position:relative, or IE has problems (See bug #2033) + page.domNode.style.position="relative"; + + // publish the addChild event for panes added via addChild(), and the original panes too + dojo.event.topic.publish(this.widgetId+"-addChild", page); + }, + + removeChild: function(/*Widget*/ page){ + dojo.widget.PageContainer.superclass.removeChild.apply(this, arguments); + + // If we are being destroyed than don't run the code below (to select another page), because we are deleting + // every page one by one + if(this._beingDestroyed){ return; } + + // this will notify any tablists to remove a button; do this first because it may affect sizing + dojo.event.topic.publish(this.widgetId+"-removeChild", page); + + // in case the tab labels now take up one line instead of two lines + this.onResized(); + + if (this.selectedChildWidget === page) { + this.selectedChildWidget = undefined; + if (this.children.length > 0) { + this.selectChild(this.children[0], true); + } + } + }, + + selectChild: function(/*Widget*/ page, /*Widget*/ callingWidget){ + // summary + // Show the given widget (which must be one of my children) + page = dojo.widget.byId(page); + this.correspondingPageButton = callingWidget; + + // Deselect old page and select new one + if(this.selectedChildWidget){ + this._hideChild(this.selectedChildWidget); + } + this.selectedChildWidget = page; + this.selectedChild = page.widgetId; + this._showChild(page); + page.isFirstChild = (page == this.children[0]); + page.isLastChild = (page == this.children[this.children.length-1]); + dojo.event.topic.publish(this.widgetId+"-selectChild", page); + }, + + forward: function(){ + // Summary: advance to next page + var index = dojo.lang.find(this.children, this.selectedChildWidget); + this.selectChild(this.children[index+1]); + }, + + back: function(){ + // Summary: go back to previous page + var index = dojo.lang.find(this.children, this.selectedChildWidget); + this.selectChild(this.children[index-1]); + }, + + onResized: function(){ + // Summary: called when any page is shown, to make it fit the container correctly + if(this.doLayout && this.selectedChildWidget){ + with(this.selectedChildWidget.domNode.style){ + top = dojo.html.getPixelValue(this.containerNode, "padding-top", true); + left = dojo.html.getPixelValue(this.containerNode, "padding-left", true); + } + var content = dojo.html.getContentBox(this.containerNode); + this.selectedChildWidget.resizeTo(content.width, content.height); + } + }, + + _showChild: function(/*Widget*/ page) { + // size the current page (in case this is the first time it's being shown, or I have been resized) + if(this.doLayout){ + var content = dojo.html.getContentBox(this.containerNode); + page.resizeTo(content.width, content.height); + } + + page.selected=true; + page.show(); + }, + + _hideChild: function(/*Widget*/ page) { + page.selected=false; + page.hide(); + }, + + closeChild: function(/*Widget*/ page) { + // summary + // callback when user clicks the [X] to remove a page + // if onClose() returns true then remove and destroy the childd + var remove = page.onClose(this, page); + if(remove) { + this.removeChild(page); + // makes sure we can clean up executeScripts in ContentPane onUnLoad + page.destroy(); + } + }, + + destroy: function(){ + this._beingDestroyed = true; + dojo.event.topic.destroy(this.widgetId+"-addChild"); + dojo.event.topic.destroy(this.widgetId+"-removeChild"); + dojo.event.topic.destroy(this.widgetId+"-selectChild"); + dojo.widget.PageContainer.superclass.destroy.apply(this, arguments); + } +}); + + +dojo.widget.defineWidget( + "dojo.widget.PageController", + dojo.widget.HtmlWidget, + { + // summary + // Set of buttons to select a page in a page list. + // Monitors the specified PageContaine, and whenever a page is + // added, deleted, or selected, updates itself accordingly. + + templateString: "<span wairole='tablist' dojoAttachEvent='onKey'></span>", + isContainer: true, + + // containerId: String + // the id of the page container that I point to + containerId: "", + + // buttonWidget: String + // the name of the button widget to create to correspond to each page + buttonWidget: "PageButton", + + // class: String + // Class name to apply to the top dom node + "class": "dojoPageController", + + fillInTemplate: function() { + dojo.html.addClass(this.domNode, this["class"]); // "class" is a reserved word in JS + dojo.widget.wai.setAttr(this.domNode, "waiRole", "role", "tablist"); + }, + + postCreate: function(){ + this.pane2button = {}; // mapping from panes to buttons + + // If children have already been added to the page container then create buttons for them + var container = dojo.widget.byId(this.containerId); + if(container){ + dojo.lang.forEach(container.children, this.onAddChild, this); + } + + dojo.event.topic.subscribe(this.containerId+"-addChild", this, "onAddChild"); + dojo.event.topic.subscribe(this.containerId+"-removeChild", this, "onRemoveChild"); + dojo.event.topic.subscribe(this.containerId+"-selectChild", this, "onSelectChild"); + }, + + destroy: function(){ + dojo.event.topic.unsubscribe(this.containerId+"-addChild", this, "onAddChild"); + dojo.event.topic.unsubscribe(this.containerId+"-removeChild", this, "onRemoveChild"); + dojo.event.topic.unsubscribe(this.containerId+"-selectChild", this, "onSelectChild"); + dojo.widget.PageController.superclass.destroy.apply(this, arguments); + }, + + onAddChild: function(/*Widget*/ page){ + // summary + // Called whenever a page is added to the container. + // Create button corresponding to the page. + var button = dojo.widget.createWidget(this.buttonWidget, + { + label: page.label, + closeButton: page.closable + }); + this.addChild(button); + this.domNode.appendChild(button.domNode); + this.pane2button[page]=button; + page.controlButton = button; // this value might be overwritten if two tabs point to same container + + var _this = this; + dojo.event.connect(button, "onClick", function(){ _this.onButtonClick(page); }); + dojo.event.connect(button, "onCloseButtonClick", function(){ _this.onCloseButtonClick(page); }); + }, + + onRemoveChild: function(/*Widget*/ page){ + // summary + // Called whenever a page is removed from the container. + // Remove the button corresponding to the page. + if(this._currentChild == page){ this._currentChild = null; } + var button = this.pane2button[page]; + if(button){ + button.destroy(); + } + this.pane2button[page] = null; + }, + + onSelectChild: function(/*Widget*/ page){ + // Summary + // Called when a page has been selected in the PageContainer, either by me or by another PageController + if(this._currentChild){ + var oldButton=this.pane2button[this._currentChild]; + oldButton.clearSelected(); + } + var newButton=this.pane2button[page]; + newButton.setSelected(); + this._currentChild=page; + }, + + onButtonClick: function(/*Widget*/ page){ + // summary + // Called whenever one of my child buttons is pressed in an attempt to select a page + var container = dojo.widget.byId(this.containerId); // TODO: do this via topics? + container.selectChild(page, false, this); + }, + + onCloseButtonClick: function(/*Widget*/ page){ + // summary + // Called whenever one of my child buttons [X] is pressed in an attempt to close a page + var container = dojo.widget.byId(this.containerId); + container.closeChild(page); + }, + + onKey: function(/*Event*/ evt){ + // summary: + // Handle keystrokes on the page list, for advancing to next/previous button + + if( (evt.keyCode == evt.KEY_RIGHT_ARROW)|| + (evt.keyCode == evt.KEY_LEFT_ARROW) ){ + var current = 0; + var next = null; // the next button to focus on + + // find currently focused button in children array + var current = dojo.lang.find(this.children, this.pane2button[this._currentChild]); + + // pick next button to focus on + if(evt.keyCode == evt.KEY_RIGHT_ARROW){ + next = this.children[ (current+1) % this.children.length ]; + }else{ // is LEFT_ARROW + next = this.children[ (current+ (this.children.length-1)) % this.children.length ]; + } + + dojo.event.browser.stopEvent(evt); + next.onClick(); + } + } + } +); + +dojo.widget.defineWidget("dojo.widget.PageButton", dojo.widget.HtmlWidget, +{ + // summary + // Internal widget used by PageList. + // The button-like or tab-like object you click to select or delete a page + + templateString: "<span class='item'>" + + "<span dojoAttachEvent='onClick' dojoAttachPoint='titleNode' class='selectButton'>${this.label}</span>" + + "<span dojoAttachEvent='onClick:onCloseButtonClick' class='closeButton'>[X]</span>" + + "</span>", + + // label: String + // Name to print on the button + label: "foo", + + // closeButton: Boolean + // true iff we should also print a close icon to destroy corresponding page + closeButton: false, + + onClick: function(){ + // summary + // Basically this is the attach point PageController listens to, to select the page + this.focus(); + }, + + onCloseButtonMouseOver: function(){ + // summary + // The close button changes color a bit when you mouse over + dojo.html.addClass(this.closeButtonNode, "closeHover"); + }, + + onCloseButtonMouseOut: function(){ + // summary + // Revert close button to normal color on mouse out + dojo.html.removeClass(this.closeButtonNode, "closeHover"); + }, + + onCloseButtonClick: function(/*Event*/ evt){ + // summary + // Handle clicking the close button for this tab + }, + + setSelected: function(){ + // summary + // This is run whenever the page corresponding to this button has been selected + dojo.html.addClass(this.domNode, "current"); + this.titleNode.setAttribute("tabIndex","0"); + }, + + clearSelected: function(){ + // summary + // This function is run whenever the page corresponding to this button has been deselected (and another page has been shown) + dojo.html.removeClass(this.domNode, "current"); + this.titleNode.setAttribute("tabIndex","-1"); + }, + + focus: function(){ + // summary + // This will focus on the this button (for accessibility you need to do this when the button is selected) + if(this.titleNode.focus){ // mozilla 1.7 doesn't have focus() func + this.titleNode.focus(); + } + } +}); + +// These arguments can be specified for the children of a PageContainer. +// Since any widget can be specified as a PageContainer child, mix them +// into the base widget class. (This is a hack, but it's effective.) +dojo.lang.extend(dojo.widget.Widget, { + // label: String + // Label or title of this widget. Used by TabContainer to the name the tab, etc. + label: "", + + // selected: Boolean + // Is this child currently selected? + selected: false, + + // closable: Boolean + // True if user can close (destroy) this child, such as (for example) clicking the X on the tab. + closable: false, // true if user can close this tab pane + + onClose: function(){ + // summary: Callback if someone tries to close the child, child will be closed if func returns true + return true; + } +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PageContainer.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PageContainer.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PageContainer.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Parse.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Parse.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Parse.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Parse.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,339 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +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(/*Object*/fragment){ + this.propertySetsList = []; + this.fragment = fragment; + + this.createComponents = function(/*Object*/frag, /*Object*/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; + var ret; + if(djTags[ltn]){ + built = true; + 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? + // ret = djTags[ltn](frag, this, parentComp, frag.index); + 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 pain sometimes + } + // if there's a sub-frag, build widgets from that too + if(!built){ + comps = comps.concat(this.createSubComponents(frag, parentComp)); + } + return comps; // Array + } + + this.createSubComponents = function(/*Object*/fragment, /*Object*/parentComp){ + // summary: recurses over a raw JavaScript object structure, + // and calls the corresponding handler for its normalized tagName if it exists + + var frag, comps = []; + for(var item in fragment){ + frag = fragment[item]; + if(frag && typeof frag == "object" + &&(frag!=fragment.nodeRef) + &&(frag!=fragment.tagName) + &&(!dojo.dom.isNode(frag))){// needed in IE when we have event.connected to the domNode + comps = comps.concat(this.createComponents(frag, parentComp)); + } + } + return comps; // Array + } + + this.parsePropertySets = function(/*Object*/fragment){ + // summary: checks the top level of a raw JavaScript object + // structure for any propertySets. It stores an array of references to + // propertySets that it finds. + 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; + */ + } + + this.parseProperties = function(/*Object*/fragment){ + // summary: parseProperties checks a raw JavaScript object structure for + // properties, and returns a hash of properties that it finds. + 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{ + var frag = fragment[item]; + if(frag.tagName && dojo.widget.tags[frag.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(frag[0] && frag[0].value!="" && frag[0].value!=null){ + try{ + // FIXME: need to allow more than one provider + if(item.toLowerCase() == "dataprovider"){ + var _this = this; + this.getDataProvider(_this, frag[0].value); + properties.dataProvider = this.dataProvider; + } + properties[item] = frag[0].value; + var nestedProperties = this.parseProperties(frag); + // 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; // Object + } + + this.getDataProvider = function(/*Object*/objRef, /*String*/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){ + // summary: returns the propertySet that matches the provided id + for(var x = 0; x < this.propertySetsList.length; x++){ + if(propertySetId == this.propertySetsList[x]["id"][0].value){ + return this.propertySetsList[x]; + } + } + return ""; // String + } + + //FIXME: doesn't use the componentType param? + this.getPropertySetsByType = function(componentType){ + // summary: returns the propertySet(s) that match(es) the + // provided componentClass + + var propertySets = []; + for(var x=0; x < this.propertySetsList.length; x++){ + var cpl = this.propertySetsList[x]; + var cpcc = cpl.componentClass || cpl.componentType || null; //FIXME: is componentType supposed to be an indirect reference? + var propertySetId = this.propertySetsList[x]["id"][0].value; + if(cpcc && (propertySetId == cpcc[0].value)){ + propertySets.push(cpl); + } + } + return propertySets; // Array + } + + this.getPropertySets = function(/*Object*/fragment){ + // summary: returns the propertySet for a given component 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); // Array + } + + this.createComponentFromScript = function(/*Node*/nodeRef, /*String*/componentName, /*Object*/properties, /*String?*/ns){ + // summary: + // nodeRef: the node to be replaced... in the future, we might want to add + // an alternative way to specify an insertion point + // componentName: the expected dojo widget name, i.e. Button of ContextMenu + // properties: an object of name value pairs + // ns: the namespace of the widget. Defaults to "dojo" + + 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)]; // Array + } + return [dojo.widget.buildWidgetFromParseTree(ltn, properties, this, null, null, properties)]; // Array + } +} + +dojo.widget._parser_collection = {"dojo": new dojo.widget.Parse() }; + +dojo.widget.getParser = function(/*String?*/name){ + if(!name){ name = "dojo"; } + if(!this._parser_collection[name]){ + this._parser_collection[name] = new dojo.widget.Parse(); + } + return this._parser_collection[name]; +} + +dojo.widget.createWidget = function(/*String*/name, /*String*/props, /*Node*/refNode, /*String*/position){ + // summary: Creates widget + // name: The name of the widget to create with optional namespace prefix, + // e.g."ns:widget", namespace defaults to "dojo". + // props: Key-Value pairs of properties of the widget + // 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 + // position: The position to insert this widget's node relative to the + // refNode argument + + 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 && widgetArray[0].domNode.parentNode){ + widgetArray[0].domNode.parentNode.removeChild(widgetArray[0].domNode); + } + }catch(e){ + /* squelch for Safari */ + dojo.debug(e); + } + return widgetArray[0]; // Widget +} Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Parse.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Parse.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Parse.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PopupContainer.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PopupContainer.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PopupContainer.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/PopupContainer.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,476 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +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"); + +dojo.declare( + "dojo.widget.PopupContainerBase", + null, + function(){ + this.queueOnAnimationFinish = []; + }, +{ + // 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 + + isContainer: true, + templateString: '<div dojoAttachPoint="containerNode" style="display:none;position:absolute;" class="dojoPopupContainer" ></div>', + + // isShowingNow: Boolean: whether this popup is shown + isShowingNow: false, + + // currentSubpopup: Widget: the shown sub popup if any + currentSubpopup: null, + + // beginZIndex: Integer: the minimal popup zIndex + beginZIndex: 1000, + + // parentPopup: Widget: parent popup widget + parentPopup: null, + + // parent: Widget: the widget that caused me to be displayed; the logical parent. + parent: null, + + // popupIndex: Integer: level of sub popup + popupIndex: 0, + + // aroundBox: 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, + + // openedForWindow: 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; } + + // 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.animationInProgre |
Free forum by Nabble | Edit this page |