Author: jmorliaguet Date: Sun Dec 25 16:41:04 2005 New Revision: 2075 Added: cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js (contents, props changed) Removed: cpsskins/branches/jmo-perspectives/ui/framework/pdlib2.js Log:
- renamed pdlib2.js as cpsskins.js (there's no code left from the original pdlib) - merged utils.js into cpsskins.js (added an 'Identifiable' API to manipulate DOM objects that have an 'id' attribute) - moved the tooltip code to cpsskins.js Added: cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js ============================================================================== --- (empty file) +++ cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js Sun Dec 25 16:41:04 2005 @@ -0,0 +1,274 @@ +/* + + Copyright (c) 2005 Nuxeo and Contributors. + All Rights Reserved. + + This software is subject to the provisions of the Zope Public License, + Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED + WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS + FOR A PARTICULAR PURPOSE. + + CPSSkins library (Identifiable elements, Contextual menus, tooltips) + + Author: Jean-Marc Orliaguet <[EMAIL PROTECTED]> + +*/ + +var CPSSkins = { + Version: '0.1' +} + +// Identifiable DOM elements. + +if (!window.Identifiable) var Identifiable = new Object(); + +Object.extend(Identifiable, { + + isIdentifiable: function(element) { + var node = $(element); + if (node.nodeType == 1 && node.getAttribute("id")) { + return true; + } else { + return false; + } + }, + + getOrder: function(element) { + var order = 0; + var node = $(element); + var nodes = node.parentNode.childNodes; + for (var i=0;i<nodes.length;i++) { + var n = nodes[i]; + if (n == node) return order; + if (this.isIdentifiable(n)) { order += 1; } + } + return order; + }, + + getNext: function(element) { + var node = $(element); + while (node) { + node = node.nextSibling; + if (!node) return null; + if (this.isIdentifiable(node)) { return node; } + } + return null; + }, + + getPrevious: function(element) { + var node = $(element); + while (node) { + node = node.previousSibling; + if (!node) return null; + if (this.isIdentifiable(node)) { return node; } + } + return null; + }, + + getParent: function(element) { + var node = $(element); + while (node) { + node = node.parentNode; + if (!node) return null; + if (this.isIdentifiable(node)) { return node; } + } + return null; + }, + + getIdentifiable: function(element) { + var node = $(element); + if (this.isIdentifiable(node)) { return node; } + return this.getParent(node); + }, + + isEmpty: function(element) { + var node = $(element); + var nodes = node.getElementsByTagName('*'); + for (var i=0;i<nodes.length;i++) { + if (this.isIdentifiable(nodes[i])) { return false; } + } + return true; + } + +}); + + +// Contextual menu + +CPSSkins.ContextualMenu = Class.create(); +CPSSkins.ContextualMenu.prototype = { + + initialize: function(menu, area, actions, options) { + this.menu = menu; + this.menunode = $(menu); + this.actions = actions; + this.setOptions(options || {}); + + this.selected = null; + this.submenunode = null; + + this.browseEvent = this.browse.bindAsEventListener(this); + this.clickEvent = this.click.bindAsEventListener(this); + + var area = area || document; + Event.observe(area, 'click', this.clickEvent); + }, + + setOptions: function(options) { + this.options = Object.extend({ + width: 120, + maxwidth: 250 + }, options || {}); + }, + + click: function(e) { + var node = Event.element(e); + if (this.active) { + this.call(node); + this.hide(); + } else { + this.selected = this.getIdentifiableElement(node); + Event.observe(this.menunode, 'mouseover', this.browseEvent); + this.show(e); + } + }, + + browse: function(e) { + node = Event.element(e); + if (Element.hasClassName(node, 'submenu')) { + this.submenunode = document.getElementsByClassName('items', node)[0]; + var xpos = this.options.width -5; + if (!document.all) + xpos += parseInt(this.menunode.style.left); + Element.setStyle(this.submenunode, 'left', xpos + 'px'); + Element.show(this.submenunode); + } + }, + + call: function(item) { + if (!item) { return; } + var action = item.getAttribute('id'); + if (!action) { return; } + var confirm = item.getAttribute("confirm"); + if (confirm) { + if (!window.confirm(confirm)) { return; } + } + var choice = item.getAttribute('choice'); + var handler = this.actions[action]['handler']; + if (handler) { handler(this.selected, choice); } + this.hide(); + }, + + hide: function() { + Element.hide(this.menunode); + Event.stopObserving(this.menunode, 'mouseover', this.browseEvent); + this.active = false; + }, + + show: function(e) { + var menunode = this.menunode; + var dimensions = Element.getDimensions(menunode); + var menuWidth = dimensions['width']; + var menuHeight = dimensions['height']; + var page_w = window.innerWidth || document.body.clientWidth; + var page_h = window.innerHeight || document.body.clientHeight; + var x = Event.pointerX(e); + var y = Event.pointerY(e); + + var menuX = (x + menuWidth > page_w) ? x - menuWidth -1 : x + 1; + var menuY = (y + menuHeight > page_h) ? y - menuHeight -1 : y + 1; + menunode.style.left = menuX + 'px'; + menunode.style.top = menuY + 'px'; + + var width = this.options.width; + if (menuWidth >= this.options.maxwidth) { + width = this.options.maxwidth; + } + menunode.style.width = width + 'px'; + + this.active = true; + this.filterMenuItems(); + Element.show(this.menunode); + }, + + filterMenuItems: function(node) { + var node = node || this.menunode; + var selected = this.selected; + if (!selected) { return; } + + if (!node.getAttribute) { return; } + var actionid = node.getAttribute("id"); + if (actionid && actionid != this.menu) { + var action_info = this.actions[actionid]; + + var visible = true; + var visibility = action_info['visibility']; + if (visibility) { + visible = (selected.getAttribute(visibility) == 1); + } + + if (visible) { + var choices = action_info['choices']; + if (choices) { + var items = selected.getAttribute(choices); + if (items) { + var html = '<div class="items">'; + var items = items.split(','); + for (var i=0; i<items.length; i++) { + var s = items[i].split(':'); + html += '<a href="#"' + + ' choice="' + s[0] + '">' + + (s[1] ? s[1] : s[0]) + '</a>'; + } + html += '</div>'; + new Insertion.Bottom(actionid, html); + } + } + Element.show(node); + } else { + Element.hide(node); + } + } + + var childnodes = node.childNodes; + for (var i = 0; i < childnodes.length; i++) + this.filterMenuItems(childnodes[i]); + } +}; + +// Tooltip +CPSSkins.Tooltip = Class.create(); +CPSSkins.Tooltip.prototype = { + + initialize: function(tooltip, area) { + this.tooltip = tooltip; + this.node = $(tooltip); + + this.showEvent = this.show.bindAsEventListener(this); + this.hideEvent = this.hide.bindAsEventListener(this); + + var area = area || document; + Event.observe(area, 'mouseover', this.showEvent); + Event.observe(area, 'mouseout', this.hideEvent); + }, + + show: function(e) { + var element = Event.element(e); + var hint = element.getAttribute('hint'); + if (!hint) { return; } + var node = this.node; + node.innerHTML = hint; + node.style.top = Event.pointerY(e) + 20 + 'px'; + node.style.left = Event.pointerX(e) + 'px'; + Element.show(node); + this.active = true; + }, + + hide: function(e) { + Element.hide(this.node); + this.active = false; + } +}; + -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins