You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by gm...@apache.org on 2014/07/11 18:23:29 UTC

svn commit: r1609737 [14/18] - in /roller/trunk/app/src/main/webapp: WEB-INF/jsps/editor/ WEB-INF/jsps/tiles/ roller-ui/yui3/arraylist/ roller-ui/yui3/assets/ roller-ui/yui3/assets/skins/ roller-ui/yui3/assets/skins/sam/ roller-ui/yui3/async-queue/ rol...

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-base/pluginhost-base.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-base/pluginhost-base.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-base/pluginhost-base.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-base/pluginhost-base.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,188 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add('pluginhost-base', function (Y, NAME) {
+
+    /**
+     * Provides the augmentable PluginHost interface, which can be added to any class.
+     * @module pluginhost
+     */
+
+    /**
+     * Provides the augmentable PluginHost interface, which can be added to any class.
+     * @module pluginhost-base
+     */
+
+    /**
+     * <p>
+     * An augmentable class, which provides the augmented class with the ability to host plugins.
+     * It adds <a href="#method_plug">plug</a> and <a href="#method_unplug">unplug</a> methods to the augmented class, which can
+     * be used to add or remove plugins from instances of the class.
+     * </p>
+     *
+     * <p>Plugins can also be added through the constructor configuration object passed to the host class' constructor using
+     * the "plugins" property. Supported values for the "plugins" property are those defined by the <a href="#method_plug">plug</a> method.
+     *
+     * For example the following code would add the AnimPlugin and IOPlugin to Overlay (the plugin host):
+     * <xmp>
+     * var o = new Overlay({plugins: [ AnimPlugin, {fn:IOPlugin, cfg:{section:"header"}}]});
+     * </xmp>
+     * </p>
+     * <p>
+     * Plug.Host's protected <a href="#method_initPlugins">_initPlugins</a> and <a href="#method_destroyPlugins">_destroyPlugins</a>
+     * methods should be invoked by the host class at the appropriate point in the host's lifecyle.
+     * </p>
+     *
+     * @class Plugin.Host
+     */
+
+    var L = Y.Lang;
+
+    function PluginHost() {
+        this._plugins = {};
+    }
+
+    PluginHost.prototype = {
+
+        /**
+         * Adds a plugin to the host object. This will instantiate the
+         * plugin and attach it to the configured namespace on the host object.
+         *
+         * @method plug
+         * @chainable
+         * @param P {Function | Object |Array} Accepts the plugin class, or an
+         * object with a "fn" property specifying the plugin class and
+         * a "cfg" property specifying the configuration for the Plugin.
+         * <p>
+         * Additionally an Array can also be passed in, with the above function or
+         * object values, allowing the user to add multiple plugins in a single call.
+         * </p>
+         * @param config (Optional) If the first argument is the plugin class, the second argument
+         * can be the configuration for the plugin.
+         * @return {Base} A reference to the host object
+         */
+        plug: function(Plugin, config) {
+            var i, ln, ns;
+
+            if (L.isArray(Plugin)) {
+                for (i = 0, ln = Plugin.length; i < ln; i++) {
+                    this.plug(Plugin[i]);
+                }
+            } else {
+                if (Plugin && !L.isFunction(Plugin)) {
+                    config = Plugin.cfg;
+                    Plugin = Plugin.fn;
+                }
+
+                // Plugin should be fn by now
+                if (Plugin && Plugin.NS) {
+                    ns = Plugin.NS;
+
+                    config = config || {};
+                    config.host = this;
+
+                    if (this.hasPlugin(ns)) {
+                        // Update config
+                        if (this[ns].setAttrs) {
+                            this[ns].setAttrs(config);
+                        }
+                    } else {
+                        // Create new instance
+                        this[ns] = new Plugin(config);
+                        this._plugins[ns] = Plugin;
+                    }
+                }
+            }
+            return this;
+        },
+
+        /**
+         * Removes a plugin from the host object. This will destroy the
+         * plugin instance and delete the namespace from the host object.
+         *
+         * @method unplug
+         * @param {String | Function} plugin The namespace of the plugin, or the plugin class with the static NS namespace property defined. If not provided,
+         * all registered plugins are unplugged.
+         * @return {Base} A reference to the host object
+         * @chainable
+         */
+        unplug: function(plugin) {
+            var ns = plugin,
+                plugins = this._plugins;
+
+            if (plugin) {
+                if (L.isFunction(plugin)) {
+                    ns = plugin.NS;
+                    if (ns && (!plugins[ns] || plugins[ns] !== plugin)) {
+                        ns = null;
+                    }
+                }
+
+                if (ns) {
+                    if (this[ns]) {
+                        if (this[ns].destroy) {
+                            this[ns].destroy();
+                        }
+                        delete this[ns];
+                    }
+                    if (plugins[ns]) {
+                        delete plugins[ns];
+                    }
+                }
+            } else {
+                for (ns in this._plugins) {
+                    if (this._plugins.hasOwnProperty(ns)) {
+                        this.unplug(ns);
+                    }
+                }
+            }
+            return this;
+        },
+
+        /**
+         * Determines if a plugin has plugged into this host.
+         *
+         * @method hasPlugin
+         * @param {String} ns The plugin's namespace
+         * @return {Plugin} Returns a truthy value (the plugin instance) if present, or undefined if not.
+         */
+        hasPlugin : function(ns) {
+            return (this._plugins[ns] && this[ns]);
+        },
+
+        /**
+         * Initializes static plugins registered on the host (using the
+         * Base.plug static method) and any plugins passed to the
+         * instance through the "plugins" configuration property.
+         *
+         * @method _initPlugins
+         * @param {Object} config The configuration object with property name/value pairs.
+         * @private
+         */
+
+        _initPlugins: function(config) {
+            this._plugins = this._plugins || {};
+
+            if (this._initConfigPlugins) {
+                this._initConfigPlugins(config);
+            }
+        },
+
+        /**
+         * Unplugs and destroys all plugins on the host
+         * @method _destroyPlugins
+         * @private
+         */
+        _destroyPlugins: function() {
+            this.unplug();
+        }
+    };
+
+    Y.namespace("Plugin").Host = PluginHost;
+
+
+}, '3.17.2', {"requires": ["yui-base"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-config/pluginhost-config-min.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-config/pluginhost-config-min.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-config/pluginhost-config-min.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-config/pluginhost-config-min.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add("pluginhost-config",function(e,t){var n=e.Plugin.Host,r=e.Lang;n.prototype._initConfigPlugins=function(t){var n=this._getClasses?this._getClasses():[this.constructor],r=[],i={},s,o,u,a,f;for(o=n.length-1;o>=0;o--)s=n[o],a=s._UNPLUG,a&&e.mix(i,a,!0),u=s._PLUG,u&&e.mix(r,u,!0);for(f in r)r.hasOwnProperty(f)&&(i[f]||this.plug(r[f]));t&&t.plugins&&this.plug(t.plugins)},n.plug=function(t,n,i){var s,o,u,a;if(t!==e.Base){t._PLUG=t._PLUG||{},r.isArray(n)||(i&&(n={fn:n,cfg:i}),n=[n]);for(o=0,u=n.length;o<u;o++)s=n[o],a=s.NAME||s.fn.NAME,t._PLUG[a]=s}},n.unplug=function(t,n){var i,s,o,u;if(t!==e.Base){t._UNPLUG=t._UNPLUG||{},r.isArray(n)||(n=[n]);for(s=0,o=n.length;s<o;s++)i=n[s],u=i.NAME,t._PLUG[u]?delete t._PLUG[u]:t._UNPLUG[u]=i}}},"3.17.2",{requires:["pluginhost-base"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-config/pluginhost-config.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-config/pluginhost-config.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-config/pluginhost-config.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/pluginhost-config/pluginhost-config.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,137 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add('pluginhost-config', function (Y, NAME) {
+
+    /**
+     * Adds pluginhost constructor configuration and static configuration support
+     * @submodule pluginhost-config
+     */
+
+    var PluginHost = Y.Plugin.Host,
+        L = Y.Lang;
+
+    /**
+     * A protected initialization method, used by the host class to initialize
+     * plugin configurations passed the constructor, through the config object.
+     *
+     * Host objects should invoke this method at the appropriate time in their
+     * construction lifecycle.
+     *
+     * @method _initConfigPlugins
+     * @param {Object} config The configuration object passed to the constructor
+     * @protected
+     * @for Plugin.Host
+     */
+    PluginHost.prototype._initConfigPlugins = function(config) {
+
+        // Class Configuration
+        var classes = (this._getClasses) ? this._getClasses() : [this.constructor],
+            plug = [],
+            unplug = {},
+            constructor, i, classPlug, classUnplug, pluginClassName;
+
+        // TODO: Room for optimization. Can we apply statically/unplug in same pass?
+        for (i = classes.length - 1; i >= 0; i--) {
+            constructor = classes[i];
+
+            classUnplug = constructor._UNPLUG;
+            if (classUnplug) {
+                // subclasses over-write
+                Y.mix(unplug, classUnplug, true);
+            }
+
+            classPlug = constructor._PLUG;
+            if (classPlug) {
+                // subclasses over-write
+                Y.mix(plug, classPlug, true);
+            }
+        }
+
+        for (pluginClassName in plug) {
+            if (plug.hasOwnProperty(pluginClassName)) {
+                if (!unplug[pluginClassName]) {
+                    this.plug(plug[pluginClassName]);
+                }
+            }
+        }
+
+        // User Configuration
+        if (config && config.plugins) {
+            this.plug(config.plugins);
+        }
+    };
+
+    /**
+     * Registers plugins to be instantiated at the class level (plugins
+     * which should be plugged into every instance of the class by default).
+     *
+     * @method plug
+     * @static
+     *
+     * @param {Function} hostClass The host class on which to register the plugins
+     * @param {Function | Array} plugin Either the plugin class, an array of plugin classes or an array of objects (with fn and cfg properties defined)
+     * @param {Object} config (Optional) If plugin is the plugin class, the configuration for the plugin
+     * @for Plugin.Host
+     */
+    PluginHost.plug = function(hostClass, plugin, config) {
+        // Cannot plug into Base, since Plugins derive from Base [ will cause infinite recurrsion ]
+        var p, i, l, name;
+
+        if (hostClass !== Y.Base) {
+            hostClass._PLUG = hostClass._PLUG || {};
+
+            if (!L.isArray(plugin)) {
+                if (config) {
+                    plugin = {fn:plugin, cfg:config};
+                }
+                plugin = [plugin];
+            }
+
+            for (i = 0, l = plugin.length; i < l;i++) {
+                p = plugin[i];
+                name = p.NAME || p.fn.NAME;
+                hostClass._PLUG[name] = p;
+            }
+        }
+    };
+
+    /**
+     * Unregisters any class level plugins which have been registered by the host class, or any
+     * other class in the hierarchy.
+     *
+     * @method unplug
+     * @static
+     *
+     * @param {Function} hostClass The host class from which to unregister the plugins
+     * @param {Function | Array} plugin The plugin class, or an array of plugin classes
+     * @for Plugin.Host
+     */
+    PluginHost.unplug = function(hostClass, plugin) {
+        var p, i, l, name;
+
+        if (hostClass !== Y.Base) {
+            hostClass._UNPLUG = hostClass._UNPLUG || {};
+
+            if (!L.isArray(plugin)) {
+                plugin = [plugin];
+            }
+
+            for (i = 0, l = plugin.length; i < l; i++) {
+                p = plugin[i];
+                name = p.NAME;
+                if (!hostClass._PLUG[name]) {
+                    hostClass._UNPLUG[name] = p;
+                } else {
+                    delete hostClass._PLUG[name];
+                }
+            }
+        }
+    };
+
+
+}, '3.17.2', {"requires": ["pluginhost-base"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/selector-native/selector-native-min.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/selector-native/selector-native-min.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/selector-native/selector-native-min.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/selector-native/selector-native-min.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add("selector-native",function(e,t){(function(e){e.namespace("Selector");var t="compareDocumentPosition",n="ownerDocument",r={_types:{esc:{token:"\ue000",re:/\\[:\[\]\(\)#\.\'\>+~"]/gi},attr:{token:"\ue001",re:/(\[[^\]]*\])/g},pseudo:{token:"\ue002",re:/(\([^\)]*\))/g}},useNative:!0,_escapeId:function(e){return e&&(e=e.replace(/([:\[\]\(\)#\.'<>+~"])/g,"\\$1")),e},_compare:"sourceIndex"in e.config.doc.documentElement?function(e,t){var n=e.sourceIndex,r=t.sourceIndex;return n===r?0:n>r?1:-1}:e.config.doc.documentElement[t]?function(e,n){return e[t](n)&4?-1:1}:function(e,t){var r,i,s;return e&&t&&(r=e[n].createRange(),r.setStart(e,0),i=t[n].createRange(),i.setStart(t,0),s=r.compareBoundaryPoints(1,i)),s},_sort:function(t){return t&&(t=e.Array(t,0,!0),t.sort&&t.sort(r._compare)),t},_deDupe:function(e){var t=[],n,r;for(n=0;r=e[n++];)r._found||(t[t.length]=r,r._found=!0);for(n=0;r=t[n++];)r._found=null,r.removeAttribute("_found");return t},query:function(t,n,i,s){n=n||e.config.doc;va
 r o=[],u=e.Selector.useNative&&e.config.doc.querySelector&&!s,a=[[t,n]],f,l,c,h=u?e.Selector._nativeQuery:e.Selector._bruteQuery;if(t&&h){!s&&(!u||n.tagName)&&(a=r._splitQueries(t,n));for(c=0;f=a[c++];)l=h(f[0],f[1],i),i||(l=e.Array(l,0,!0)),l&&(o=o.concat(l));a.length>1&&(o=r._sort(r._deDupe(o)))}return i?o[0]||null:o},_replaceSelector:function(t){var n=e.Selector._parse("esc",t),i,s;return t=e.Selector._replace("esc",t),s=e.Selector._parse("pseudo",t),t=r._replace("pseudo",t),i=e.Selector._parse("attr",t),t=e.Selector._replace("attr",t),{esc:n,attrs:i,pseudos:s,selector:t}},_restoreSelector:function(t){var n=t.selector;return n=e.Selector._restore("attr",n,t.attrs),n=e.Selector._restore("pseudo",n,t.pseudos),n=e.Selector._restore("esc",n,t.esc),n},_replaceCommas:function(t){var n=e.Selector._replaceSelector(t),t=n.selector;return t&&(t=t.replace(/,/g,"\ue007"),n.selector=t,t=e.Selector._restoreSelector(n)),t},_splitQueries:function(t,n){t.indexOf(",")>-1&&(t=e.Selector._replaceCom
 mas(t));var r=t.split("\ue007"),i=[],s="",o,u,a;if(n){n.nodeType===1&&(o=e.Selector._escapeId(e.DOM.getId(n)),o||(o=e.guid(),e.DOM.setId(n,o)),s='[id="'+o+'"] ');for(u=0,a=r.length;u<a;++u)t=s+r[u],i.push([t,n])}return i},_nativeQuery:function(t,n,r){if((e.UA.webkit||e.UA.opera)&&t.indexOf(":checked")>-1&&e.Selector.pseudos&&e.Selector.pseudos.checked)return e.Selector.query(t,n,r,!0);try{return n["querySelector"+(r?"":"All")](t)}catch(i){return e.Selector.query(t,n,r,!0)}},filter:function(t,n){var r=[],i,s;if(t&&n)for(i=0;s=t[i++];)e.Selector.test(s,n)&&(r[r.length]=s);return r},test:function(t,r,i){var s=!1,o=!1,u,a,f,l,c,h,p,d,v;if(t&&t.tagName)if(typeof r=="function")s=r.call(t,t);else{u=r.split(","),!i&&!e.DOM.inDoc(t)&&(a=t.parentNode,a?i=a:(c=t[n].createDocumentFragment(),c.appendChild(t),i=c,o=!0)),i=i||t[n],h=e.Selector._escapeId(e.DOM.getId(t)),h||(h=e.guid(),e.DOM.setId(t,h));for(p=0;v=u[p++];){v+='[id="'+h+'"]',l=e.Selector.query(v,i);for(d=0;f=l[d++];)if(f===t){s=!0;bre
 ak}if(s)break}o&&c.removeChild(t)}return s},ancestor:function(t,n,r){return e.DOM.ancestor(t,function(t){return e.Selector.test(t,n)},r)},_parse:function(t,n){return n.match(e.Selector._types[t].re)},_replace:function(t,n){var r=e.Selector._types[t];return n.replace(r.re,r.token)},_restore:function(t,n,r){if(r){var i=e.Selector._types[t].token,s,o;for(s=0,o=r.length;s<o;++s)n=n.replace(i,r[s])}return n}};e.mix(e.Selector,r,!0)})(e)},"3.17.2",{requires:["dom-base"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/selector-native/selector-native.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/selector-native/selector-native.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/selector-native/selector-native.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/selector-native/selector-native.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,407 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add('selector-native', function (Y, NAME) {
+
+(function(Y) {
+/**
+ * The selector-native module provides support for native querySelector
+ * @module dom
+ * @submodule selector-native
+ * @for Selector
+ */
+
+/**
+ * Provides support for using CSS selectors to query the DOM
+ * @class Selector
+ * @static
+ * @for Selector
+ */
+
+Y.namespace('Selector'); // allow native module to standalone
+
+var COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
+    OWNER_DOCUMENT = 'ownerDocument';
+
+var Selector = {
+    _types: {
+        esc: {
+            token: '\uE000',
+            re: /\\[:\[\]\(\)#\.\'\>+~"]/gi
+        },
+
+        attr: {
+            token: '\uE001',
+            re: /(\[[^\]]*\])/g
+        },
+
+        pseudo: {
+            token: '\uE002',
+            re: /(\([^\)]*\))/g
+        }
+    },
+
+    /**
+     *  Use the native version of `querySelectorAll`, if it exists.
+     *
+     * @property useNative
+     * @default true
+     * @static
+     */
+    useNative: true,
+
+    _escapeId: function(id) {
+        if (id) {
+            id = id.replace(/([:\[\]\(\)#\.'<>+~"])/g,'\\$1');
+        }
+        return id;
+    },
+
+    _compare: ('sourceIndex' in Y.config.doc.documentElement) ?
+        function(nodeA, nodeB) {
+            var a = nodeA.sourceIndex,
+                b = nodeB.sourceIndex;
+
+            if (a === b) {
+                return 0;
+            } else if (a > b) {
+                return 1;
+            }
+
+            return -1;
+
+        } : (Y.config.doc.documentElement[COMPARE_DOCUMENT_POSITION] ?
+        function(nodeA, nodeB) {
+            if (nodeA[COMPARE_DOCUMENT_POSITION](nodeB) & 4) {
+                return -1;
+            } else {
+                return 1;
+            }
+        } :
+        function(nodeA, nodeB) {
+            var rangeA, rangeB, compare;
+            if (nodeA && nodeB) {
+                rangeA = nodeA[OWNER_DOCUMENT].createRange();
+                rangeA.setStart(nodeA, 0);
+                rangeB = nodeB[OWNER_DOCUMENT].createRange();
+                rangeB.setStart(nodeB, 0);
+                compare = rangeA.compareBoundaryPoints(1, rangeB); // 1 === Range.START_TO_END
+            }
+
+            return compare;
+
+    }),
+
+    _sort: function(nodes) {
+        if (nodes) {
+            nodes = Y.Array(nodes, 0, true);
+            if (nodes.sort) {
+                nodes.sort(Selector._compare);
+            }
+        }
+
+        return nodes;
+    },
+
+    _deDupe: function(nodes) {
+        var ret = [],
+            i, node;
+
+        for (i = 0; (node = nodes[i++]);) {
+            if (!node._found) {
+                ret[ret.length] = node;
+                node._found = true;
+            }
+        }
+
+        for (i = 0; (node = ret[i++]);) {
+            node._found = null;
+            node.removeAttribute('_found');
+        }
+
+        return ret;
+    },
+
+    /**
+     * Retrieves a set of nodes based on a given CSS selector.
+     * @method query
+     *
+     * @param {String} selector A CSS selector.
+     * @param {HTMLElement} root optional A node to start the query from. Defaults to `Y.config.doc`.
+     * @param {Boolean} firstOnly optional Whether or not to return only the first match.
+     * @return {HTMLElement[]} The array of nodes that matched the given selector.
+     * @static
+     */
+    query: function(selector, root, firstOnly, skipNative) {
+        root = root || Y.config.doc;
+        var ret = [],
+            useNative = (Y.Selector.useNative && Y.config.doc.querySelector && !skipNative),
+            queries = [[selector, root]],
+            query,
+            result,
+            i,
+            fn = (useNative) ? Y.Selector._nativeQuery : Y.Selector._bruteQuery;
+
+        if (selector && fn) {
+            // split group into seperate queries
+            if (!skipNative && // already done if skipping
+                    (!useNative || root.tagName)) { // split native when element scoping is needed
+                queries = Selector._splitQueries(selector, root);
+            }
+
+            for (i = 0; (query = queries[i++]);) {
+                result = fn(query[0], query[1], firstOnly);
+                if (!firstOnly) { // coerce DOM Collection to Array
+                    result = Y.Array(result, 0, true);
+                }
+                if (result) {
+                    ret = ret.concat(result);
+                }
+            }
+
+            if (queries.length > 1) { // remove dupes and sort by doc order
+                ret = Selector._sort(Selector._deDupe(ret));
+            }
+        }
+
+        return (firstOnly) ? (ret[0] || null) : ret;
+
+    },
+
+    _replaceSelector: function(selector) {
+        var esc = Y.Selector._parse('esc', selector), // pull escaped colon, brackets, etc.
+            attrs,
+            pseudos;
+
+        // first replace escaped chars, which could be present in attrs or pseudos
+        selector = Y.Selector._replace('esc', selector);
+
+        // then replace pseudos before attrs to avoid replacing :not([foo])
+        pseudos = Y.Selector._parse('pseudo', selector);
+        selector = Selector._replace('pseudo', selector);
+
+        attrs = Y.Selector._parse('attr', selector);
+        selector = Y.Selector._replace('attr', selector);
+
+        return {
+            esc: esc,
+            attrs: attrs,
+            pseudos: pseudos,
+            selector: selector
+        };
+    },
+
+    _restoreSelector: function(replaced) {
+        var selector = replaced.selector;
+        selector = Y.Selector._restore('attr', selector, replaced.attrs);
+        selector = Y.Selector._restore('pseudo', selector, replaced.pseudos);
+        selector = Y.Selector._restore('esc', selector, replaced.esc);
+        return selector;
+    },
+
+    _replaceCommas: function(selector) {
+        var replaced = Y.Selector._replaceSelector(selector),
+            selector = replaced.selector;
+
+        if (selector) {
+            selector = selector.replace(/,/g, '\uE007');
+            replaced.selector = selector;
+            selector = Y.Selector._restoreSelector(replaced);
+        }
+        return selector;
+    },
+
+    // allows element scoped queries to begin with combinator
+    // e.g. query('> p', document.body) === query('body > p')
+    _splitQueries: function(selector, node) {
+        if (selector.indexOf(',') > -1) {
+            selector = Y.Selector._replaceCommas(selector);
+        }
+
+        var groups = selector.split('\uE007'), // split on replaced comma token
+            queries = [],
+            prefix = '',
+            id,
+            i,
+            len;
+
+        if (node) {
+            // enforce for element scoping
+            if (node.nodeType === 1) { // Elements only
+                id = Y.Selector._escapeId(Y.DOM.getId(node));
+
+                if (!id) {
+                    id = Y.guid();
+                    Y.DOM.setId(node, id);
+                }
+
+                prefix = '[id="' + id + '"] ';
+            }
+
+            for (i = 0, len = groups.length; i < len; ++i) {
+                selector =  prefix + groups[i];
+                queries.push([selector, node]);
+            }
+        }
+
+        return queries;
+    },
+
+    _nativeQuery: function(selector, root, one) {
+        if (
+            (Y.UA.webkit || Y.UA.opera) &&          // webkit (chrome, safari) and Opera
+            selector.indexOf(':checked') > -1 &&    // fail to pick up "selected"  with ":checked"
+            (Y.Selector.pseudos && Y.Selector.pseudos.checked)
+        ) {
+            return Y.Selector.query(selector, root, one, true); // redo with skipNative true to try brute query
+        }
+        try {
+            return root['querySelector' + (one ? '' : 'All')](selector);
+        } catch(e) { // fallback to brute if available
+            return Y.Selector.query(selector, root, one, true); // redo with skipNative true
+        }
+    },
+
+    /**
+     * Filters out nodes that do not match the given CSS selector.
+     * @method filter
+     *
+     * @param {HTMLElement[]} nodes An array of nodes.
+     * @param {String} selector A CSS selector to test each node against.
+     * @return {HTMLElement[]} The nodes that matched the given CSS selector.
+     * @static
+     */
+    filter: function(nodes, selector) {
+        var ret = [],
+            i, node;
+
+        if (nodes && selector) {
+            for (i = 0; (node = nodes[i++]);) {
+                if (Y.Selector.test(node, selector)) {
+                    ret[ret.length] = node;
+                }
+            }
+        } else {
+        }
+
+        return ret;
+    },
+
+    /**
+     * Determines whether or not the given node matches the given CSS selector.
+     * @method test
+     * 
+     * @param {HTMLElement} node A node to test.
+     * @param {String} selector A CSS selector to test the node against.
+     * @param {HTMLElement} root optional A node to start the query from. Defaults to the parent document of the node.
+     * @return {Boolean} Whether or not the given node matched the given CSS selector.
+     * @static
+     */
+    test: function(node, selector, root) {
+        var ret = false,
+            useFrag = false,
+            groups,
+            parent,
+            item,
+            items,
+            frag,
+            id,
+            i, j, group;
+
+        if (node && node.tagName) { // only test HTMLElements
+
+            if (typeof selector == 'function') { // test with function
+                ret = selector.call(node, node);
+            } else { // test with query
+                // we need a root if off-doc
+                groups = selector.split(',');
+                if (!root && !Y.DOM.inDoc(node)) {
+                    parent = node.parentNode;
+                    if (parent) {
+                        root = parent;
+                    } else { // only use frag when no parent to query
+                        frag = node[OWNER_DOCUMENT].createDocumentFragment();
+                        frag.appendChild(node);
+                        root = frag;
+                        useFrag = true;
+                    }
+                }
+                root = root || node[OWNER_DOCUMENT];
+
+                id = Y.Selector._escapeId(Y.DOM.getId(node));
+                if (!id) {
+                    id = Y.guid();
+                    Y.DOM.setId(node, id);
+                }
+
+                for (i = 0; (group = groups[i++]);) { // TODO: off-dom test
+                    group += '[id="' + id + '"]';
+                    items = Y.Selector.query(group, root);
+
+                    for (j = 0; item = items[j++];) {
+                        if (item === node) {
+                            ret = true;
+                            break;
+                        }
+                    }
+                    if (ret) {
+                        break;
+                    }
+                }
+
+                if (useFrag) { // cleanup
+                    frag.removeChild(node);
+                }
+            };
+        }
+
+        return ret;
+    },
+
+    /**
+     * A convenience method to emulate Y.Node's aNode.ancestor(selector).
+     * @method ancestor
+     *
+     * @param {HTMLElement} node A node to start the query from.
+     * @param {String} selector A CSS selector to test the node against.
+     * @param {Boolean} testSelf optional Whether or not to include the node in the scan.
+     * @return {HTMLElement} The ancestor node matching the selector, or null.
+     * @static
+     */
+    ancestor: function (node, selector, testSelf) {
+        return Y.DOM.ancestor(node, function(n) {
+            return Y.Selector.test(n, selector);
+        }, testSelf);
+    },
+
+    _parse: function(name, selector) {
+        return selector.match(Y.Selector._types[name].re);
+    },
+
+    _replace: function(name, selector) {
+        var o = Y.Selector._types[name];
+        return selector.replace(o.re, o.token);
+    },
+
+    _restore: function(name, selector, items) {
+        if (items) {
+            var token = Y.Selector._types[name].token,
+                i, len;
+            for (i = 0, len = items.length; i < len; ++i) {
+                selector = selector.replace(token, items[i]);
+            }
+        }
+        return selector;
+    }
+};
+
+Y.mix(Y.Selector, Selector, true);
+
+})(Y);
+
+
+}, '3.17.2', {"requires": ["dom-base"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/selector/selector-min.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/selector/selector-min.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/selector/selector-min.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/selector/selector-min.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add("selector",function(e,t){},"3.17.2",{requires:["selector-native"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/selector/selector.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/selector/selector.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/selector/selector.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/selector/selector.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,12 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add('selector', function (Y, NAME) {
+
+
+
+}, '3.17.2', {"requires": ["selector-native"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview-base/tabview-base-min.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview-base/tabview-base-min.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview-base/tabview-base-min.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview-base/tabview-base-min.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add("tabview-base",function(e,t){var n=e.ClassNameManager.getClassName,r="tabview",i="tab",s="panel",o="selected",u={},a=".",f=function(){this.init.apply(this,arguments)};f.NAME="tabviewBase",f._classNames={tabview:n(r),tabviewPanel:n(r,s),tabviewList:n(r,"list"),tab:n(i),tabLabel:n(i,"label"),tabPanel:n(i,s),selectedTab:n(i,o),selectedPanel:n(i,s,o)},f._queries={tabview:a+f._classNames.tabview,tabviewList:"> ul",tab:"> ul > li",tabLabel:"> ul > li > a",tabviewPanel:"> div",tabPanel:"> div > div",selectedTab:"> ul > "+a+f._classNames.selectedTab,selectedPanel:"> div "+a+f._classNames.selectedPanel},e.mix(f.prototype,{init:function(t){t=t||u,this._node=t.host||e.one(t.node),this.refresh()},initClassNames:function(t){var n=e.TabviewBase._classNames;e.Object.each(e.TabviewBase._queries,function(e,r){if(n[r]){var i=this.all(e);t!==undefined&&(i=i.item(t)),i&&i.addClass(n[r])}},this._node),this._node.addClass(n.tabview)},_select:function(t){var n=e.TabviewBase._classNames,r=e.Tabview
 Base._queries,i=this._node,s=i.one(r.selectedTab),o=i.one(r.selectedPanel),u=i.all(r.tab).item(t),a=i.all(r.tabPanel).item(t);s&&s.removeClass(n.selectedTab),o&&o.removeClass(n.selectedPanel),u&&u.addClass(n.selectedTab),a&&a.addClass(n.selectedPanel)},initState:function(){var t=e.TabviewBase._queries,n=this._node,r=n.one(t.selectedTab),i=r?n.all(t.tab).indexOf(r):0;this._select(i)},_scrubTextNodes:function(){this._node.one(e.TabviewBase._queries.tabviewList).get("childNodes").each(function(e){e.get("nodeType")===3&&e.remove()})},refresh:function(){this._scrubTextNodes(),this.initClassNames(),this.initState(),this.initEvents()},tabEventName:"click",initEvents:function(){this._node.delegate(this.tabEventName,this.onTabEvent,e.TabviewBase._queries.tab,this)},onTabEvent:function(t){t.preventDefault(),this._select(this._node.all(e.TabviewBase._queries.tab).indexOf(t.currentTarget))},destroy:function(){this._node.detach(this.tabEventName)}}),e.TabviewBase=f},"3.17.2",{requires:["node-eve
 nt-delegate","classnamemanager"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview-base/tabview-base.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview-base/tabview-base.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview-base/tabview-base.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview-base/tabview-base.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,151 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add('tabview-base', function (Y, NAME) {
+
+var getClassName = Y.ClassNameManager.getClassName,
+    TABVIEW = 'tabview',
+    TAB = 'tab',
+    PANEL = 'panel',
+    SELECTED = 'selected',
+    EMPTY_OBJ = {},
+    DOT = '.',
+
+    TabviewBase = function() {
+        this.init.apply(this, arguments);
+    };
+
+TabviewBase.NAME = 'tabviewBase';
+TabviewBase._classNames = {
+    tabview: getClassName(TABVIEW),
+    tabviewPanel: getClassName(TABVIEW, PANEL),
+    tabviewList: getClassName(TABVIEW, 'list'),
+    tab: getClassName(TAB),
+    tabLabel: getClassName(TAB, 'label'),
+    tabPanel: getClassName(TAB, PANEL),
+    selectedTab: getClassName(TAB, SELECTED),
+    selectedPanel: getClassName(TAB, PANEL, SELECTED)
+};
+TabviewBase._queries = {
+    tabview: DOT + TabviewBase._classNames.tabview,
+    tabviewList: '> ul',
+    tab: '> ul > li',
+    tabLabel: '> ul > li > a',
+    tabviewPanel: '> div',
+    tabPanel: '> div > div',
+    selectedTab: '> ul > ' + DOT + TabviewBase._classNames.selectedTab,
+    selectedPanel: '> div ' + DOT + TabviewBase._classNames.selectedPanel
+};
+
+Y.mix(TabviewBase.prototype, {
+    init: function(config) {
+        config = config || EMPTY_OBJ;
+        this._node = config.host || Y.one(config.node);
+
+        this.refresh();
+    },
+
+    initClassNames: function(index) {
+        var _classNames = Y.TabviewBase._classNames;
+
+        Y.Object.each(Y.TabviewBase._queries, function(query, name) {
+            // this === tabview._node
+            if (_classNames[name]) {
+                var result = this.all(query);
+
+                if (index !== undefined) {
+                    result = result.item(index);
+                }
+
+                if (result) {
+                    result.addClass(_classNames[name]);
+                }
+            }
+        }, this._node);
+
+        this._node.addClass(_classNames.tabview);
+    },
+
+    _select: function(index) {
+        var _classNames = Y.TabviewBase._classNames,
+            _queries = Y.TabviewBase._queries,
+            node = this._node,
+            oldItem = node.one(_queries.selectedTab),
+            oldContent = node.one(_queries.selectedPanel),
+            newItem = node.all(_queries.tab).item(index),
+            newContent = node.all(_queries.tabPanel).item(index);
+
+        if (oldItem) {
+            oldItem.removeClass(_classNames.selectedTab);
+        }
+
+        if (oldContent) {
+            oldContent.removeClass(_classNames.selectedPanel);
+        }
+
+        if (newItem) {
+            newItem.addClass(_classNames.selectedTab);
+        }
+
+        if (newContent) {
+            newContent.addClass(_classNames.selectedPanel);
+        }
+    },
+
+    initState: function() {
+        var _queries = Y.TabviewBase._queries,
+            node = this._node,
+            activeNode = node.one(_queries.selectedTab),
+            activeIndex = activeNode ?
+                    node.all(_queries.tab).indexOf(activeNode) : 0;
+
+        this._select(activeIndex);
+    },
+
+    // collapse extra space between list-items
+    _scrubTextNodes: function() {
+        this._node.one(Y.TabviewBase._queries.tabviewList).get('childNodes').each(function(node) {
+            if (node.get('nodeType') === 3) { // text node
+                node.remove();
+            }
+        });
+    },
+
+    // base renderer only enlivens existing markup
+    refresh: function() {
+        this._scrubTextNodes();
+        this.initClassNames();
+        this.initState();
+        this.initEvents();
+    },
+
+    tabEventName: 'click',
+
+    initEvents: function() {
+        // TODO: detach prefix for delegate?
+        // this._node.delegate('tabview|' + this.tabEventName),
+        this._node.delegate(this.tabEventName,
+            this.onTabEvent,
+            Y.TabviewBase._queries.tab,
+            this
+        );
+    },
+
+    onTabEvent: function(e) {
+        e.preventDefault();
+        this._select(this._node.all(Y.TabviewBase._queries.tab).indexOf(e.currentTarget));
+    },
+
+    destroy: function() {
+        this._node.detach(this.tabEventName);
+    }
+});
+
+Y.TabviewBase = TabviewBase;
+
+
+}, '3.17.2', {"requires": ["node-event-delegate", "classnamemanager"]});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/night/tabview-skin.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/night/tabview-skin.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/night/tabview-skin.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/night/tabview-skin.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,96 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+.yui3-skin-night .yui3-tabview-panel{
+	background-color:#333333;
+	color:#808080;
+	padding:1px;
+}
+.yui3-skin-night .yui3-tab-panel p{
+	margin:10px;
+}
+.yui3-skin-night .yui3-tabview-list {
+    background-color:#0f0f0f;
+    border-top:1px solid #000;
+	text-align:center;
+    height:46px;
+    background: -moz-linear-gradient(
+		0% 100% 90deg, 
+		#0f0f0f 0%, 
+		#1e1e1e 96%,
+		#292929 100%
+	);
+    background: -webkit-gradient(
+        linear,
+        left bottom,
+        left top,
+        from(#0f0f0f),
+        color-stop(0.96, #1e1e1e),
+        to(#292929)     
+    );
+}
+
+.yui3-skin-night .yui3-tabview-list li {
+	margin-top:8px;
+}
+.yui3-skin-night .yui3-tabview-list li a{
+	border:solid 1px #0c0c0c;
+	border-right-style:none;
+
+	-moz-box-shadow: 0 1px #222222; 
+	-webkit-box-shadow: 0 1px #222222;
+	box-shadow: 0 1px #222222; 
+
+    text-shadow: 0 -1px 0 rgba(0,0,0,0.7);
+	font-size:85%;
+	text-align:center;
+	color: #fff;
+	padding: 6px 28px;
+	background-color:#555658;
+	background: -moz-linear-gradient(
+		0% 100% 90deg, 
+		#343536 0%, 
+		#555658 96%,
+		#3E3F41 100%
+	);
+    background: -webkit-gradient(
+        linear,
+        left bottom,
+        left top,
+        from(#343536),
+        color-stop(0.96, #555658),
+        to(#3E3F41)     
+    );
+}
+.yui3-skin-night .yui3-tabview-list li.yui3-tab-selected a {
+	background-color:#2B2D2D;
+	background: -moz-linear-gradient(
+		0% 100% 90deg, 
+		#242526 0%, 
+		#3b3c3d 96%,
+		#2C2D2F 100%
+	);
+    background: -webkit-gradient(
+        linear,
+        left bottom,
+        left top,
+        from(#242526),
+        color-stop(0.96, #3b3c3d),
+        to(#2C2D2F)     
+    );
+}
+.yui3-skin-night .yui3-tabview-list li:first-child a{
+	-moz-border-radius:6px 0 0 6px;
+	-webkit-border-radius:6px 0 0 6px;
+	border-radius:6px 0 0 6px;
+}
+.yui3-skin-night .yui3-tabview-list li:last-child a{
+	border-right-style:solid;
+	-moz-border-radius:0 6px 6px 0;
+	-webkit-border-radius:0 6px 6px 0;
+	border-radius:0 6px 6px 0;
+}

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/night/tabview.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/night/tabview.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/night/tabview.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/night/tabview.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+.yui3-tab-panel{display:none}.yui3-tab-panel-selected{display:block}.yui3-tabview-list,.yui3-tab{margin:0;padding:0;list-style:none}.yui3-tabview{position:relative}.yui3-tabview,.yui3-tabview-list,.yui3-tabview-panel,.yui3-tab,.yui3-tab-panel{zoom:1}.yui3-tab{display:inline-block;*display:inline;vertical-align:bottom;cursor:pointer}.yui3-tab-label{display:block;display:inline-block;padding:6px 10px;position:relative;text-decoration:none;vertical-align:bottom}.yui3-skin-night .yui3-tabview-panel{background-color:#333;color:#808080;padding:1px}.yui3-skin-night .yui3-tab-panel p{margin:10px}.yui3-skin-night .yui3-tabview-list{background-color:#0f0f0f;border-top:1px solid #000;text-align:center;height:46px;background:-moz-linear-gradient(0% 100% 90deg,#0f0f0f 0,#1e1e1e 96%,#292929 100%);background:-webkit-gradient(linear,left bottom,left top,from(#0f0f0f),color-stop(0.96,#1e1e1e),to(#292929))}.yui3-skin-night .yui3-tabview-list li{margin-top:8px}.yui3-skin-night .yui3-tabview-list li a{
 border:solid 1px #0c0c0c;border-right-style:none;-moz-box-shadow:0 1px #222;-webkit-box-shadow:0 1px #222;box-shadow:0 1px #222;text-shadow:0 -1px 0 rgba(0,0,0,0.7);font-size:85%;text-align:center;color:#fff;padding:6px 28px;background-color:#555658;background:-moz-linear-gradient(0% 100% 90deg,#343536 0,#555658 96%,#3e3f41 100%);background:-webkit-gradient(linear,left bottom,left top,from(#343536),color-stop(0.96,#555658),to(#3e3f41))}.yui3-skin-night .yui3-tabview-list li.yui3-tab-selected a{background-color:#2b2d2d;background:-moz-linear-gradient(0% 100% 90deg,#242526 0,#3b3c3d 96%,#2c2d2f 100%);background:-webkit-gradient(linear,left bottom,left top,from(#242526),color-stop(0.96,#3b3c3d),to(#2c2d2f))}.yui3-skin-night .yui3-tabview-list li:first-child a{-moz-border-radius:6px 0 0 6px;-webkit-border-radius:6px 0 0 6px;border-radius:6px 0 0 6px}.yui3-skin-night .yui3-tabview-list li:last-child a{border-right-style:solid;-moz-border-radius:0 6px 6px 0;-webkit-border-radius:0 6px 6px
  0;border-radius:0 6px 6px 0}#yui3-css-stamp.skin-night-tabview{display:none}

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/sam/tabview-skin.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/sam/tabview-skin.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/sam/tabview-skin.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/sam/tabview-skin.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,65 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+/* .yui-navset defaults to .yui-navset-top */
+.yui3-skin-sam .yui3-tabview-list {
+    border:solid #2647a0; /* color between tab list and content */
+    border-width:0 0 5px;
+    zoom:1;
+}
+
+.yui3-skin-sam .yui3-tab {
+    margin:0 0.2em 0 0;
+    padding:1px 0 0; /* gecko: make room for overflow */
+    zoom:1;
+}
+
+.yui3-skin-sam .yui3-tab-selected {
+    margin-bottom:-1px; /* for overlap (mapped to tabview-list border-width) */
+}
+
+.yui3-skin-sam .yui3-tab-label {
+    background:#d8d8d8 url(../../../../assets/skins/sam/sprite.png) repeat-x; /* tab background */
+    border:solid #a3a3a3;
+    border-width: 1px 1px 0 1px;
+    color:#000;
+    cursor:pointer;
+    font-size:85%;
+    padding:0.3em .75em;
+    text-decoration:none;
+}
+
+.yui3-skin-sam .yui3-tab-label:hover,
+.yui3-skin-sam .yui3-tab-label:focus {
+    background:#bfdaff url(../../../../assets/skins/sam/sprite.png) repeat-x left -1300px; /* hovered tab background */
+    outline:0;
+}
+
+.yui3-skin-sam .yui3-tab-selected .yui3-tab-label,
+.yui3-skin-sam .yui3-tab-selected .yui3-tab-label:focus,
+.yui3-skin-sam .yui3-tab-selected .yui3-tab-label:hover { /* no hover effect for selected */
+    background:#2647a0 url(../../../../assets/skins/sam/sprite.png) repeat-x left -1400px; /* selected tab background */
+    color:#fff;
+}
+
+.yui3-skin-sam .yui3-tab-selected .yui3-tab-label {
+    padding:0.4em 0.75em; /* raise selected tab */
+}
+
+.yui3-skin-sam .yui3-tab-selected .yui3-tab-label {
+    border-color:#243356; /* selected tab border color */
+}
+
+.yui3-skin-sam .yui3-tabview-panel {
+    background:#edf5ff; /* content background color */
+}
+
+.yui3-skin-sam .yui3-tabview-panel {
+    border:1px solid #808080; /* content border */
+    border-top-color:#243356; /* different border color */
+    padding:0.25em 0.5em; /* content padding */
+}

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/sam/tabview.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/sam/tabview.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/sam/tabview.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/skins/sam/tabview.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+.yui3-tab-panel{display:none}.yui3-tab-panel-selected{display:block}.yui3-tabview-list,.yui3-tab{margin:0;padding:0;list-style:none}.yui3-tabview{position:relative}.yui3-tabview,.yui3-tabview-list,.yui3-tabview-panel,.yui3-tab,.yui3-tab-panel{zoom:1}.yui3-tab{display:inline-block;*display:inline;vertical-align:bottom;cursor:pointer}.yui3-tab-label{display:block;display:inline-block;padding:6px 10px;position:relative;text-decoration:none;vertical-align:bottom}.yui3-skin-sam .yui3-tabview-list{border:solid #2647a0;border-width:0 0 5px;zoom:1}.yui3-skin-sam .yui3-tab{margin:0 .2em 0 0;padding:1px 0 0;zoom:1}.yui3-skin-sam .yui3-tab-selected{margin-bottom:-1px}.yui3-skin-sam .yui3-tab-label{background:#d8d8d8 url(../../../../assets/skins/sam/sprite.png) repeat-x;border:solid #a3a3a3;border-width:1px 1px 0 1px;color:#000;cursor:pointer;font-size:85%;padding:.3em .75em;text-decoration:none}.yui3-skin-sam .yui3-tab-label:hover,.yui3-skin-sam .yui3-tab-label:focus{background:#bfdaff url(../
 ../../../assets/skins/sam/sprite.png) repeat-x left -1300px;outline:0}.yui3-skin-sam .yui3-tab-selected .yui3-tab-label,.yui3-skin-sam .yui3-tab-selected .yui3-tab-label:focus,.yui3-skin-sam .yui3-tab-selected .yui3-tab-label:hover{background:#2647a0 url(../../../../assets/skins/sam/sprite.png) repeat-x left -1400px;color:#fff}.yui3-skin-sam .yui3-tab-selected .yui3-tab-label{padding:.4em .75em}.yui3-skin-sam .yui3-tab-selected .yui3-tab-label{border-color:#243356}.yui3-skin-sam .yui3-tabview-panel{background:#edf5ff}.yui3-skin-sam .yui3-tabview-panel{border:1px solid #808080;border-top-color:#243356;padding:.25em .5em}#yui3-css-stamp.skin-sam-tabview{display:none}

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/tabview-core.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/tabview-core.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/tabview-core.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/assets/tabview-core.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,49 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+.yui3-tab-panel {
+    display:none;
+}
+
+.yui3-tab-panel-selected {
+    display:block;
+}
+
+.yui3-tabview-list,
+.yui3-tab {
+    margin:0;
+    padding:0;
+    list-style:none;
+}
+
+.yui3-tabview {
+    position:relative; /* contain absolute positioned tabs (left/right) */
+}
+
+.yui3-tabview,
+.yui3-tabview-list,
+.yui3-tabview-panel,
+.yui3-tab,
+.yui3-tab-panel { /* IE: kill space between horizontal tabs */
+    zoom:1;
+}
+
+.yui3-tab {
+    display:inline-block;
+    *display:inline; /* IE */
+    vertical-align:bottom; /* safari: for overlap */
+    cursor:pointer;
+}
+
+.yui3-tab-label {
+    display:block;
+    display:inline-block;
+    padding: 6px 10px;
+    position:relative; /* IE: to allow overlap */
+    text-decoration: none;
+    vertical-align:bottom; /* safari: for overlap */
+}

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/tabview-min.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/tabview-min.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/tabview-min.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/tabview-min.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add("tabview",function(e,t){var n=".",r=e.Base.create("tabView",e.Widget,[e.WidgetParent],{_afterChildAdded:function(){this.get("contentBox").focusManager.refresh()},_defListNodeValueFn:function(){var t=e.Node.create(this.LIST_TEMPLATE);return t.addClass(e.TabviewBase._classNames.tabviewList),t},_defPanelNodeValueFn:function(){var t=e.Node.create(this.PANEL_TEMPLATE);return t.addClass(e.TabviewBase._classNames.tabviewPanel),t},_afterChildRemoved:function(e){var t=e.index,n=this.get("selection");n||(n=this.item(t-1)||this.item(0),n&&n.set("selected",1)),this.get("contentBox").focusManager.refresh()},_initAria:function(t){var n=t.one(e.TabviewBase._queries.tabviewList);n&&n.setAttrs({role:"tablist"})},bindUI:function(){this.get("contentBox").plug(e.Plugin.NodeFocusManager,{descendants:n+e.TabviewBase._classNames.tabLabel,keys:{next:"down:39",previous:"down:37"},circular:!0}),this.after("render",this._setDefSelection),this.after("addChild",this._afterChildAdded),this.after("removeC
 hild",this._afterChildRemoved)},renderUI:function(){var e=this.get("contentBox");this._renderListBox(e),this._renderPanelBox(e),this._childrenContainer=this.get("listNode"),this._renderTabs(e),this._initAria(e)},_setDefSelection:function(){var e=this.get("selection")||this.item(0);this.some(function(t){if(t.get("selected"))return e=t,!0}),e&&(this.set("selection",e),e.set("selected",1))},_renderListBox:function(e){var t=this.get("listNode");t.inDoc()||e.append(t)},_renderPanelBox:function(e){var t=this.get("panelNode");t.inDoc()||e.append(t)},_renderTabs:function(t){var r=e.TabviewBase._classNames,i=e.TabviewBase._queries,s=t.all(i.tab),o=this.get("panelNode"),u=o?this.get("panelNode").get("children"):null,a=this;s&&(s.addClass(r.tab),t.all(i.tabLabel).addClass(r.tabLabel),t.all(i.tabPanel).addClass(r.tabPanel),s.each(function(e,t){var i=u?u.item(t):null;a.add({boundingBox:e,contentBox:e.one(n+r.tabLabel),panelNode:i})}))}},{ATTRS:{defaultChildType:{value:"Tab"},listNode:{setter:fun
 ction(t){return t=e.one(t),t&&t.addClass(e.TabviewBase._classNames.tabviewList),t},valueFn:"_defListNodeValueFn"},panelNode:{setter:function(t){return t=e.one(t),t&&t.addClass(e.TabviewBase._classNames.tabviewPanel),t},valueFn:"_defPanelNodeValueFn"},tabIndex:{value:null}},HTML_PARSER:{listNode:function(t){return t.one(e.TabviewBase._queries.tabviewList)},panelNode:function(t){return t.one(e.TabviewBase._queries.tabviewPanel)}},LIST_TEMPLATE:"<ul></ul>",PANEL_TEMPLATE:"<div></div>"});r.prototype.LIST_TEMPLATE=r.LIST_TEMPLATE,r.prototype.PANEL_TEMPLATE=r.PANEL_TEMPLATE,e.TabView=r,e.Tab=e.Base.create("tab",e.Widget,[e.WidgetChild],{BOUNDING_TEMPLATE:"<li></li>",CONTENT_TEMPLATE:"<a></a>",PANEL_TEMPLATE:"<div></div>",_uiSetSelectedPanel:function(t){this.get("panelNode").toggleClass(e.TabviewBase._classNames.selectedPanel,t)},_afterTabSelectedChange:function(e){this._uiSetSelectedPanel(e.newVal)},_afterParentChange:function(e){e.newVal?this._add():this._remove()},_initAria:function(){v
 ar t=this.get("contentBox"),n=t.get("id"),r=this.get("panelNode");n||(n=e.guid(),t.set("id",n)),t.set("role","tab"),t.get("parentNode").set("role","presentation"),r.setAttrs({role:"tabpanel","aria-labelledby":n})},syncUI:function(){var t=e.TabviewBase._classNames;this.get("boundingBox").addClass(t.tab),this.get("contentBox").addClass(t.tabLabel),this.set("label",this.get("label")),this.set("content",this.get("content")),this._uiSetSelectedPanel(this.get("selected"))},bindUI:function(){this.after("selectedChange",this._afterTabSelectedChange),this.after("parentChange",this._afterParentChange)},renderUI:function(){this._renderPanel(),this._initAria()},_renderPanel:function(){this.get("parent").get("panelNode").appendChild(this.get("panelNode"))},_add:function(){var e=this.get("parent").get("contentBox"),t=e.get("listNode"),n=e.get("panelNode");t&&t.appendChild(this.get("boundingBox")),n&&n.appendChild(this.get("panelNode"))},_remove:function(){this.get("boundingBox").remove(),this.get
 ("panelNode").remove()},_onActivate:function(e){e.target===this&&(e.domEvent.preventDefault(),e.target.set("selected",1))},initializer:function(){this.publish(this.get("triggerEvent"),{defaultFn:this._onActivate})},_defLabelGetter:function(){return this.get("contentBox").getHTML()},_defLabelSetter:function(e){var t=this.get("contentBox");return t.getHTML()!==e&&t.setHTML(e),e},_defContentSetter:function(e){var t=this.get("panelNode");return t.getHTML()!==e&&t.setHTML(e),e},_defContentGetter:function(){return this.get("panelNode").getHTML()},_defPanelNodeValueFn:function(){var t=e.TabviewBase._classNames,n=this.get("contentBox").get("href")||"",r=this.get("parent"),i=n.indexOf("#"),s;return n=n.substr(i),n.charAt(0)==="#"&&(s=e.one(n),s&&s.addClass(t.tabPanel)),!s&&r&&(s=r.get("panelNode").get("children").item(this.get("index"))),s||(s=e.Node.create(this.PANEL_TEMPLATE),s.addClass(t.tabPanel)),s}},{ATTRS:{triggerEvent:{value:"click"},label:{setter:"_defLabelSetter",getter:"_defLabelG
 etter"},content:{setter:"_defContentSetter",getter:"_defContentGetter"},panelNode:{setter:function(t){return t=e.one(t),t&&t.addClass(e.TabviewBase._classNames.tabPanel),t},valueFn:"_defPanelNodeValueFn"},tabIndex:{value:null,validator:"_validTabIndex"}},HTML_PARSER:{selected:function(){var t=this.get("boundingBox").hasClass(e.TabviewBase._classNames.selectedTab)?1:0;return t}}})},"3.17.2",{requires:["widget","widget-parent","widget-child","tabview-base","node-pluginhost","node-focusmanager"],skinnable:!0});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/tabview.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/tabview.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/tabview.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/tabview/tabview.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,443 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add('tabview', function (Y, NAME) {
+
+/**
+ * The TabView module
+ *
+ * @module tabview
+ */
+
+var DOT = '.',
+
+    /**
+     * Provides a tabbed widget interface
+     * @param config {Object} Object literal specifying tabview configuration properties.
+     *
+     * @class TabView
+     * @constructor
+     * @extends Widget
+     * @uses WidgetParent
+     */
+    TabView = Y.Base.create('tabView', Y.Widget, [Y.WidgetParent], {
+
+    _afterChildAdded: function() {
+        this.get('contentBox').focusManager.refresh();
+    },
+
+    _defListNodeValueFn: function() {
+        var node = Y.Node.create(this.LIST_TEMPLATE);
+
+        node.addClass(Y.TabviewBase._classNames.tabviewList);
+
+        return node;
+    },
+
+    _defPanelNodeValueFn: function() {
+        var node = Y.Node.create(this.PANEL_TEMPLATE);
+
+        node.addClass(Y.TabviewBase._classNames.tabviewPanel);
+
+        return node;
+    },
+
+    _afterChildRemoved: function(e) { // update the selected tab when removed
+        var i = e.index,
+            selection = this.get('selection');
+
+        if (!selection) { // select previous item if selection removed
+            selection = this.item(i - 1) || this.item(0);
+            if (selection) {
+                selection.set('selected', 1);
+            }
+        }
+
+        this.get('contentBox').focusManager.refresh();
+    },
+
+    _initAria: function(contentBox) {
+        var tablist = contentBox.one(Y.TabviewBase._queries.tabviewList);
+
+        if (tablist) {
+            tablist.setAttrs({
+                //'aria-labelledby':
+                role: 'tablist'
+            });
+        }
+    },
+
+    bindUI: function() {
+        //  Use the Node Focus Manager to add keyboard support:
+        //  Pressing the left and right arrow keys will move focus
+        //  among each of the tabs.
+
+        this.get('contentBox').plug(Y.Plugin.NodeFocusManager, {
+                        descendants: DOT + Y.TabviewBase._classNames.tabLabel,
+                        keys: { next: 'down:39', // Right arrow
+                                previous: 'down:37' },  // Left arrow
+                        circular: true
+                    });
+
+        this.after('render', this._setDefSelection);
+        this.after('addChild', this._afterChildAdded);
+        this.after('removeChild', this._afterChildRemoved);
+    },
+
+    renderUI: function() {
+        var contentBox = this.get('contentBox');
+        this._renderListBox(contentBox);
+        this._renderPanelBox(contentBox);
+        this._childrenContainer = this.get('listNode');
+        this._renderTabs(contentBox);
+        this._initAria(contentBox);
+    },
+
+    _setDefSelection: function() {
+        //  If no tab is selected, select the first tab.
+        var selection = this.get('selection') || this.item(0);
+
+        this.some(function(tab) {
+            if (tab.get('selected')) {
+                selection = tab;
+                return true;
+            }
+        });
+        if (selection) {
+            // TODO: why both needed? (via widgetParent/Child)?
+            this.set('selection', selection);
+            selection.set('selected', 1);
+        }
+    },
+
+    _renderListBox: function(contentBox) {
+        var node = this.get('listNode');
+        if (!node.inDoc()) {
+            contentBox.append(node);
+        }
+    },
+
+    _renderPanelBox: function(contentBox) {
+        var node = this.get('panelNode');
+        if (!node.inDoc()) {
+            contentBox.append(node);
+        }
+    },
+
+    _renderTabs: function(contentBox) {
+        var _classNames = Y.TabviewBase._classNames,
+            _queries = Y.TabviewBase._queries,
+            tabs = contentBox.all(_queries.tab),
+            panelNode = this.get('panelNode'),
+            panels = (panelNode) ? this.get('panelNode').get('children') : null,
+            tabview = this;
+
+        if (tabs) { // add classNames and fill in Tab fields from markup when possible
+            tabs.addClass(_classNames.tab);
+            contentBox.all(_queries.tabLabel).addClass(_classNames.tabLabel);
+            contentBox.all(_queries.tabPanel).addClass(_classNames.tabPanel);
+
+            tabs.each(function(node, i) {
+                var panelNode = (panels) ? panels.item(i) : null;
+                tabview.add({
+                    boundingBox: node,
+                    contentBox: node.one(DOT + _classNames.tabLabel),
+                    panelNode: panelNode
+                });
+            });
+        }
+    }
+}, {
+    ATTRS: {
+        defaultChildType: {
+            value: 'Tab'
+        },
+
+        listNode: {
+            setter: function(node) {
+                node = Y.one(node);
+                if (node) {
+                    node.addClass(Y.TabviewBase._classNames.tabviewList);
+                }
+                return node;
+            },
+
+            valueFn: '_defListNodeValueFn'
+        },
+
+        panelNode: {
+            setter: function(node) {
+                node = Y.one(node);
+                if (node) {
+                    node.addClass(Y.TabviewBase._classNames.tabviewPanel);
+                }
+                return node;
+            },
+
+            valueFn: '_defPanelNodeValueFn'
+        },
+
+        tabIndex: {
+            value: null
+            //validator: '_validTabIndex'
+        }
+    },
+
+    HTML_PARSER: {
+        listNode: function(srcNode) {
+            return srcNode.one(Y.TabviewBase._queries.tabviewList);
+        },
+        panelNode: function(srcNode) {
+            return srcNode.one(Y.TabviewBase._queries.tabviewPanel);
+        }
+    },
+
+    // Static for legacy support.
+    LIST_TEMPLATE: '<ul></ul>',
+    PANEL_TEMPLATE: '<div></div>'
+});
+
+// Map to static values by default.
+TabView.prototype.LIST_TEMPLATE = TabView.LIST_TEMPLATE;
+TabView.prototype.PANEL_TEMPLATE = TabView.PANEL_TEMPLATE;
+
+Y.TabView = TabView;
+/**
+ * Provides Tab instances for use with TabView
+ * @param config {Object} Object literal specifying tabview configuration properties.
+ *
+ * @class Tab
+ * @constructor
+ * @extends Widget
+ * @uses WidgetChild
+ */
+Y.Tab = Y.Base.create('tab', Y.Widget, [Y.WidgetChild], {
+    BOUNDING_TEMPLATE: '<li></li>',
+    CONTENT_TEMPLATE: '<a></a>',
+    PANEL_TEMPLATE: '<div></div>',
+
+    _uiSetSelectedPanel: function(selected) {
+        this.get('panelNode').toggleClass(Y.TabviewBase._classNames.selectedPanel, selected);
+    },
+
+    _afterTabSelectedChange: function(event) {
+       this._uiSetSelectedPanel(event.newVal);
+    },
+
+    _afterParentChange: function(e) {
+        if (!e.newVal) {
+            this._remove();
+        } else {
+            this._add();
+        }
+    },
+
+    _initAria: function() {
+        var anchor = this.get('contentBox'),
+            id = anchor.get('id'),
+            panel = this.get('panelNode');
+
+        if (!id) {
+            id = Y.guid();
+            anchor.set('id', id);
+        }
+        //  Apply the ARIA roles, states and properties to each tab
+        anchor.set('role', 'tab');
+        anchor.get('parentNode').set('role', 'presentation');
+
+        //  Apply the ARIA roles, states and properties to each panel
+        panel.setAttrs({
+            role: 'tabpanel',
+            'aria-labelledby': id
+        });
+    },
+
+    syncUI: function() {
+        var _classNames = Y.TabviewBase._classNames;
+
+        this.get('boundingBox').addClass(_classNames.tab);
+        this.get('contentBox').addClass(_classNames.tabLabel);
+        this.set('label', this.get('label'));
+        this.set('content', this.get('content'));
+        this._uiSetSelectedPanel(this.get('selected'));
+    },
+
+    bindUI: function() {
+       this.after('selectedChange', this._afterTabSelectedChange);
+       this.after('parentChange', this._afterParentChange);
+    },
+
+    renderUI: function() {
+        this._renderPanel();
+        this._initAria();
+    },
+
+    _renderPanel: function() {
+        this.get('parent').get('panelNode')
+            .appendChild(this.get('panelNode'));
+    },
+
+    _add: function() {
+        var parent = this.get('parent').get('contentBox'),
+            list = parent.get('listNode'),
+            panel = parent.get('panelNode');
+
+        if (list) {
+            list.appendChild(this.get('boundingBox'));
+        }
+
+        if (panel) {
+            panel.appendChild(this.get('panelNode'));
+        }
+    },
+
+    _remove: function() {
+        this.get('boundingBox').remove();
+        this.get('panelNode').remove();
+    },
+
+    _onActivate: function(e) {
+         if (e.target === this) {
+             //  Prevent the browser from navigating to the URL specified by the
+             //  anchor's href attribute.
+             e.domEvent.preventDefault();
+             e.target.set('selected', 1);
+         }
+    },
+
+    initializer: function() {
+       this.publish(this.get('triggerEvent'), {
+           defaultFn: this._onActivate
+       });
+    },
+
+    _defLabelGetter: function() {
+        return this.get('contentBox').getHTML();
+    },
+
+    _defLabelSetter: function(label) {
+        var labelNode = this.get('contentBox');
+        if (labelNode.getHTML() !== label) { // Avoid rewriting existing label.
+            labelNode.setHTML(label);
+        }
+        return label;
+    },
+
+    _defContentSetter: function(content) {
+        var panel = this.get('panelNode');
+        if (panel.getHTML() !== content) { // Avoid rewriting existing content.
+            panel.setHTML(content);
+        }
+        return content;
+    },
+
+    _defContentGetter: function() {
+        return this.get('panelNode').getHTML();
+    },
+
+    // find panel by ID mapping from label href
+    _defPanelNodeValueFn: function() {
+        var _classNames = Y.TabviewBase._classNames,
+            href = this.get('contentBox').get('href') || '',
+            parent = this.get('parent'),
+            hashIndex = href.indexOf('#'),
+            panel;
+
+        href = href.substr(hashIndex);
+
+        if (href.charAt(0) === '#') { // in-page nav, find by ID
+            panel = Y.one(href);
+            if (panel) {
+                panel.addClass(_classNames.tabPanel);
+            }
+        }
+
+        // use the one found by id, or else try matching indices
+        if (!panel && parent) {
+            panel = parent.get('panelNode')
+                    .get('children').item(this.get('index'));
+        }
+
+        if (!panel) { // create if none found
+            panel = Y.Node.create(this.PANEL_TEMPLATE);
+            panel.addClass(_classNames.tabPanel);
+        }
+        return panel;
+    }
+}, {
+    ATTRS: {
+        /**
+         * @attribute triggerEvent
+         * @default "click"
+         * @type String
+         */
+        triggerEvent: {
+            value: 'click'
+        },
+
+        /**
+         * @attribute label
+         * @type HTML
+         */
+        label: {
+            setter: '_defLabelSetter',
+            getter: '_defLabelGetter'
+        },
+
+        /**
+         * @attribute content
+         * @type HTML
+         */
+        content: {
+            setter: '_defContentSetter',
+            getter: '_defContentGetter'
+        },
+
+        /**
+         * @attribute panelNode
+         * @type Y.Node
+         */
+        panelNode: {
+            setter: function(node) {
+                node = Y.one(node);
+                if (node) {
+                    node.addClass(Y.TabviewBase._classNames.tabPanel);
+                }
+                return node;
+            },
+            valueFn: '_defPanelNodeValueFn'
+        },
+
+        tabIndex: {
+            value: null,
+            validator: '_validTabIndex'
+        }
+
+    },
+
+    HTML_PARSER: {
+        selected: function() {
+            var ret = (this.get('boundingBox').hasClass(Y.TabviewBase._classNames.selectedTab)) ?
+                        1 : 0;
+            return ret;
+        }
+    }
+
+});
+
+
+}, '3.17.2', {
+    "requires": [
+        "widget",
+        "widget-parent",
+        "widget-child",
+        "tabview-base",
+        "node-pluginhost",
+        "node-focusmanager"
+    ],
+    "skinnable": true
+});

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/night/widget-base-skin.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/night/widget-base-skin.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/night/widget-base-skin.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/night/widget-base-skin.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,7 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/night/widget-base.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/night/widget-base.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/night/widget-base.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/night/widget-base.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+.yui3-widget-hidden{display:none}.yui3-widget-content{overflow:hidden}.yui3-widget-content-expanded{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;height:100%}.yui3-widget-tmp-forcesize{overflow:hidden!important}#yui3-css-stamp.skin-night-widget-base{display:none}

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/sam/widget-base-skin.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/sam/widget-base-skin.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/sam/widget-base-skin.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/sam/widget-base-skin.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,7 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/sam/widget-base.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/sam/widget-base.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/sam/widget-base.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/skins/sam/widget-base.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,8 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+.yui3-widget-hidden{display:none}.yui3-widget-content{overflow:hidden}.yui3-widget-content-expanded{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;height:100%}.yui3-widget-tmp-forcesize{overflow:hidden!important}#yui3-css-stamp.skin-sam-widget-base{display:none}

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/widget-base-core.css
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/widget-base-core.css?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/widget-base-core.css (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/assets/widget-base-core.css Fri Jul 11 16:23:25 2014
@@ -0,0 +1,27 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+.yui3-widget-hidden {
+    display:none;
+}
+
+.yui3-widget-content {
+    overflow:hidden;
+}
+
+.yui3-widget-content-expanded {
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    box-sizing:border-box;
+    height:100%;
+}
+
+/* Only used for IE6, to go from a bigger size to a smaller size when using cb.sizeTo(bb) */
+.yui3-widget-tmp-forcesize {
+    overflow:hidden !important;
+}
\ No newline at end of file

Added: roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/widget-base-min.js
URL: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/widget-base-min.js?rev=1609737&view=auto
==============================================================================
--- roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/widget-base-min.js (added)
+++ roller/trunk/app/src/main/webapp/roller-ui/yui3/widget-base/widget-base-min.js Fri Jul 11 16:23:25 2014
@@ -0,0 +1,9 @@
+/*
+YUI 3.17.2 (build 9c3c78e)
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add("widget-base",function(e,t){function R(e){var t=this,n,r,i=t.constructor;t._strs={},t._cssPrefix=i.CSS_PREFIX||s(i.NAME.toLowerCase()),e=e||{},R.superclass.constructor.call(t,e),r=t.get(T),r&&(r!==P&&(n=r),t.render(n))}var n=e.Lang,r=e.Node,i=e.ClassNameManager,s=i.getClassName,o,u=e.cached(function(e){return e.substring(0,1).toUpperCase()+e.substring(1)}),a="content",f="visible",l="hidden",c="disabled",h="focused",p="width",d="height",v="boundingBox",m="contentBox",g="parentNode",y="ownerDocument",b="auto",w="srcNode",E="body",S="tabIndex",x="id",T="render",N="rendered",C="destroyed",k="strings",L="<div></div>",A="Change",O="loading",M="_uiSet",_="",D=function(){},P=!0,H=!1,B,j={},F=[f,c,d,p,h,S],I=e.UA.webkit,q={};R.NAME="widget",B=R.UI_SRC="ui",R.ATTRS=j,j[x]={valueFn:"_guid",writeOnce:P},j[N]={value:H,readOnly:P},j[v]={valueFn:"_defaultBB",setter:"_setBB",writeOnce:P},j[m]={valueFn:"_defaultCB",setter:"_setCB",writeOnce:P},j[S]={value:null,validator:"_validTabIndex"},j[h
 ]={value:H,readOnly:P},j[c]={value:H},j[f]={value:P},j[d]={value:_},j[p]={value:_},j[k]={value:{},setter:"_strSetter",getter:"_strGetter"},j[T]={value:H,writeOnce:P},R.CSS_PREFIX=s(R.NAME.toLowerCase()),R.getClassName=function(){return s.apply(i,[R.CSS_PREFIX].concat(e.Array(arguments),!0))},o=R.getClassName,R.getByNode=function(t){var n,i=o();return t=r.one(t),t&&(t=t.ancestor("."+i,!0),t&&(n=q[e.stamp(t,!0)])),n||null},e.extend(R,e.Base,{getClassName:function(){return s.apply(i,[this._cssPrefix].concat(e.Array(arguments),!0))},initializer:function(t){var n=this.get(v);n instanceof r&&this._mapInstance(e.stamp(n))},_mapInstance:function(e){q[e]=this},destructor:function(){var t=this.get(v),n;t instanceof r&&(n=e.stamp(t,!0),n in q&&delete q[n],this._destroyBox())},destroy:function(e){return this._destroyAllNodes=e,R.superclass.destroy.apply(this)},_destroyBox:function(){var e=this.get(v),t=this.get(m),n=this._destroyAllNodes,r;r=e&&e.compareTo(t),this.UI_EVENTS&&this._destroyUIEven
 ts(),this._unbindUI(e),t&&(n&&t.empty(),t.remove(P)),r||(n&&e.empty(),e.remove(P))},render:function(e){return!this.get(C)&&!this.get(N)&&(this.publish(T,{queuable:H,fireOnce:P,defaultTargetOnly:P,defaultFn:this._defRenderFn}),this.fire(T,{parentNode:e?r.one(e):null})),this},_defRenderFn:function(e){this._parentNode=e.parentNode,this.renderer(),this._set(N,P),this._removeLoadingClassNames()},renderer:function(){var e=this;e._renderUI(),e.renderUI(),e._bindUI(),e.bindUI(),e._syncUI(),e.syncUI()},bindUI:D,renderUI:D,syncUI:D,hide:function(){return this.set(f,H)},show:function(){return this.set(f,P)},focus:function(){return this._set(h,P)},blur:function(){return this._set(h,H)},enable:function(){return this.set(c,H)},disable:function(){return this.set(c,P)},_uiSizeCB:function(e){this.get(m).toggleClass(o(a,"expanded"),e)},_renderBox:function(e){var t=this,n=t.get(m),i=t.get(v),s=t.get(w),o=t.DEF_PARENT_NODE,u=s&&s.get(y)||i.get(y)||n.get(y);s&&!s.compareTo(n)&&!n.inDoc(u)&&s.replace(n),
 !i.compareTo(n.get(g))&&!i.compareTo(n)&&(n.inDoc(u)&&n.replace(i),i.appendChild(n)),e=e||o&&r.one(o),e?e.appendChild(i):i.inDoc(u)||r.one(E).insert(i,0)},_setBB:function(e){return this._setBox(this.get(x),e,this.BOUNDING_TEMPLATE,!0)},_setCB:function(e){return this.CONTENT_TEMPLATE===null?this.get(v):this._setBox(null,e,this.CONTENT_TEMPLATE,!1)},_defaultBB:function(){var e=this.get(w),t=this.CONTENT_TEMPLATE===null;return e&&t?e:null},_defaultCB:function(e){return this.get(w)||null},_setBox:function(t,n,i,s){return n=r.one(n),n||(n=r.create(i),s?this._bbFromTemplate=!0:this._cbFromTemplate=!0),n.get(x)||n.set(x,t||e.guid()),n},_renderUI:function(){this._renderBoxClassNames(),this._renderBox(this._parentNode)},_renderBoxClassNames:function(){var e=this._getClasses(),t,n=this.get(v),r;n.addClass(o());for(r=e.length-3;r>=0;r--)t=e[r],n.addClass(t.CSS_PREFIX||s(t.NAME.toLowerCase()));this.get(m).addClass(this.getClassName(a))},_removeLoadingClassNames:function(){var e=this.get(v),t=th
 is.get(m),n=this.getClassName(O),r=o(O);e.removeClass(r).removeClass(n),t.removeClass(r).removeClass(n)},_bindUI:function(){this._bindAttrUI(this._UI_ATTRS.BIND),this._bindDOM()},_unbindUI:function(e){this._unbindDOM(e)},_bindDOM:function(){var t=this.get(v).get(y),n=R._hDocFocus;n||(n=R._hDocFocus=t.on("focus",this._onDocFocus,this),n.listeners={count:0}),n.listeners[e.stamp(this,!0)]=!0,n.listeners.count++,I&&(this._hDocMouseDown=t.on("mousedown",this._onDocMouseDown,this))},_unbindDOM:function(t){var n=R._hDocFocus,r=e.stamp(this,!0),i,s=this._hDocMouseDown;n&&(i=n.listeners,i[r]&&(delete i[r],i.count--),i.count===0&&(n.detach(),R._hDocFocus=null)),I&&s&&s.detach()},_syncUI:function(){this._syncAttrUI(this._UI_ATTRS.SYNC)},_uiSetHeight:function(e){this._uiSetDim(d,e),this._uiSizeCB(e!==_&&e!==b)},_uiSetWidth:function(e){this._uiSetDim(p,e)},_uiSetDim:function(e,t){this.get(v).setStyle(e,n.isNumber(t)?t+this.DEF_UNIT:t)},_uiSetVisible:function(e){this.get(v).toggleClass(this.getCl
 assName(l),!e)},_uiSetDisabled:function(e){this.get(v).toggleClass(this.getClassName(c),e)},_uiSetFocused:function(e,t){var n=this.get(v);n.toggleClass(this.getClassName(h),e),t!==B&&(e?n.focus():n.blur())},_uiSetTabIndex:function(e){var t=this.get(v);n.isNumber(e)?t.set(S,e):t.removeAttribute(S)},_onDocMouseDown:function(e){this._domFocus&&this._onDocFocus(e)},_onDocFocus:function(e){var t=R.getByNode(e.target),n=R._active;n&&n!==t&&(n._domFocus=!1,n._set(h,!1,{src:B}),R._active=null),t&&(t._domFocus=!0,t._set(h,!0,{src:B}),R._active=t)},toString:function(){return this.name+"["+this.get(x)+"]"},DEF_UNIT:"px",DEF_PARENT_NODE:null,CONTENT_TEMPLATE:L,BOUNDING_TEMPLATE:L,_guid:function(){return e.guid()},_validTabIndex:function(e){return n.isNumber(e)||n.isNull(e)},_bindAttrUI:function(e){var t,n=e.length;for(t=0;t<n;t++)this.after(e[t]+A,this._setAttrUI)},_syncAttrUI:function(e){var t,n=e.length,r;for(t=0;t<n;t++)r=e[t],this[M+u(r)](this.get(r))},_setAttrUI:function(e){e.target===this
 &&this[M+u(e.attrName
+)](e.newVal,e.src)},_strSetter:function(t){return e.merge(this.get(k),t)},getString:function(e){return this.get(k)[e]},getStrings:function(){return this.get(k)},_UI_ATTRS:{BIND:F,SYNC:F}}),e.Widget=R},"3.17.2",{requires:["attribute","base-base","base-pluginhost","classnamemanager","event-focus","node-base","node-style"],skinnable:!0});