sports_db 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/app/assets/javascripts/clients/android/client.js +53 -0
  2. data/app/assets/javascripts/clients/ios/client.js +58 -0
  3. data/app/assets/javascripts/core/Application.js +173 -0
  4. data/app/assets/javascripts/core/BaseView.js +117 -0
  5. data/app/assets/javascripts/core/History.js +45 -0
  6. data/app/assets/javascripts/core/Mock.js +90 -0
  7. data/app/assets/javascripts/core/Timer.js +18 -0
  8. data/app/assets/javascripts/core/View.js +56 -0
  9. data/app/assets/javascripts/core/utilities.js +81 -0
  10. data/app/assets/javascripts/libs/SimpleInheritance.js +53 -0
  11. data/app/assets/javascripts/libs/microjungle.zepto.js +45 -0
  12. data/app/assets/javascripts/libs/zepto-v1.0rc1/ajax.js +279 -0
  13. data/app/assets/javascripts/libs/zepto-v1.0rc1/assets.js +21 -0
  14. data/app/assets/javascripts/libs/zepto-v1.0rc1/data.js +66 -0
  15. data/app/assets/javascripts/libs/zepto-v1.0rc1/detect.js +40 -0
  16. data/app/assets/javascripts/libs/zepto-v1.0rc1/event.js +224 -0
  17. data/app/assets/javascripts/libs/zepto-v1.0rc1/form.js +40 -0
  18. data/app/assets/javascripts/libs/zepto-v1.0rc1/fx.js +91 -0
  19. data/app/assets/javascripts/libs/zepto-v1.0rc1/fx_methods.js +72 -0
  20. data/app/assets/javascripts/libs/zepto-v1.0rc1/gesture.js +35 -0
  21. data/app/assets/javascripts/libs/zepto-v1.0rc1/polyfill.js +36 -0
  22. data/app/assets/javascripts/libs/zepto-v1.0rc1/selector.js +70 -0
  23. data/app/assets/javascripts/libs/zepto-v1.0rc1/stack.js +22 -0
  24. data/app/assets/javascripts/libs/zepto-v1.0rc1/touch.js +85 -0
  25. data/app/assets/javascripts/libs/zepto-v1.0rc1/zepto.js +591 -0
  26. data/app/assets/javascripts/libs/zepto_0.8.js +1213 -0
  27. data/app/assets/javascripts/plugins/assert.js +11 -0
  28. data/app/assets/javascripts/plugins/calnav.js +18 -0
  29. data/app/assets/javascripts/plugins/detect.js +16 -0
  30. data/app/assets/javascripts/plugins/filterable.js +12 -0
  31. data/app/assets/javascripts/plugins/flash.js +15 -0
  32. data/app/assets/javascripts/plugins/jquery.zumobi-0.2.js +57 -0
  33. data/app/assets/javascripts/plugins/loading.js +47 -0
  34. data/app/assets/javascripts/plugins/params.js +27 -0
  35. data/app/assets/javascripts/plugins/resizeable.js +40 -0
  36. data/app/assets/stylesheets/_base.css.scss +42 -0
  37. data/app/assets/stylesheets/_filterable.css.scss +19 -0
  38. data/app/assets/stylesheets/_flash.css.scss +9 -0
  39. data/app/assets/stylesheets/_loading.css.scss +28 -0
  40. data/app/assets/stylesheets/_play.css.scss +38 -0
  41. data/app/assets/stylesheets/_reset.css.scss +33 -0
  42. data/app/assets/stylesheets/_table_base.scss +121 -0
  43. data/app/assets/stylesheets/mock.css.scss +52 -0
  44. data/app/controllers/application_controller.rb +39 -0
  45. data/app/views/application/load.html.erb +1 -0
  46. data/app/views/layouts/application.html.erb +27 -0
  47. data/lib/sports_db/version.rb +1 -1
  48. metadata +90 -5
