r840 - branches/experimental/ui/widget-auto-getters

r840 - branches/experimental/ui/widget-auto-getters

Author: scott.gonzalez
Date: Sun Oct 26 19:22:34 2008
New Revision: 840
Added:
branches/experimental/ui/widget-auto-getters/
branches/experimental/ui/widget-auto-getters/ui.core.js (contents,
props changed)
branches/experimental/ui/widget-auto-getters/ui.dialog.js (contents,
props changed)
Log:
Experimental change to widget factory to prevent the need to predefine
getters.
Added: branches/experimental/ui/widget-auto-getters/ui.core.js
==============================================================================
--- (empty file)
+++ branches/experimental/ui/widget-auto-getters/ui.core.js    Sun Oct 26
19:22:34 2008
@@ -0,0 +1,466 @@
+/*
+ * jQuery UI @VERSION
+ *
+ * Copyright (c) 2008 Paul Bakaus (ui.jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+;(function($) {
+
+/** jQuery core modifications and additions **/
+
+var _remove = $.fn.remove;
+$.fn.remove = function() {
+    // Safari has a native remove event which actually removes DOM elements,
+    // so we have to use triggerHandler instead of trigger (#3037).
+    $("*", this).add(this).each(function() {
+        $(this).triggerHandler("remove");
+    });
+    return _remove.apply(this, arguments );
+};
+
+function isVisible(element) {
+    function checkStyles(element) {
+        var style = element.style;
+        return (style.display != 'none' && style.visibility != 'hidden');
+    }
+    
+    var visible = checkStyles(element);
+    
+    (visible && $.each($.dir(element, 'parentNode'), function() {
+        return (visible = checkStyles(this));
+    }));
+    
+    return visible;
+}
+
+$.extend($.expr[':'], {
+    data: function(a, i, m) {
+        return $.data(a, m[3]);
+    },
+    
+    // TODO: add support for object, area
+    tabbable: function(a, i, m) {
+        var nodeName = a.nodeName.toLowerCase();
+        
+        return (
+            // in tab order
+            a.tabIndex >= 0 &&
+            
+            ( // filter node types that participate in the tab order
+                
+                // anchor tag
+                ('a' == nodeName && a.href) ||
+                
+                // enabled form element
+                (/input|select|textarea|button/.test(nodeName) &&
+                    'hidden' != a.type && !a.disabled)
+            ) &&
+            
+            // visible on page
+            isVisible(a)
+        );
+    }
+});
+
+$.keyCode = {
+    BACKSPACE: 8,
+    CAPS_LOCK: 20,
+    COMMA: 188,
+    CONTROL: 17,
+    DELETE: 46,
+    DOWN: 40,
+    END: 35,
+    ENTER: 13,
+    ESCAPE: 27,
+    HOME: 36,
+    INSERT: 45,
+    LEFT: 37,
+    NUMPAD_ADD: 107,
+    NUMPAD_DECIMAL: 110,
+    NUMPAD_DIVIDE: 111,
+    NUMPAD_ENTER: 108,
+    NUMPAD_MULTIPLY: 106,
+    NUMPAD_SUBTRACT: 109,
+    PAGE_DOWN: 34,
+    PAGE_UP: 33,
+    PERIOD: 190,
+    RIGHT: 39,
+    SHIFT: 16,
+    SPACE: 32,
+    TAB: 9,
+    UP: 38
+};
+
+// WAI-ARIA Semantics
+var isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
+$.fn.extend({
+    ariaRole: function(role) {
+        return (role !== undefined
+            
+            // setter
+            ? this.attr("role", isFF2 ? "wairole:" + role : role)
+            
+            // getter
+            : (this.attr("role") || "").replace(/^wairole:/, ""));
+    },
+    
+    ariaState: function(state, value) {
+        return (value !== undefined
+            
+            // setter
+            ? this.each(function(i, el) {
+                (isFF2
+                    ? el.setAttributeNS("http://www.w3.org/2005/07/aaa",
+                        "aaa:" + state, value)
+                    : $(el).attr("aria-" + state, value));
+            })
+            
+            // getter
+            : this.attr(isFF2 ? "aaa:" + state : "aria-" + state));
+    }
+});
+
+// $.widget is a factory to create jQuery plugins
+// taking some boilerplate code out of the plugin code
+// created by Scott González and Jörn Zaefferer
+function getter(namespace, plugin, method, args) {
+    function getMethods(type) {
+        var methods = $[namespace][plugin][type] || [];
+        return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
+    }
+    
+    var methods = getMethods('getter');
+    if (args.length == 1 && typeof args[0] == 'string') {
+        methods = methods.concat(getMethods('getterSetter'));
+    }
+    return ($.inArray(method, methods) != -1);
+}
+
+$.widget = function(name, prototype) {
+    var namespace = name.split(".")[0];
+    name = name.split(".")[1];
+    
+    // create plugin method
+    $.fn[name] = function(options) {
+        var isMethodCall = (typeof options == 'string'),
+            args = Array.prototype.slice.call(arguments, 1),
+            returnValue = this;
+        
+        // prevent calls to internal methods
+        if (isMethodCall && options.substring(0, 1) == '_') {
+            return returnValue;
+        }
+        
+        (isMethodCall
+            ? this.each(function() {
+                var instance = $.data(this, name),
+                    methodValue = (instance && $.isFunction(instance[options])
+                        ? instance[options].apply(instance, args)
+                        : instance);
+                if (methodValue !== instance) {
+                    returnValue = methodValue;
+                    return false;
+                }
+            })
+            : this.each(function() {
+                ($.data(this, name) ||
+                    $.data(this, name, new $[namespace][name](this, options)));
+            }));
+        
+        return returnValue;
+    };
+    
+    // create widget constructor
+    $[namespace] = $[namespace] || {};
+    $[namespace][name] = function(element, options) {
+        var self = this;
+        
+        this.widgetName = name;
+        this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
+        this.widgetBaseClass = namespace + '-' + name;
+        
+        this.options = $.extend({},
+            $.widget.defaults,
+            $[namespace][name].defaults,
+            $.metadata && $.metadata.get(element)[name],
+            options);
+        
+        this.element = $(element)
+            .bind('setData.' + name, function(e, key, value) {
+                return self._setData(key, value);
+            })
+            .bind('getData.' + name, function(e, key) {
+                return self._getData(key);
+            })
+            .bind('remove', function() {
+                return self.destroy();
+            });
+        
+        this._init();
+    };
+    
+    // add widget prototype
+    $[namespace][name].prototype = $.extend({}, $.widget.prototype,
prototype);
+};
+
+$.widget.prototype = {
+    _init: function() {},
+    destroy: function() {
+        this.element.removeData(this.widgetName);
+    },
+    
+    option: function(key, value) {
+        var options = key,
+            self = this;
+        
+        if (typeof key == "string") {
+            if (value === undefined) {
+                return this._getData(key);
+            }
+            options = {};
+            options[key] = value;
+        }
+        
+        $.each(options, function(key, value) {
+            self._setData(key, value);
+        });
+    },
+    _getData: function(key) {
+        return this.options[key];
+    },
+    _setData: function(key, value) {
+        this.options[key] = value;
+        
+        if (key == 'disabled') {
+            this.element[value ? 'addClass' : 'removeClass'](
+                this.widgetBaseClass + '-disabled');
+        }
+    },
+    
+    enable: function() {
+        this._setData('disabled', false);
+    },
+    disable: function() {
+        this._setData('disabled', true);
+    },
+    
+    _trigger: function(type, e, data) {
+        var eventName = (type == this.widgetEventPrefix
+            ? type : this.widgetEventPrefix + type);
+        e = e || $.event.fix({ type: eventName, target: this.element[0] });
+        return this.element.triggerHandler(eventName, [e, data],
this.options[type]);
+    }
+};
+
+$.widget.defaults = {
+    disabled: false
+};
+
+
+/** jQuery UI core **/
+
+$.ui = {
+    version: "@VERSION",
+    // $.ui.plugin is deprecated. Use the proxy pattern instead.
+    plugin: {
+        add: function(module, option, set) {
+            var proto = $.ui[module].prototype;
+            for(var i in set) {
+                proto.plugins[i] = proto.plugins[i] || [];
+                proto.plugins[i].push([option, set[i]]);
+            }
+        },
+        call: function(instance, name, args) {
+            var set = instance.plugins[name];
+            if(!set) { return; }
+            
+            for (var i = 0; i < set.length; i++) {
+                if (instance.options[set[i][0]]) {
+                    set[i][1].apply(instance.element, args);
+                }
+            }
+        }    
+    },
+    cssCache: {},
+    css: function(name) {
+        if ($.ui.cssCache[name]) { return $.ui.cssCache[name]; }
+        var tmp = $('<div
class="ui-gen">').addClass(name).css({position:'absolute', top:'-5000px',
left:'-5000px', display:'block'}).appendTo('body');
+        
+        //if (!$.browser.safari)
+            //tmp.appendTo('body');
+        
+        //Opera and Safari set width and height to 0px instead of auto
+        //Safari returns rgba(0,0,0,0) when bgcolor is not set
+        $.ui.cssCache[name] = !!(
+            (!(/auto|default/).test(tmp.css('cursor')) ||
(/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) ||
+            !(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0,
0, 0, 0\)/).test(tmp.css('backgroundColor')))
+        );
+        try { $('body').get(0).removeChild(tmp.get(0));    } catch(e){}
+        return $.ui.cssCache[name];
+    },
+    disableSelection: function(el) {
+        return $(el)
+            .attr('unselectable', 'on')
+            .css('MozUserSelect', 'none')
+            .bind('selectstart.ui', function() { return false; });
+    },
+    enableSelection: function(el) {
+        return $(el)
+            .attr('unselectable', 'off')
+            .css('MozUserSelect', '')
+            .unbind('selectstart.ui');
+    },
+    hasScroll: function(e, a) {
+        
+        //If overflow is hidden, the element might have extra content, but the
user wants to hide it
+        if ($(e).css('overflow') == 'hidden') { return false; }
+        
+        var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
+            has = false;
+        
+        if (e[scroll] > 0) { return true; }
+        
+        // TODO: determine which cases actually cause this to happen
+        // if the element doesn't have the scroll set, see if it's possible to
+        // set the scroll
+        e[scroll] = 1;
+        has = (e[scroll] > 0);
+        e[scroll] = 0;
+        return has;
+    }
+};
+
+
+/** Mouse Interaction Plugin **/
+
+$.ui.mouse = {
+    _mouseInit: function() {
+        var self = this;
+    
+        this.element.bind('mousedown.'+this.widgetName, function(e) {
+            return self._mouseDown(e);
+        });
+        
+        // Prevent text selection in IE
+        if ($.browser.msie) {
+            this._mouseUnselectable = this.element.attr('unselectable');
+            this.element.attr('unselectable', 'on');
+        }
+        
+        this.started = false;
+    },
+    
+    // TODO: make sure destroying one instance of mouse doesn't mess with
+    // other instances of mouse
+    _mouseDestroy: function() {
+        this.element.unbind('.'+this.widgetName);
+        
+        // Restore text selection in IE
+        ($.browser.msie
+            && this.element.attr('unselectable', this._mouseUnselectable));
+    },
+    
+    _mouseDown: function(e) {
+        // we may have missed mouseup (out of window)
+        (this._mouseStarted && this._mouseUp(e));
+        
+        this._mouseDownEvent = e;
+        
+        var self = this,
+            btnIsLeft = (e.which == 1),
+            elIsCancel = (typeof this.options.cancel == "string" ?
$(e.target).parents().add(e.target).filter(this.options.cancel).length :
false);
+        if (!btnIsLeft || elIsCancel || !this._mouseCapture(e)) {
+            return true;
+        }
+        
+        this.mouseDelayMet = !this.options.delay;
+        if (!this.mouseDelayMet) {
+            this._mouseDelayTimer = setTimeout(function() {
+                self.mouseDelayMet = true;
+            }, this.options.delay);
+        }
+        
+        if (this._mouseDistanceMet(e) && this._mouseDelayMet(e)) {
+            this._mouseStarted = (this._mouseStart(e) !== false);
+            if (!this._mouseStarted) {
+                e.preventDefault();
+                return true;
+            }
+        }
+        
+        // these delegates are required to keep context
+        this._mouseMoveDelegate = function(e) {
+            return self._mouseMove(e);
+        };
+        this._mouseUpDelegate = function(e) {
+            return self._mouseUp(e);
+        };
+        $(document)
+            .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+            .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+        
+        return false;
+    },
+    
+    _mouseMove: function(e) {
+        // IE mouseup check - mouseup happened when mouse was out of window
+        if ($.browser.msie && !e.button) {
+            return this._mouseUp(e);
+        }
+        
+        if (this._mouseStarted) {
+            this._mouseDrag(e);
+            return false;
+        }
+        
+        if (this._mouseDistanceMet(e) && this._mouseDelayMet(e)) {
+            this._mouseStarted =
+                (this._mouseStart(this._mouseDownEvent, e) !== false);
+            (this._mouseStarted ? this._mouseDrag(e) : this._mouseUp(e));
+        }
+        
+        return !this._mouseStarted;
+    },
+    
+    _mouseUp: function(e) {
+        $(document)
+            .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+            .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+        
+        if (this._mouseStarted) {
+            this._mouseStarted = false;
+            this._mouseStop(e);
+        }
+        
+        return false;
+    },
+    
+    _mouseDistanceMet: function(e) {
+        return (Math.max(
+                Math.abs(this._mouseDownEvent.pageX - e.pageX),
+                Math.abs(this._mouseDownEvent.pageY - e.pageY)
+            ) >= this.options.distance
+        );
+    },
+    
+    _mouseDelayMet: function(e) {
+        return this.mouseDelayMet;
+    },
+    
+    // These are placeholder methods, to be overriden by extending plugin
+    _mouseStart: function(e) {},
+    _mouseDrag: function(e) {},
+    _mouseStop: function(e) {},
+    _mouseCapture: function(e) { return true; }
+};
+
+$.ui.mouse.defaults = {
+    cancel: null,
+    distance: 1,
+    delay: 0
+};
+
+})(jQuery);
Added: branches/experimental/ui/widget-auto-getters/ui.dialog.js
==============================================================================
--- (empty file)
+++ branches/experimental/ui/widget-auto-getters/ui.dialog.js    Sun Oct 26
19:22:34 2008
@@ -0,0 +1,591 @@
+/*
+ * jQuery UI Dialog @VERSION
+ *
+ * Copyright (c) 2008 Richard D. Worth (rdworth.org)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ *    ui.core.js
+ *    ui.draggable.js
+ *    ui.resizable.js
+ */
+(function($) {
+
+var setDataSwitch = {
+    dragStart: "start.draggable",
+    drag: "drag.draggable",
+    dragStop: "stop.draggable",
+    maxHeight: "maxHeight.resizable",
+    minHeight: "minHeight.resizable",
+    maxWidth: "maxWidth.resizable",
+    minWidth: "minWidth.resizable",
+    resizeStart: "start.resizable",
+    resize: "drag.resizable",
+    resizeStop: "stop.resizable"
+};
+
+$.widget("ui.dialog", {
+    _init: function() {
+        this.originalTitle = this.element.attr('title');
+        this.options.title = this.options.title || this.originalTitle;
+        
+        var self = this,
+            options = this.options,
+            
+            uiDialogContent = this.element
+                .removeAttr('title')
+                .addClass('ui-dialog-content')
+                .wrap('<div/>')
+                .wrap('<div/>'),
+            
+            uiDialogContainer = (this.uiDialogContainer = uiDialogContent.parent())
+                .addClass('ui-dialog-container')
+                .css({
+                    position: 'relative',
+                    width: '100%',
+                    height: '100%'
+                }),
+            
+            uiDialogTitlebar = (this.uiDialogTitlebar = $('<div/>'))
+                .addClass('ui-dialog-titlebar')
+                .append('<a href="#"
class="ui-dialog-titlebar-close"><span>X</span></a>')
+                .prependTo(uiDialogContainer),
+            
+            title = options.title || '&nbsp;',
+            titleId = $.ui.dialog.getTitleId(this.element),
+            uiDialogTitle = $('<span/>')
+                .addClass('ui-dialog-title')
+                .attr('id', titleId)
+                .html(title)
+                .prependTo(uiDialogTitlebar),
+           &n