source: gs3-extensions/seaweed-debug/trunk/src/MVC.js@ 25160

Last change on this file since 25160 was 25160, checked in by sjm84, 12 years ago

Initial cut at a version of seaweed for debugging purposes. Check it out live into the web/ext folder

File size: 5.4 KB
Line 
1/*
2 * file: MVC.js
3 *
4 * @BEGINLICENSE
5 * Copyright 2010 Brook Novak (email : [email protected])
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 * @ENDLICENSE
18 */
19bootstrap.provides("MVC");
20
21/**
22 * Extends the given instance into a model (wrt MVC).
23 *
24 * @param {Object} subject The subject containing model data to be observed.
25 */
26function _model(subject) {
27
28 // The list of registered observers for this subject
29 var observers = [],
30 observersToRemove; // Zeroed/undef when not firing event, array when model is firing event.
31
32 $extend(subject, {
33
34 /**
35 *
36 * Notifies all observers that a specific event occured.
37 *
38 * @param {String} event The event name to fire (excluding the "on" prefix).
39 * For example, "KeyDown" would invoke "onKeyDown" in all observers
40 *
41 * @param {Object} details Optional custom details data
42 */
43 fireEvent: function(event){
44
45 if (observers.length > 0) {
46
47 // Construct additional arguments array
48 var i,
49 observer,
50 remObservers,
51 args = Array.prototype.slice.call(arguments);
52
53 args.shift();
54
55 // Flag this model as firing
56 observersToRemove = [];
57
58 // Fire events on each observer
59 for (i in observers) {
60 observer = observers[i];
61
62 // If the observer has declared a listener function for this event invoke it
63 if (typeof observer.ref["on" + event] == "function")
64 observer.ref["on" + event].apply(observer.context, args);
65 }
66
67 // Reset flag
68 remObservers = observersToRemove;
69 observersToRemove = 0;
70
71 // If Observers when trying to remove themself during an event fire
72 // then safely remove them now.
73 for (i in remObservers) {
74 this.removeObserver(remObservers[i]);
75 }
76
77 }
78 },
79
80 /**
81 * Adds an observer for receiving event notifications.
82 * If the observer already exists in the observer set it will not be added twice.
83 *
84 * @param {Object} observer An observer to add to the set.
85 *
86 * @param {Object} context (Optional) The context at which the events should be invoked in.
87 * Will default to the observer object.
88 *
89 * @param {Boolean} notifiedFirst (Optional) True to be the first observer to be notified in the current list.
90 * Otherwise it will be added to the end of the list
91 */
92 addObserver: function(observer, context, notifiedFirst){
93
94 // Ensure that observer array is a set
95 if (observerIndex(observer) != -1)
96 return;
97
98 // Create observer instance
99 observer = {
100 ref : observer,
101 context : context || observer
102 };
103
104 // Add to list depending on requested order
105 if (notifiedFirst) observers.unshift(observer);
106 else observers.push(observer);
107
108 },
109
110 /**
111 * Removes an observer from the subjects observer list.
112 *
113 * @param {Object} observer An observer to remove from the set
114 */
115 removeObserver: function(observer) {
116
117 // Avoid removing observers while in a firing-event state since some browsers
118 // may miss firing an event on a observer if the observer list is sliced while iterating the list
119 if (observersToRemove)
120 observersToRemove.push(observer); // Will be removed after firing of events finished
121
122 else {
123 var index = observerIndex(observer);
124 if (index >= 0) observers.splice(index, 1);
125 }
126 }
127 });
128
129 /**
130 * @param {Object} observerRef The observer reference to check
131 *
132 * @return {Number} The index in the observers array at which observerRef exists.
133 * -1 if not found.
134 */
135 function observerIndex(observerRef) {
136 for (var i = 0; i < observers.length; i++) {
137 if (observers[i].ref == observerRef)
138 return i;
139 }
140 return -1;
141 }
142
143}
144
145/**
146 * Exposure of model internal
147 * @see _model
148 */
149de.model = _model;
150
Note: See TracBrowser for help on using the repository browser.