sports_db 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ });