PageRenderTime 24ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/qooxdoo/framework/source/class/qx/bom/element/Attribute.js

https://github.com/Wkasel/qooxdoo
JavaScript | 389 lines | 211 code | 42 blank | 136 comment | 37 complexity | 72c4caa6cff9098fec993d4b5de59842 MD5 | raw file
  1. /* ************************************************************************
  2. qooxdoo - the new era of web development
  3. http://qooxdoo.org
  4. Copyright:
  5. 2004-2010 1&1 Internet AG, Germany, http://www.1und1.de
  6. License:
  7. LGPL: http://www.gnu.org/licenses/lgpl.html
  8. EPL: http://www.eclipse.org/org/documents/epl-v10.php
  9. See the LICENSE file in the project's top-level directory for details.
  10. Authors:
  11. * Sebastian Werner (wpbasti)
  12. * Alexander Steitz (aback)
  13. ======================================================================
  14. This class contains code based on the following work:
  15. * Prototype JS
  16. http://www.prototypejs.org/
  17. Version 1.5
  18. Copyright:
  19. (c) 2006-2007, Prototype Core Team
  20. License:
  21. MIT: http://www.opensource.org/licenses/mit-license.php
  22. Authors:
  23. * Prototype Core Team
  24. ----------------------------------------------------------------------
  25. Copyright (c) 2005-2008 Sam Stephenson
  26. Permission is hereby granted, free of charge, to any person
  27. obtaining a copy of this software and associated documentation
  28. files (the "Software"), to deal in the Software without restriction,
  29. including without limitation the rights to use, copy, modify, merge,
  30. publish, distribute, sublicense, and/or sell copies of the Software,
  31. and to permit persons to whom the Software is furnished to do so,
  32. subject to the following conditions:
  33. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  34. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  35. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  36. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  37. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  38. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  39. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  40. DEALINGS IN THE SOFTWARE.
  41. ************************************************************************ */
  42. /**
  43. * Attribute/Property handling for DOM HTML elements.
  44. *
  45. * Also includes support for HTML properties like <code>checked</code>
  46. * or <code>value</code>. This feature set is supported cross-browser
  47. * through one common interface and is independent of the differences between
  48. * the multiple implementations.
  49. *
  50. * Supports applying text and HTML content using the attribute names
  51. * <code>text</code> and <code>html</code>.
  52. */
  53. qx.Class.define("qx.bom.element.Attribute",
  54. {
  55. /*
  56. *****************************************************************************
  57. STATICS
  58. *****************************************************************************
  59. */
  60. statics :
  61. {
  62. /** Internal map of attribute conversions */
  63. __hints :
  64. {
  65. // Name translation table (camelcase is important for some attributes)
  66. names :
  67. {
  68. "class" : "className",
  69. "for" : "htmlFor",
  70. html : "innerHTML",
  71. text : (qx.core.Environment.get("engine.name") == "mshtml") ? "innerText" : "textContent",
  72. colspan : "colSpan",
  73. rowspan : "rowSpan",
  74. valign : "vAlign",
  75. datetime : "dateTime",
  76. accesskey : "accessKey",
  77. tabindex : "tabIndex",
  78. maxlength : "maxLength",
  79. readonly : "readOnly",
  80. longdesc : "longDesc",
  81. cellpadding : "cellPadding",
  82. cellspacing : "cellSpacing",
  83. frameborder : "frameBorder",
  84. usemap : "useMap"
  85. },
  86. // Attributes which are only applyable on a DOM element (not using compile())
  87. runtime :
  88. {
  89. "html" : 1,
  90. "text" : 1
  91. },
  92. // Attributes which are (forced) boolean
  93. bools :
  94. {
  95. compact : 1,
  96. nowrap : 1,
  97. ismap : 1,
  98. declare : 1,
  99. noshade : 1,
  100. checked : 1,
  101. disabled : 1,
  102. readOnly : 1,
  103. multiple : 1,
  104. selected : 1,
  105. noresize : 1,
  106. defer : 1,
  107. allowTransparency : 1
  108. },
  109. // Interpreted as property (element.property)
  110. property :
  111. {
  112. // Used by qx.html.Element
  113. $$html : 1,
  114. // Used by qx.ui.core.Widget
  115. $$widget : 1,
  116. // Native properties
  117. disabled : 1,
  118. checked : 1,
  119. readOnly : 1,
  120. multiple : 1,
  121. selected : 1,
  122. value : 1,
  123. maxLength : 1,
  124. className : 1,
  125. innerHTML : 1,
  126. innerText : 1,
  127. textContent : 1,
  128. htmlFor : 1,
  129. tabIndex : 1
  130. },
  131. qxProperties :
  132. {
  133. $$widget : 1,
  134. $$html : 1
  135. },
  136. // Default values when "null" is given to a property
  137. propertyDefault :
  138. {
  139. disabled : false,
  140. checked : false,
  141. readOnly : false,
  142. multiple : false,
  143. selected : false,
  144. value : "",
  145. className : "",
  146. innerHTML : "",
  147. innerText : "",
  148. textContent : "",
  149. htmlFor : "",
  150. tabIndex : 0,
  151. maxLength: qx.core.Environment.select("engine.name", {
  152. "mshtml" : 2147483647,
  153. "webkit": 524288,
  154. "default": -1
  155. })
  156. },
  157. // Properties which can be removed to reset them
  158. removeableProperties :
  159. {
  160. disabled: 1,
  161. multiple: 1,
  162. maxLength: 1
  163. },
  164. // Use getAttribute(name, 2) for these to query for the real value, not
  165. // the interpreted one.
  166. original :
  167. {
  168. href : 1,
  169. src : 1,
  170. type : 1
  171. }
  172. },
  173. /**
  174. * Compiles an incoming attribute map to a string which
  175. * could be used when building HTML blocks using innerHTML.
  176. *
  177. * This method silently ignores runtime attributes like
  178. * <code>html</code> or <code>text</code>.
  179. *
  180. * @param map {Map} Map of attributes. The key is the name of the attribute.
  181. * @return {String} Returns a compiled string ready for usage.
  182. */
  183. compile : function(map)
  184. {
  185. var html = [];
  186. var runtime = this.__hints.runtime;
  187. for (var key in map)
  188. {
  189. if (!runtime[key]) {
  190. html.push(key, "='", map[key], "'");
  191. }
  192. }
  193. return html.join("");
  194. },
  195. /**
  196. * Returns the value of the given HTML attribute
  197. *
  198. * @param element {Element} The DOM element to query
  199. * @param name {String} Name of the attribute
  200. * @return {var} The value of the attribute
  201. * @signature function(element, name)
  202. */
  203. get : qx.core.Environment.select("engine.name",
  204. {
  205. "mshtml" : function(element, name)
  206. {
  207. var hints = this.__hints;
  208. var value;
  209. // normalize name
  210. name = hints.names[name] || name;
  211. // respect original values
  212. // http://msdn2.microsoft.com/en-us/library/ms536429.aspx
  213. if (hints.original[name]) {
  214. value = element.getAttribute(name, 2);
  215. }
  216. // respect properties
  217. else if (hints.property[name])
  218. {
  219. value = element[name];
  220. if (typeof hints.propertyDefault[name] !== "undefined" &&
  221. value == hints.propertyDefault[name])
  222. {
  223. // only return null for all non-boolean properties
  224. if (typeof hints.bools[name] === "undefined") {
  225. return null;
  226. } else {
  227. return value;
  228. }
  229. }
  230. } else { // fallback to attribute
  231. value = element.getAttribute(name);
  232. }
  233. // TODO: Is this enough, what's about string false values?
  234. if (hints.bools[name]) {
  235. return !!value;
  236. }
  237. return value;
  238. },
  239. // currently supported by gecko, opera and webkit
  240. "default" : function(element, name)
  241. {
  242. var hints = this.__hints;
  243. var value;
  244. // normalize name
  245. name = hints.names[name] || name;
  246. // respect properties
  247. if (hints.property[name])
  248. {
  249. value = element[name];
  250. if (typeof hints.propertyDefault[name] !== "undefined" &&
  251. value == hints.propertyDefault[name])
  252. {
  253. // only return null for all non-boolean properties
  254. if (typeof hints.bools[name] === "undefined") {
  255. return null;
  256. } else {
  257. return value;
  258. }
  259. }
  260. } else { // fallback to attribute
  261. value = element.getAttribute(name);
  262. }
  263. // TODO: Is this enough, what's about string false values?
  264. if (hints.bools[name]) {
  265. return !!value;
  266. }
  267. return value;
  268. }
  269. }),
  270. /**
  271. * Sets an HTML attribute on the given DOM element
  272. *
  273. * @param element {Element} The DOM element to modify
  274. * @param name {String} Name of the attribute
  275. * @param value {var} New value of the attribute
  276. * @return {void}
  277. */
  278. set : function(element, name, value)
  279. {
  280. if (typeof value === "undefined") {
  281. return;
  282. }
  283. var hints = this.__hints;
  284. // normalize name
  285. name = hints.names[name] || name;
  286. // respect booleans
  287. if (hints.bools[name]) {
  288. value = !!value;
  289. }
  290. // apply attribute
  291. // only properties which can be applied by the browser or qxProperties
  292. // otherwise use the attribute methods
  293. if (hints.property[name] && (!(element[name] === undefined) || hints.qxProperties[name]))
  294. {
  295. // resetting the attribute/property
  296. if (value == null)
  297. {
  298. // for properties which need to be removed for a correct reset
  299. if (hints.removeableProperties[name])
  300. {
  301. element.removeAttribute(name);
  302. return;
  303. } else if (typeof hints.propertyDefault[name] !== "undefined") {
  304. value = hints.propertyDefault[name];
  305. }
  306. }
  307. element[name] = value;
  308. }
  309. else
  310. {
  311. if (value === true) {
  312. element.setAttribute(name, name);
  313. } else if (value === false || value === null) {
  314. element.removeAttribute(name);
  315. } else {
  316. element.setAttribute(name, value);
  317. }
  318. }
  319. },
  320. /**
  321. * Resets an HTML attribute on the given DOM element
  322. *
  323. * @param element {Element} The DOM element to modify
  324. * @param name {String} Name of the attribute
  325. * @return {void}
  326. */
  327. reset : function(element, name) {
  328. this.set(element, name, null);
  329. }
  330. }
  331. });