/lib/models/active_object.js

https://github.com/ajanthanm/cssfilterlab · JavaScript · 169 lines · 132 code · 22 blank · 15 comment · 20 complexity · f9c0cf8e7fc7ce6ef654e04350ebfb93 MD5 · raw file

  1. /*
  2. * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. (function() {
  17. function ActiveObject(source, delegate) {
  18. ActiveObject.$super.call(this);
  19. this.delegate = delegate;
  20. this.properties = {};
  21. if (source)
  22. this.loadFromJSON(source);
  23. }
  24. function ActiveCollection(source, delegate) {
  25. ActiveCollection.$super.call(this, source, delegate);
  26. }
  27. Global.Utils.extend(ActiveObject).from(Global.EventDispatcher);
  28. Global.Utils.extend(ActiveCollection).from(ActiveObject);
  29. $.extend(ActiveObject.prototype, {
  30. loadFromJSON: function(source) {
  31. var self = this;
  32. $.each(source, function(key, val) {
  33. if (!self.properties.hasOwnProperty(key))
  34. self.injectSetterMethod(key);
  35. self.properties[key] = self.wrapValue(val);
  36. });
  37. },
  38. injectSetterMethod: function(key) {
  39. Object.defineProperty(this, key, {
  40. get: this.get.bind(this, key),
  41. set: this.set.bind(this, key),
  42. enumerable: true,
  43. configurable: true
  44. });
  45. },
  46. wrapValue: function(val) {
  47. if (val !== null && typeof(val) == "object") {
  48. if (val instanceof Array)
  49. val = new ActiveCollection(val, this);
  50. else if (!(val instanceof ActiveObject))
  51. val = new ActiveObject(val, this);
  52. }
  53. return val;
  54. },
  55. toJSON: function() {
  56. var result = {};
  57. $.each(this.properties, function(key, value) {
  58. if (value && value instanceof ActiveObject)
  59. value = value.toJSON();
  60. result[key] = value;
  61. });
  62. return result;
  63. },
  64. fireRootValueChanged: function() {
  65. var root = this;
  66. while (root.delegate)
  67. root = root.delegate;
  68. root.fire("rootValueChanged");
  69. },
  70. set: function(key, newValue) {
  71. var oldValue = this.properties[key],
  72. hadValue = this.properties.hasOwnProperty(key);
  73. if (!hadValue)
  74. this.injectSetterMethod(key);
  75. this.properties[key] = newValue = this.wrapValue(newValue);
  76. this.fire("propertyChanged." + key, [newValue, oldValue]);
  77. this.fire("propertyChanged", [key, newValue, oldValue]);
  78. if (!hadValue)
  79. this.fire("propertyAdded", [key, newValue]);
  80. this.fireRootValueChanged();
  81. return newValue;
  82. },
  83. get: function(key) {
  84. return this.properties[key];
  85. },
  86. remove: function(key) {
  87. var oldValue = this.properties[key],
  88. hadValue = this.properties.hasOwnProperty(key);
  89. if (!hadValue)
  90. return;
  91. delete this.properties[key];
  92. this.fire("propertyChanged." + key, [null, oldValue]);
  93. this.fire("propertyChanged", [key, null, oldValue]);
  94. this.fire("propertyRemoved", [key, oldValue]);
  95. this.fireRootValueChanged();
  96. return oldValue;
  97. },
  98. bind: function(key, fn) {
  99. fn(this.get(key), null);
  100. return this.on("propertyChanged." + key, fn);
  101. },
  102. unbind: function(key, fn) {
  103. return this.off("propertyChanged." + key, fn);
  104. },
  105. oneWayBind: function(key, el, fn) {
  106. this.bind(key, function(newValue, oldValue) {
  107. var value = el[fn].call(el);
  108. if (oldValue != null && value == newValue)
  109. return;
  110. el[fn].call(el, newValue);
  111. });
  112. return this;
  113. },
  114. twoWayBind: function(key, el, fn, events) {
  115. var self = this;
  116. this.oneWayBind(key, el, fn);
  117. el.bind(events, function() {
  118. var value = el[fn].call(el);
  119. self.set(key, value);
  120. });
  121. return this;
  122. },
  123. bindToTextInput: function(key, el) {
  124. return this.twoWayBind(key, el, "val", "change keyup blur");
  125. },
  126. bindToSelectInput: function(key, el) {
  127. return this.twoWayBind(key, el, "val", "change keyup click blur");
  128. }
  129. });
  130. $.extend(ActiveCollection.prototype, {
  131. loadFromJSON: function(source) {
  132. this.$super.loadFromJSON.call(this, source);
  133. this.set("length", source.length);
  134. },
  135. toJSON: function() {
  136. var result = [];
  137. $.each(this.properties, function(key, value) {
  138. if (value && value instanceof ActiveObject)
  139. value = value.toJSON();
  140. result.push(value);
  141. });
  142. return result;
  143. }
  144. });
  145. Global.ActiveObject = ActiveObject;
  146. Global.ActiveCollection = ActiveCollection;
  147. })();