1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 base.exportTo('ui', function() { 6 7 /** 8 * Helper function for creating new element for define. 9 */ 10 function createElementHelper(tagName, opt_bag) { 11 // Allow passing in ownerDocument to create in a different document. 12 var doc; 13 if (opt_bag && opt_bag.ownerDocument) 14 doc = opt_bag.ownerDocument; 15 16 return doc.createElement(tagName); 17 } 18 19 /** 20 * Creates the constructor for a UI element class. 21 * 22 * Usage: 23 * <pre> 24 * var List = base.ui.define('list'); 25 * List.prototype = { 26 * __proto__: HTMLUListElement.prototype, 27 * decorate: function() { 28 * ... 29 * }, 30 * ... 31 * }; 32 * </pre> 33 * 34 * @param {string|Function} tagNameOrFunction The tagName or 35 * function to use for newly created elements. If this is a function it 36 * needs to return a new element when called. 37 * @return {function(Object=):Element} The constructor function which takes 38 * an optional property bag. The function also has a static 39 * {@code decorate} method added to it. 40 */ 41 function define(tagNameOrFunction) { 42 var createFunction, tagName; 43 if (typeof tagNameOrFunction == 'function') { 44 createFunction = tagNameOrFunction; 45 tagName = ''; 46 } else { 47 createFunction = createElementHelper; 48 tagName = tagNameOrFunction; 49 } 50 51 /** 52 * Creates a new UI element constructor. 53 * @param {Object=} opt_propertyBag Optional bag of properties to set on the 54 * object after created. The property {@code ownerDocument} is special 55 * cased and it allows you to create the element in a different 56 * document than the default. 57 * @constructor 58 */ 59 function f(opt_propertyBag) { 60 var el = createFunction(tagName, opt_propertyBag); 61 f.decorate(el); 62 for (var propertyName in opt_propertyBag) { 63 el[propertyName] = opt_propertyBag[propertyName]; 64 } 65 return el; 66 } 67 68 /** 69 * Decorates an element as a UI element class. 70 * @param {!Element} el The element to decorate. 71 */ 72 f.decorate = function(el) { 73 el.__proto__ = f.prototype; 74 el.decorate(); 75 }; 76 77 return f; 78 } 79 80 return { 81 define: define 82 }; 83 }); 84