OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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 cr.define('cr.ui', function() { |
| 6 |
| 7 /** |
| 8 * Decorates elements as an instance of a class. |
| 9 * @param {string|!Element} source The way to find the element(s) to decorate. |
| 10 * If this is a string then {@code querySeletorAll} is used to find the |
| 11 * elements to decorate. |
| 12 * @param {!Function} constr The constructor to decorate with. The constr |
| 13 * needs to have a {@code decorate} function. |
| 14 */ |
| 15 function decorate(source, constr) { |
| 16 var elements; |
| 17 if (typeof source == 'string') |
| 18 elements = cr.doc.querySelectorAll(source); |
| 19 else |
| 20 elements = [source]; |
| 21 |
| 22 for (var i = 0, el; el = elements[i]; i++) { |
| 23 if (!(el instanceof constr)) |
| 24 constr.decorate(el); |
| 25 } |
| 26 } |
| 27 |
| 28 /** |
| 29 * Helper function for creating new element for define. |
| 30 */ |
| 31 function createElementHelper(tagName, opt_bag) { |
| 32 // Allow passing in ownerDocument to create in a different document. |
| 33 var doc; |
| 34 if (opt_bag && opt_bag.ownerDocument) |
| 35 doc = opt_bag.ownerDocument; |
| 36 else |
| 37 doc = cr.doc; |
| 38 return doc.createElement(tagName); |
| 39 } |
| 40 |
| 41 /** |
| 42 * Creates the constructor for a UI element class. |
| 43 * |
| 44 * Usage: |
| 45 * <pre> |
| 46 * var List = cr.ui.define('list'); |
| 47 * List.prototype = { |
| 48 * __proto__: HTMLUListElement.prototype, |
| 49 * decorate: function() { |
| 50 * ... |
| 51 * }, |
| 52 * ... |
| 53 * }; |
| 54 * </pre> |
| 55 * |
| 56 * @param {string|Function} tagNameOrFunction The tagName or |
| 57 * function to use for newly created elements. If this is a function it |
| 58 * needs to return a new element when called. |
| 59 * @return {function(Object=):Element} The constructor function which takes |
| 60 * an optional property bag. The function also has a static |
| 61 * {@code decorate} method added to it. |
| 62 */ |
| 63 function define(tagNameOrFunction) { |
| 64 var createFunction, tagName; |
| 65 if (typeof tagNameOrFunction == 'function') { |
| 66 createFunction = tagNameOrFunction; |
| 67 tagName = ''; |
| 68 } else { |
| 69 createFunction = createElementHelper; |
| 70 tagName = tagNameOrFunction; |
| 71 } |
| 72 |
| 73 /** |
| 74 * Creates a new UI element constructor. |
| 75 * @param {Object=} opt_propertyBag Optional bag of properties to set on the |
| 76 * object after created. The property {@code ownerDocument} is special |
| 77 * cased and it allows you to create the element in a different |
| 78 * document than the default. |
| 79 * @constructor |
| 80 */ |
| 81 function f(opt_propertyBag) { |
| 82 var el = createFunction(tagName, opt_propertyBag); |
| 83 f.decorate(el); |
| 84 for (var propertyName in opt_propertyBag) { |
| 85 el[propertyName] = opt_propertyBag[propertyName]; |
| 86 } |
| 87 return el; |
| 88 } |
| 89 |
| 90 /** |
| 91 * Decorates an element as a UI element class. |
| 92 * @param {!Element} el The element to decorate. |
| 93 */ |
| 94 f.decorate = function(el) { |
| 95 el.__proto__ = f.prototype; |
| 96 el.decorate(); |
| 97 }; |
| 98 |
| 99 return f; |
| 100 } |
| 101 |
| 102 /** |
| 103 * Input elements do not grow and shrink with their content. This is a simple |
| 104 * (and not very efficient) way of handling shrinking to content with support |
| 105 * for min width and limited by the width of the parent element. |
| 106 * @param {HTMLElement} el The element to limit the width for. |
| 107 * @param {number} parentEl The parent element that should limit the size. |
| 108 * @param {number} min The minimum width. |
| 109 */ |
| 110 function limitInputWidth(el, parentEl, min) { |
| 111 // Needs a size larger than borders |
| 112 el.style.width = '10px'; |
| 113 var doc = el.ownerDocument; |
| 114 var win = doc.defaultView; |
| 115 var computedStyle = win.getComputedStyle(el); |
| 116 var parentComputedStyle = win.getComputedStyle(parentEl); |
| 117 var rtl = computedStyle.direction == 'rtl'; |
| 118 |
| 119 // To get the max width we get the width of the treeItem minus the position |
| 120 // of the input. |
| 121 var inputRect = el.getBoundingClientRect(); // box-sizing |
| 122 var parentRect = parentEl.getBoundingClientRect(); |
| 123 var startPos = rtl ? parentRect.right - inputRect.right : |
| 124 inputRect.left - parentRect.left; |
| 125 |
| 126 // Add up border and padding of the input. |
| 127 var inner = parseInt(computedStyle.borderLeftWidth, 10) + |
| 128 parseInt(computedStyle.paddingLeft, 10) + |
| 129 parseInt(computedStyle.paddingRight, 10) + |
| 130 parseInt(computedStyle.borderRightWidth, 10); |
| 131 |
| 132 // We also need to subtract the padding of parent to prevent it to overflow. |
| 133 var parentPadding = rtl ? parseInt(parentComputedStyle.paddingLeft, 10) : |
| 134 parseInt(parentComputedStyle.paddingRight, 10); |
| 135 |
| 136 // The magic number 14 comes from trial and error :'( It consists of: |
| 137 // border + padding + treeItem.paddingEnd + treeItem.borderEnd + |
| 138 // tree.paddingEnd |
| 139 var max = parentEl.clientWidth - startPos - inner - parentPadding; |
| 140 |
| 141 var pcs = getComputedStyle(parentEl); |
| 142 console.log('pcs', 'borderLeft', pcs.borderLeftWidth, |
| 143 'paddingLeft', pcs.paddingLeft, |
| 144 'paddingRight', pcs.paddingRight, |
| 145 'borderRight', pcs.borderRightWidth, |
| 146 'width', pcs.width, |
| 147 'clientWidth', parentEl.clientWidth, |
| 148 'offsetWidth', parentEl.offsetWidth); |
| 149 |
| 150 function limit() { |
| 151 if (el.scrollWidth > max) { |
| 152 el.style.width = max + 'px'; |
| 153 } else { |
| 154 el.style.width = 0; |
| 155 var sw = el.scrollWidth; |
| 156 if (sw < min) { |
| 157 el.style.width = min + 'px'; |
| 158 } else { |
| 159 el.style.width = sw + 'px'; |
| 160 } |
| 161 } |
| 162 } |
| 163 |
| 164 el.addEventListener('input', limit); |
| 165 limit(); |
| 166 } |
| 167 |
| 168 return { |
| 169 decorate: decorate, |
| 170 define: define, |
| 171 limitInputWidth: limitInputWidth |
| 172 }; |
| 173 }); |
OLD | NEW |