Requires

Provides

Styles.js

Set, get and render different kind of styles on widget

License:
Public domain (http://unlicense.org).
Authors:
Yaroslaff Fedin
  1. 25
  2. 26
  3. 27
  4. 28
  5. 29
  6. 30
  7. 31
  8. 32
  9. 33
  10. 34
  11. 35
  12. 36
  13. 37
  14. 38
  15. 39
  16. 40
  17. 41
  18. 42
  19. 43
  20. 44
  21. 45
  22. 46
  23. 47
  24. 48
  25. 49
  26. 50
  27. 51
  28. 52
  29. 53
  30. 54
  31. 55
  32. 56
  33. 57
  34. 58
  35. 59
  36. 60
  37. 61
  38. 62
  39. 63
  40. 64
  41. 65
  42. 66
  43. 67
  44. 68
  45. 69
  46. 70
  47. 71
  48. 72
  49. 73
  50. 74
  51. 75
  52. 76
  53. 77
  54. 78
  55. 79
  56. 80
  57. 81
  58. 82
  59. 83
  60. 84
  61. 85
  62. 86
  63. 87
  64. 88
  65. 89
  66. 90
  67. 91
  68. 92
  69. 93
  70. 94
  71. 95
  72. 96
  73. 97
  74. 98
  75. 99
  76. 100
  77. 101
  78. 102
  79. 103
  80. 104
  81. 105
  82. 106
  83. 107
  84. 108
  85. 109
  86. 110
  87. 111
  88. 112
  89. 113
  90. 114
  91. 115
  92. 116
  93. 117
  94. 118
  95. 119
  96. 120
  97. 121
  98. 122
  99. 123
  100. 124
  101. 125
  102. 126
  103. 127
  104. 128
  105. 129
  106. 130
  107. 131
  108. 132
  109. 133
  110. 134
  111. 135
  112. 136
  113. 137
  114. 138
  115. 139
  116. 140
  117. 141
  118. 142
  119. 143
  120. 144
  121. 145
  122. 146
  123. 147
  124. 148
  125. 149
  126. 150
  127. 151
  128. 152
  129. 153
  130. 154
  131. 155
  132. 156
  133. 157
  134. 158
  135. 159
  136. 160
  137. 161
  138. 162
  139. 163
  140. 164
  141. 165
  142. 166
  143. 167
  144. 168
  145. 169
  146. 170
  147. 171
  148. 172
  149. 173
  150. 174
  151. 175
  152. 176
  153. 177
  154. 178
  155. 179
  156. 180
  157. 181
  158. 182
  159. 183
  160. 184
  161. 185
  162. 186
  163. 187
  164. 188
  165. 189
  166. 190
  167. 191
  168. 192
  169. 193
  170. 194
  171. 195
  172. 196
  173. 197
  174. 198
  175. 199
  176. 200
  177. 201
  178. 202
  179. 203
  180. 204
  181. 205
  182. 206
  183. 207
  184. 208
  185. 209
  186. 210
  187. 211
!function() { var CSS = SheetParser.Styles, Paint = LSD.Styles; var setStyle = function(element, property, value, type) { delete this.style.expressed[property]; delete this.style.calculated[property]; if (value === false) { if (element && this.element) delete this.element.style[property]; delete this.style[element ? 'element' : 'paint'][property], this.style.current[property]; if (type) delete this.style[type][property]; } else { if (element && this.element) this.element.style[property] = (typeof value == 'number') ? value + 'px' : value; this.style[element ? 'element' : 'paint'][property] = this.style.current[property] = value; if (type) this.style[type][property] = value; } } LSD.Module.Styles = new Class({ options: { styles: {}, events: { _styles: { update: function() { this.style.calculated = {}; this.style.computed = {}; } } } }, initialize: function() { this.style = { current: {}, //styles that widget currently has found: {}, //styles that were found in stylesheets given: {}, //styles that were manually assigned changed: {}, //styles that came from stylesheet since last render calculated: {}, //styles that are calculated in runtime computed: {}, //styles that are already getStyled expressed: {}, //styles that are expressed through function implied: {}, //styles that are assigned by environment element: {}, //styles that are currently assigned to element paint: {} //styles that are currently used to paint }; this.rules = []; this.parent.apply(this, arguments); Object.append(this.style.current, this.options.styles); for (var property in this.style.current) this.setStyle(property, this.style.current[property]) }, setStyle: function(property, value) { var paint, css; if (!(paint = Paint[property]) && !(css = CSS[property])) return false; var length = arguments.length; if (length > 2) { if (arguments[length - 1] in this.style) var type = arguments[--length]; if (length > 2) value = Array.prototype.splice.call(arguments, 1, length); } if (value.call) { var expression = value; value = value.call(this, property); } var result = (css || paint)[value.push ? 'apply' : 'call'](this, value); if (property == 'stroke') console.info(value, result, $t = this, this.element); if (result === true || result === false) setStyle.call(this, css, property, value, type); else for (var prop in result) setStyle.call(this, css, prop, result[prop], type); if (expression) { this.style.expressed[property] = expression this.style.computed[property] = value } return result; }, setStyles: function(style, type) { for (var key in style) this.setStyle(key, style[key], type) }, getStyle: function(property) { if (this.style.computed[property]) return this.style.computed[property]; var value; var definition = Paint[property] || CSS[property]; if (!definition) return; if (definition.properties) return definition.properties.map(this.getStyle.bind(this)); var expression = this.style.expressed[property]; if (expression) { value = this.style.current[property] = this.calculateStyle(property, expression); } else { value = this.style.current[property]; if (property == 'height') { if (typeof value !== 'number') value = this.getClientHeight(); } else if (property == 'width') { if (typeof value !== 'number') value = this.getClientWidth(); } else { if (value == "inherit") value = this.inheritStyle(property); if (value == "auto") value = this.calculateStyle(property); } } this.style.computed[property] = value; return value; }, getStyles: function(properties) { var result = {}; for (var i = 0, property, args = arguments; property = args[i++];) result[property] = this.getStyle(property); return result; }, renderStyles: function(styles) { var style = this.style, current = style.current, paint = style.paint, element = style.element, found = style.found, implied = style.implied, calculated = style.calculated, given = Object.append(style.given, styles), changed = style.changed; this.setStyles(given, 'given') for (var property in found) if ((property in changed) && !(property in given)) this.setStyle(property, found[property]); Object.append(style.current, style.implied); for (var property in element) { if (!(property in given) && !(property in found) && !(property in calculated) && !(property in implied)) { this.element.style[property] = ''; delete element[property] } } for (var property in current) { if (!(property in given) && !(property in found) && !(property in calculated) && !(property in implied)) { delete current[property]; delete paint[property]; } } }, combineRules: function(rule) { var rules = this.rules, style = this.style, found = style.found = {}, implied = style.implied = {}, changed = style.changed; for (var j = rules.length, other; other = rules[--j];) { var setting = other.style, implying = other.implied, self = (rule == other); if (setting) for (var property in setting) if (!(property in found)) { if (self) changed[property] = setting[property]; found[property] = setting[property]; } if (implying) for (var property in implying) if (!(property in implied)) implied[property] = implying[property]; } }, addRule: function(rule) { var rules = this.rules; if (rules.indexOf(rule) > -1) return for (var i = 0, other; other = rules[i++];) { if ((other.specificity > rule.specificity) || ((other.specificity == rule.specificity) && (other.index > rule.index))) break; } rules.splice(--i, 0, rule); this.combineRules(rule); }, removeRule: function(rule) { var rules = this.rules, index = rules.indexOf(rule) if (index == -1) return rules.splice(index, 1); this.combineRules(); var style = this.style, found = style.found, changed = style.changed, setting = rule.style; if (setting) for (var property in setting) if (!Object.equals(found[property], setting[property])) changed[property] = found[property]; }, inheritStyle: function(property) { var node = this; var style = node.style.current[property]; while ((style == 'inherit' || !style) && (node = node.parentNode)) style = node.style.current[property]; return style; }, calculateStyle: function(property, expression) { if (this.style.calculated[property]) return this.style.calculated[property]; var value; if (expression) { value = expression.call(this, property); } else { switch (property) { case "height": value = this.getClientHeight(); case "width": value = this.inheritStyle(property); if (value == "auto") value = this.getClientWidth(); case "height": case "width":

if dimension size is zero, then the widget is not in DOM yet so we wait until the root widget is injected, and then try to repeat

  1. 214
  2. 215
  3. 216
  4. 217
  5. 218
  6. 219
  7. 220
  8. 221
  9. 222
  10. 223
  11. 224
  12. 225
  13. 226
  14. 227
  15. 228
if (value == 0 && (this.redraws == 0)) this.halt(); } } this.style.calculated[property] = value; return value; }, render: function(style) { this.renderStyles(style); this.parent.apply(this, arguments); } }); }();