@@ -0,0 +1,53 @@
1
+ if ($.client.android) {
2
+ console.log('=> Using AndroidClient.js');
3
+
4
+ // This should be in a mock file...
5
+ if (!window.ClientBridge) {
6
+ window.ClientBridge = {
7
+ notify: function(obj) {
8
+ window.console.debug(obj);
9
+ }
10
+ };
11
+ }
12
+
13
+ var Client = Class.extend({
14
+ initialize: function() {
15
+
16
+ },
17
+ /**
18
+ * Called by the web application to send values to the client.
19
+ *
20
+ * @param {Object} obj - a set of key/value parameters to send to client
21
+ */
22
+ notify: function(obj) {
23
+ var arr = [];
24
+ for (var prop in obj) {
25
+ arr.push(prop +'='+ encodeURIComponent(obj[prop]));
26
+ }
27
+ ClientBridge.notify( arr.join('&') );
28
+ },
29
+
30
+ /**
31
+ * Called by the client to set a value or trigger an action in the web page.
32
+ *
33
+ * @param {String} name
34
+ * @param {Object} value (optional)
35
+ */
36
+ callback: function(name, value) {
37
+ Application.onClientCallback(name, value);
38
+ }
39
+ });
40
+
41
+ // Singleton
42
+ Client = new Client();
43
+
44
+ // Fix console as it doesn't appear to exist in Android WebView, and we frequently leave these statements in our code
45
+ if (!window.console) {
46
+ window.console = {};
47
+ var f = function() {};
48
+ ["debug", "info", "warn", "error", "assert", "dir", "dirxml", "trace", "group", "groupCollapsed",
49
+ "groupEnd", "time", "timeEnd", "profile", "profileEnd", "count"].forEach(function(func) {
50
+ window.console[func] = f;
51
+ });
52
+ }
53
+ }
@@ -0,0 +1,58 @@
1
+ if ($.client.ios) {
2
+ console.log('=> Using iOSClient.js');
3
+
4
+ var Client = Class.extend({
5
+ // Called by the web application to send values to the client.
6
+ //
7
+ // @param {Object} obj - a set of key/value parameters to send to client
8
+ notify: function(obj) {
9
+ if (top.location === self.location) {
10
+ this._createUrlForClientInterception("client_notify", obj);
11
+ }
12
+ },
13
+ // Called by the client to set a value or trigger an action in the web page.
14
+ //
15
+ // @param {String} name
16
+ // @param {Object} value (optional)
17
+ callback: function(name, value) {
18
+ Application.onClientCallback(name, value);
19
+ },
20
+ _createUrlForClientInterception: function(prefix, obj) {
21
+ this._initClientTransportIfNecessary(prefix);
22
+ for (var prop in obj) {
23
+ if (typeof obj[prop] !== 'function') {
24
+ var input = document.createElement("input");
25
+ input.type = "hidden";
26
+ input.name = prop;
27
+ // these do not need to be encoded, because the form does this for us.
28
+ input.value = obj[prop];
29
+ this.form.appendChild(input);
30
+ }
31
+ }
32
+ // prevent embedded iframe from being source of further events.
33
+ if (top.location === self.location) {
34
+ this.form.submit();
35
+ }
36
+ },
37
+ _initClientTransportIfNecessary: function(prefix) {
38
+ if (this.iframe === null || this.iframe === undefined) {
39
+ this.iframe = document.createElement("iframe");
40
+ this.iframe.name = "postit";
41
+ this.iframe.setAttribute("style", "position:absolute; left:-1000px; top:-100px;");
42
+ this.iframe.width = this.iframe.height = 10;
43
+ document.body.appendChild(this.iframe);
44
+
45
+ this.form = document.createElement("form");
46
+ this.form.target = "postit";
47
+ this.form.style.visibility = "hidden";
48
+ this.form.style.position = "absolute";
49
+ document.body.appendChild(this.form);
50
+ }
51
+ this.form.action = prefix;
52
+ this.form.innerHTML = "";
53
+ }
54
+ });
55
+
56
+ // Singleton
57
+ Client = new Client();
58
+ }
@@ -0,0 +1,173 @@
1
+ var Application = Class.extend({
2
+ initialize: function() {
3
+ this.app_is_initializing = true;
4
+ this.views = {};
5
+ this.params = {};
6
+ this.cache = {};
7
+ this.currentView = null;
8
+ this.clientCallbackHandlers = [];
9
+ this.params = {};
10
+
11
+ // Get hash params
12
+ if (window.location.hash) {
13
+ this.params = $.hashStrToObj();
14
+ }
15
+
16
+ // I'm not reallys ure we want to store these together, but whatever (For now)
17
+ this.params = $.extend(window.CONFIG, this.params);
18
+
19
+ // Start timer for game updates
20
+ // TODO only run this on game views
21
+ this.timer = new Timer($.proxy(this._fireTimerEvent, this), this.params.GAME_UPDATE_FREQUENCY);
22
+ this.timer.start();
23
+ },
24
+ // Fire a timer event
25
+ _fireTimerEvent: function() {
26
+ $(document.body).trigger("timerReachInterval", false, false);
27
+ },
28
+ // Call the view if the method exists
29
+ _onTimerReachedInterval: function() {
30
+ var view = this.currentView;
31
+ if (view && view._onTimerReachedInterval) {
32
+ view._onTimerReachedInterval.call(view);
33
+ }
34
+ },
35
+ // Register a view constructor under a specific name. If a link in the application has
36
+ // a parameter named "view" that points to a registered view name, then the `Application`
37
+ // will load that view. Optionally, you can pass in parameters, and these will be merged
38
+ // with any other parameters in the link that triggers view loading (parameters in the
39
+ // link override parameters in the registration binding). This allows you to bind the
40
+ // same view under different names with different parameters in order to parameterize
41
+ // its behavior.
42
+ //
43
+ // @param {Object} name
44
+ // @param {Object} constructor
45
+ // @param {Object} params (optional)
46
+ registerView: function(name, constructor, params) {
47
+ this.views[name] = { constructor: constructor, params: (params || {}) };
48
+ },
49
+ // Stash a view, i.e. change the url to something meaningful, but do not show the
50
+ // view based on this URL change. This is needed in cases where the device goes to
51
+ // sleep, and then reloads upon awakening.
52
+ stashView: function(params) {
53
+ var local = {};
54
+ local.view = params.view;
55
+ if (params.filter) { local.filter = params.filter; }
56
+ if (params.key) { local.key = params.key; }
57
+ local.stash = true;
58
+ var url = "#" + $.objToQueryStr(local);
59
+
60
+ document.location = url;
61
+ },
62
+ // Show a view based on the supplied parameters. The only required parameter is "view"
63
+ // which must reference a valid view name.
64
+ //
65
+ // @param {Object} params
66
+ showView: function(params) {
67
+ $.assert(params.view, "No view specified (use #view=<viewName>)", "Error: no view specified.");
68
+ var binding = this.views[params.view];
69
+
70
+ $.assert(binding, params.view + " is not a registered view name. Did you add it to views.js?", "Error: not a registered view.");
71
+
72
+ // Merge binding parameters (from views.js) into any parameters that were supplied in the URL
73
+ for (var prop in binding.params) {
74
+ if (typeof params[prop] === 'undefined') {
75
+ params[prop] = binding.params[prop];
76
+ }
77
+ }
78
+ var view = new binding.constructor(params);
79
+ $.assert(view.create, params.view + " doesn't have a create method and is not a valid view", "Error: not a valid view.");
80
+
81
+ view.create();
82
+ },
83
+ // When the view is done initializing, it must call this method.
84
+ appendView: function(view) {
85
+ view.beforeViewAppended(view.params);
86
+ view.buffer.html('empty');
87
+
88
+ // if we have a reference to the previous view, remove() it
89
+ if (this.currentView && this.currentView.element) {
90
+ $(this.currentView.element).remove();
91
+ }
92
+
93
+ // re-assign this.curentView to the new view, and add it to the
94
+ // Application.cache
95
+ this.currentView = this.cache[History.currentHash()] = view;
96
+
97
+ document.body.appendChild(view.element);
98
+
99
+ if (view.params.scrollY) {
100
+ window.scrollTo(0,view.params.scrollY);
101
+ this.params.scrollY = 0;
102
+ } else {
103
+ window.scrollTo(0,0);
104
+ }
105
+ $.alignLoader();
106
+
107
+ view.afterViewAppended(view.params);
108
+
109
+ $(view.element).addClass('cached');
110
+ if (!view.params.skip_metrics === true) this.sendMetrics();
111
+ },
112
+ sendMetrics: function() {
113
+ var view = Application.currentView;
114
+ Client.notify({
115
+ "metric": view.getMetric(),
116
+ "title": view.getTitle(),
117
+ "buttons": view.getButtons(),
118
+ "action": view.getAction(),
119
+ "filter": view.getFilter(),
120
+ "section": view.getSection()
121
+ });
122
+ },
123
+ // The web application is receiving a callback from the client to set a value or execute some
124
+ // behavior. If the view has an `onClientCallback` method, this will be executed first. It can
125
+ // cancel any further event handling by returning `true`. Otherwise, the application sends the
126
+ // event to all of the `clientCallbackHandlers` that are registered with the application, in the
127
+ // order they were registered.
128
+ //
129
+ // @param {String} name
130
+ // @param {Object} value
131
+ onClientCallback: function(name, value) {
132
+ var handled = false;
133
+ var view = this.currentView;
134
+ if (view && view.onClientCallback) {
135
+ handled = view.onClientCallback.call(view, name, value);
136
+ }
137
+ if (!handled) {
138
+ this.clientCallbackHandlers.forEach(function(handler) {
139
+ handler.call(this, name, value);
140
+ }, this);
141
+ }
142
+ },
143
+ // load a view from cache or the server when we get a hashchange event
144
+ _onHashChange: function(event, data) {
145
+ // If the app is not initializing, and the view is stashed, do not do anything
146
+ if (!this.app_is_initializing && data.stash) {
147
+ console.log('=> App is not initializing & a view is stashed. RETURN');
148
+ return;
149
+ }
150
+
151
+ $.assert(data.view, "No view specified (use #view=<viewName>)", "Error: no view specified.");
152
+
153
+ var view = this.cache[History.currentHash()];
154
+ view ? this.appendView(view) : this.showView(data);
155
+
156
+ this.app_is_initializing = false;
157
+ },
158
+ // Initializes application functionality on page load, and kicks off loading the view.
159
+ //
160
+ // @private
161
+ _onReady: function() {
162
+ $(document.body)
163
+ .on("hashchange", $.proxy(Application._onHashChange, this))
164
+ .on("timerReachInterval", $.proxy(Application._onTimerReachedInterval, this));
165
+ }
166
+ });
167
+
168
+ // Singleton.
169
+ Application = new Application();
170
+
171
+ Zepto(function($) {
172
+ Application._onReady();
173
+ });
@@ -0,0 +1,117 @@
1
+ // A basic view implementation that expects an `URL` to be passed as one of the parameters
2
+ // to the view; it will format that `URL` using any other parameters, and use it to retrieve
3
+ // an `HTML` fragment from the server. This is only one of many strategies that could be
4
+ // followed to create views, of course. It also assumes that the parameters object will
5
+ // get a title property.
6
+ var BaseView = View.extend({
7
+ // Subclasses must ensure there is an url property to the parameter object passed
8
+ // into this superconstructor, i.e.:
9
+ //
10
+ // this._super(params)
11
+ //
12
+ // Any parameters passed in to the view constructor will be substituted
13
+ // into the URL string using the String format method (see utilities.js).
14
+ //
15
+ // @param {Object} params
16
+ initialize: function(params) {
17
+ this.url = this.getUrl(params);
18
+ this.params = params;
19
+ this.buffer = Application.params.BUFFER_EL;
20
+ },
21
+ getUrl: function(params) {
22
+ if (params.url) {
23
+ return params.url.format(params);
24
+ } else {
25
+ return "/" + Application.params.APP_NAME + "/" + params.view;
26
+ }
27
+ },
28
+ getTitle: function() {
29
+ // The title varies on the Team View between Android and iOS.
30
+ // cstuart 2011-08-29
31
+ if ($.client.ios) {
32
+ this.params.title = this.params.ios_title || this.params.title;
33
+ }
34
+ return this.params.title || this.params.view.capitalize();
35
+ },
36
+ getMetric: function() {
37
+ return this.params.metric || "/" + this.params.view.capitalize();
38
+ },
39
+ getButtons: function() {
40
+ return this.params.buttons || "Back:";
41
+ },
42
+ getAction: function() {
43
+ return this.params.action || "<None>";
44
+ },
45
+ getFilter: function() {
46
+ return this.params.filter || "<None>";
47
+ },
48
+ getSection: function() {
49
+ return this.params.view;
50
+ },
51
+ // Loads the content of the view from the server (the content should be wrapped by a `div`).
52
+ // The content is inserted into the page.
53
+ create: function() {
54
+ var view = this;
55
+
56
+ // This is a hack. The TSN keys include periods that confuse the Rails page caching system. Convert
57
+ // here to underscores, and back to periods again on the server using a filter.
58
+ view.url = view.url.replace(/\./g,"_");
59
+
60
+ function onError() {
61
+ var params = {};
62
+ // The old currentView won't exist in the case of a 404 or
63
+ // other server error.
64
+ if (Application.currentView && Application.currentView.params) {
65
+ params = Application.currentView.params;
66
+ }
67
+ $.hideLoader();
68
+ $.flash("A network error occurred.", params, true);
69
+ throw new Error('An error occurred.');
70
+ }
71
+ $.showLoader();
72
+ $.ajax({
73
+ url: view.url,
74
+ success: function(response) {
75
+ // If the server is unreachable, zepto calls `success`
76
+ // and then the `response` is empty. Catch it here and throw an error.
77
+ if (response === "") onError();
78
+
79
+ var response = $.highResifyLogosForRetinaAndAndroid(response);
80
+
81
+ view.buffer.html(response);
82
+ view.element = view.buffer.find('div').get(0);
83
+ view._evaluateDataAttribute();
84
+ Application.appendView(view);
85
+ $.hideLoader();
86
+ $.delayedLoad();
87
+ },
88
+ error: function() {
89
+ onError();
90
+ }
91
+ });
92
+ },
93
+ onClientCallback: function(name, value) {
94
+ console.log('BaseView.onClientCallback({' + name + ': ' + value + '})');
95
+ },
96
+ // If HTML returned from the server includes a `<data id="view_data" data=""></data>` element,
97
+ // this should contain an object literal (JSON string) with values that will be merged into
98
+ // the parameters for this view instance. This is used to pass back additional information
99
+ // from the server via the HTML. For example, when loading a player it might be useful to
100
+ // return the key for the player's team so that can be used when communicating with the client:
101
+ //
102
+ // <data id="view_data" data="{'title': '<%= @team.city_name %> <%= @team.team_name %>'}"></data>
103
+ //
104
+ // This will add the integer 1588 (correctly typed) under the property "team_key" to the
105
+ // parameters (`this.params`) for this view.
106
+ _evaluateDataAttribute: function() {
107
+ var view_data_el = Application.params.BUFFER_EL.find("#view_data");
108
+ if (view_data_el.size() === 0) return;
109
+ if (!view_data_el.attr('data')) return;
110
+
111
+ var data = eval.call(window, "(" + view_data_el.attr("data") + ")");
112
+ for (var key in data) {
113
+ // If you escape a non-string value, it is first converted to a string, which we don't want
114
+ this.params[key] = (typeof data[key] == "string") ? unescape(data[key]) : data[key];
115
+ }
116
+ }
117
+ });
@@ -0,0 +1,45 @@
1
+ // A very simple history implementation. Generates events on the `document.body` element when the
2
+ // hash changes, and includes a parsed object of parameters or a string from the hash.
3
+
4
+ var History = (function() {
5
+
6
+ var currentHash = null;
7
+
8
+ function getMemo() {
9
+ return currentHash.toParameters();
10
+ }
11
+
12
+ function getHash() {
13
+ return window.location.hash.substring(1);
14
+ }
15
+
16
+ function poll() {
17
+ var hash = getHash();
18
+ if (currentHash !== hash) {
19
+ currentHash = hash;
20
+ $(document.body).trigger("hashchange", [getMemo()]);
21
+ }
22
+ }
23
+
24
+ $(document).ready(function() {
25
+ currentHash = getHash();
26
+
27
+ if ('onhashchange' in window) {
28
+ $(window).on('hashchange', poll);
29
+ } else {
30
+ setInterval(poll, 50);
31
+ }
32
+
33
+ $(document.body).trigger("hashchange", [getMemo()]);
34
+ });
35
+
36
+ return {
37
+ add: function(params) {
38
+ window.location.hash = "#" + $.objToQueryStr(params);
39
+ },
40
+ currentHash: function() {
41
+ return getHash();
42
+ }
43
+ }
44
+
45
+ })();
@@ -0,0 +1,90 @@
1
+ // Mock client interface
2
+ var Mock = Class.extend({
3
+ initialize: function(client) {
4
+ this.client = client;
5
+ window.addEventListener("load", this._makeToolbar.bind(this), true);
6
+ },
7
+ _makeToolbar: function(){
8
+ var toolbar = document.createElement("div");
9
+ toolbar.id = "mock-toolbar-container";
10
+ // CSS is set in `mock.css`
11
+ toolbar.innerHTML = "<div id='mock-toolbar'>\
12
+ <div id='mock-left'></div>\
13
+ <div id='mock-center'></div>\
14
+ <div id='mock-right'></div>\
15
+ </div>";
16
+
17
+ document.body.insertBefore(toolbar, document.body.firstChild);
18
+ this.toolbar = toolbar;
19
+ }
20
+ });
21
+
22
+ var Mock = new Mock(Client);
23
+
24
+ Client.notify = function(obj) {
25
+ if (typeof obj.buttons !== 'undefined') {
26
+ this.makeButtons(obj.buttons);
27
+ }
28
+ if (typeof obj.title !== 'undefined') {
29
+ this.makeTitle(obj.title);
30
+ }
31
+
32
+ if (obj.action === "getFavesAndNotifs") {
33
+ Client.callback("favesAndNotifs", {
34
+ faves: Application.params.MOCK_FAVORITES,
35
+ notifs: Application.params.MOCK_NOTIFS
36
+ });
37
+ }
38
+
39
+ // Client.notify logs notifications to the console.
40
+ if (window.console && window.console.log) {
41
+ var arr = [];
42
+ for (var prop in obj) {
43
+ if (typeof obj[prop] !== "function") {
44
+ arr.push(escape(prop) + ": " + escape(obj[prop]));
45
+ }
46
+ }
47
+ console.log("Client.notify({ " + arr.join(", ") + " })");
48
+ }
49
+ };
50
+
51
+ Client.makeButtons = function(str) {
52
+ if (!str) return;
53
+ var specs = str.split(":");
54
+ if (specs.length != 2) {
55
+ alert("There should be 2 segments to a buttons specification");
56
+ } else {
57
+ makeButtonsForSection(specs[0], "mock-left");
58
+ makeButtonsForSection(specs[1], "mock-right");
59
+ }
60
+ function makeButtonsForSection(str, id) {
61
+ $('#'+id).hide();
62
+ if (str !== "") {
63
+ $('#'+id).show();
64
+ if (str === "NudgeNav") {
65
+ // Support for nudge nav in mock toolbar.
66
+ $('#'+id).html("<action name='nudge' value='prev'>&uarr;</action>&nbsp;<action name='nudge' value='next'>&darr;</action>");
67
+ } else {
68
+ $('#'+id).html("<action name='callback' value=" + str + ">" + str + "</action>");
69
+ }
70
+ }
71
+ }
72
+ };
73
+
74
+ // Set the view title
75
+ Client.makeTitle = function(title) {
76
+ $("#mock-center").html(title);
77
+ };
78
+
79
+ setTimeout(function() {
80
+ $('#mock-toolbar').delegate('action', 'click', function(e) {
81
+ var name = $(e.target).attr('name');
82
+ var value = $(e.target).attr('value');
83
+
84
+ Application.onClientCallback(name, value);
85
+ });
86
+ }, 400);
87
+
88
+ Application.clientCallbackHandlers.push(function(name, value) {
89
+ if (value === "Back") history.back();
90
+ });
@@ -0,0 +1,18 @@
1
+ // Timer class for use with auto-updating of game status'.
2
+ var Timer = Class.extend({
3
+ initialize: function(func, period) {
4
+ this.func = func;
5
+ this.period = period;
6
+ this.interval = null;
7
+ },
8
+ // startNow: function() {
9
+ // this.func();
10
+ // this.interval = window.setInterval(this.func, this.period);
11
+ // },
12
+ start: function() {
13
+ this.interval = window.setInterval(this.func, this.period);
14
+ },
15
+ stop: function() {
16
+ window.clearInterval(this.interval);
17
+ }
18
+ });
@@ -0,0 +1,56 @@
1
+ // If your view implements an initialization function, that function will be passed a parameter
2
+ // object containing all the query parameters in the URL that triggered the view's creation, plus
3
+ // all of those values that were assigned to the view when it was registered and bound to a name.
4
+ // It does not need to hold on to these values (although the base implementation of view does, as
5
+ // `this.params`). At the end of a view's create method, it should have inserted a dom element into
6
+ // the body of the page. This will be assigned as the "element" property to the view by the application,
7
+ // as it needs to be referenced outside your view class.
8
+ var View = Class.extend({
9
+ // This method should create (by any means desirable) a DOM element and insert it into the page.
10
+ // Our base implementation queries for an HTML fragment from the server, but this is up to
11
+ // your view implementation.
12
+ create: function() {
13
+ throw new Error("Create method not implemented in subclass");
14
+ },
15
+ // Title of this view. We may not actually use titles in this version of the application,
16
+ // but we needed to provide this in the past.
17
+ getTitle: function() {
18
+ throw new Error("getTitle method not implemented in subclass");
19
+ },
20
+ // The name of the view that is used to log metrics to Google Analytics. The view
21
+ // may also provide additional calls to `Client.notify({'metric': 'metricName'})` if it updates
22
+ // internally (changing tabs, for example).
23
+ getMetric: function() {
24
+ throw new Error("getMetric method not implemented in subclass");
25
+ },
26
+ getButtons: function() {
27
+ throw new Error("getButtons method not implemented in subclass");
28
+ },
29
+ // Send off any necessary notifications to the client. This avoids and issue on iOS where
30
+ // two notifications send right after one another causes one of them to fail.
31
+ getAction: function() {
32
+ throw new Error("getAction method not implemented in subclass");
33
+ },
34
+ // Tell the client what a filtereable view is filtered to.
35
+ getFilter: function() {
36
+ throw new Error("getFilter method not implemented in subclass");
37
+ },
38
+ // Tell the client what section we are in.
39
+ getSection: function() {
40
+ throw new Error("getSection method not implemented in subclass");
41
+ },
42
+ // Called before the view is appended to the page.
43
+ beforeViewAppended: function() {
44
+
45
+ },
46
+ // Called after the view is appended into the page. Either if comes from the cache, or if
47
+ // it is from a get request.
48
+ afterViewAppended: function() {
49
+
50
+ }
51
+ // The client has executed a callback on the web page, to pass a value to the page
52
+ // or to execute some functionality.
53
+ /*
54
+ ,onClientCallback( name, value ) {}
55
+ */
56
+ });