less-rails-semantic_ui 1.12.3.0 → 2.0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/assets/javascripts/semantic_ui/definitions/behaviors/api.js +394 -188
  3. data/assets/javascripts/semantic_ui/definitions/behaviors/colorize.js +4 -2
  4. data/assets/javascripts/semantic_ui/definitions/behaviors/form.js +263 -125
  5. data/assets/javascripts/semantic_ui/definitions/behaviors/state.js +3 -3
  6. data/assets/javascripts/semantic_ui/definitions/behaviors/visibility.js +213 -96
  7. data/assets/javascripts/semantic_ui/definitions/behaviors/visit.js +6 -4
  8. data/assets/javascripts/semantic_ui/definitions/globals/site.js +4 -4
  9. data/assets/javascripts/semantic_ui/definitions/modules/accordion.js +66 -52
  10. data/assets/javascripts/semantic_ui/definitions/modules/checkbox.js +309 -112
  11. data/assets/javascripts/semantic_ui/definitions/modules/dimmer.js +24 -26
  12. data/assets/javascripts/semantic_ui/definitions/modules/dropdown.js +2005 -590
  13. data/assets/javascripts/semantic_ui/definitions/modules/embed.js +662 -0
  14. data/assets/javascripts/semantic_ui/definitions/modules/modal.js +106 -79
  15. data/assets/javascripts/semantic_ui/definitions/modules/nag.js +7 -8
  16. data/assets/javascripts/semantic_ui/definitions/modules/popup.js +323 -194
  17. data/assets/javascripts/semantic_ui/definitions/modules/progress.js +111 -103
  18. data/assets/javascripts/semantic_ui/definitions/modules/rating.js +78 -54
  19. data/assets/javascripts/semantic_ui/definitions/modules/search.js +304 -122
  20. data/assets/javascripts/semantic_ui/definitions/modules/shape.js +93 -47
  21. data/assets/javascripts/semantic_ui/definitions/modules/sidebar.js +83 -149
  22. data/assets/javascripts/semantic_ui/definitions/modules/sticky.js +99 -29
  23. data/assets/javascripts/semantic_ui/definitions/modules/tab.js +219 -124
  24. data/assets/javascripts/semantic_ui/definitions/modules/transition.js +202 -171
  25. data/assets/stylesheets/semantic_ui/definitions/collections/breadcrumb.less +2 -1
  26. data/assets/stylesheets/semantic_ui/definitions/collections/form.less +135 -58
  27. data/assets/stylesheets/semantic_ui/definitions/collections/grid.less +366 -383
  28. data/assets/stylesheets/semantic_ui/definitions/collections/menu.less +838 -631
  29. data/assets/stylesheets/semantic_ui/definitions/collections/message.less +89 -71
  30. data/assets/stylesheets/semantic_ui/definitions/collections/table.less +183 -131
  31. data/assets/stylesheets/semantic_ui/definitions/elements/button.less +1097 -300
  32. data/assets/stylesheets/semantic_ui/definitions/elements/container.less +135 -0
  33. data/assets/stylesheets/semantic_ui/definitions/elements/divider.less +31 -30
  34. data/assets/stylesheets/semantic_ui/definitions/elements/flag.less +1 -1
  35. data/assets/stylesheets/semantic_ui/definitions/elements/header.less +209 -121
  36. data/assets/stylesheets/semantic_ui/definitions/elements/icon.less +201 -96
  37. data/assets/stylesheets/semantic_ui/definitions/elements/image.less +26 -11
  38. data/assets/stylesheets/semantic_ui/definitions/elements/input.less +49 -14
  39. data/assets/stylesheets/semantic_ui/definitions/elements/label.less +391 -221
  40. data/assets/stylesheets/semantic_ui/definitions/elements/list.less +107 -68
  41. data/assets/stylesheets/semantic_ui/definitions/elements/loader.less +3 -1
  42. data/assets/stylesheets/semantic_ui/definitions/elements/rail.less +34 -25
  43. data/assets/stylesheets/semantic_ui/definitions/elements/reveal.less +25 -10
  44. data/assets/stylesheets/semantic_ui/definitions/elements/segment.less +261 -173
  45. data/assets/stylesheets/semantic_ui/definitions/elements/step.less +169 -70
  46. data/assets/stylesheets/semantic_ui/definitions/globals/reset.less +1 -1
  47. data/assets/stylesheets/semantic_ui/definitions/globals/site.less +3 -1
  48. data/assets/stylesheets/semantic_ui/definitions/modules/accordion.less +1 -2
  49. data/assets/stylesheets/semantic_ui/definitions/modules/checkbox.less +175 -103
  50. data/assets/stylesheets/semantic_ui/definitions/modules/dimmer.less +26 -15
  51. data/assets/stylesheets/semantic_ui/definitions/modules/dropdown.less +349 -80
  52. data/assets/stylesheets/semantic_ui/definitions/modules/embed.less +174 -0
  53. data/assets/stylesheets/semantic_ui/definitions/modules/modal.less +83 -36
  54. data/assets/stylesheets/semantic_ui/definitions/modules/nag.less +1 -1
  55. data/assets/stylesheets/semantic_ui/definitions/modules/popup.less +48 -7
  56. data/assets/stylesheets/semantic_ui/definitions/modules/progress.less +160 -107
  57. data/assets/stylesheets/semantic_ui/definitions/modules/rating.less +57 -54
  58. data/assets/stylesheets/semantic_ui/definitions/modules/search.less +55 -10
  59. data/assets/stylesheets/semantic_ui/definitions/modules/shape.less +5 -6
  60. data/assets/stylesheets/semantic_ui/definitions/modules/sidebar.less +9 -5
  61. data/assets/stylesheets/semantic_ui/definitions/modules/sticky.less +1 -1
  62. data/assets/stylesheets/semantic_ui/definitions/modules/tab.less +1 -1
  63. data/assets/stylesheets/semantic_ui/definitions/modules/transition.less +3 -4
  64. data/assets/stylesheets/semantic_ui/definitions/views/card.less +240 -130
  65. data/assets/stylesheets/semantic_ui/definitions/views/comment.less +1 -1
  66. data/assets/stylesheets/semantic_ui/definitions/views/feed.less +15 -8
  67. data/assets/stylesheets/semantic_ui/definitions/views/item.less +13 -13
  68. data/assets/stylesheets/semantic_ui/definitions/views/statistic.less +230 -86
  69. data/assets/stylesheets/semantic_ui/theme.less +22 -15
  70. data/assets/stylesheets/semantic_ui/themes/amazon/elements/button.overrides +5 -5
  71. data/assets/stylesheets/semantic_ui/themes/amazon/elements/button.variables +5 -4
  72. data/assets/stylesheets/semantic_ui/themes/basic/collections/table.variables +1 -0
  73. data/assets/stylesheets/semantic_ui/themes/basic/views/card.variables +6 -4
  74. data/assets/stylesheets/semantic_ui/themes/bookish/elements/header.variables +4 -4
  75. data/assets/stylesheets/semantic_ui/themes/bootstrap3/elements/button.variables +1 -1
  76. data/assets/stylesheets/semantic_ui/themes/chubby/collections/form.overrides +8 -0
  77. data/assets/stylesheets/semantic_ui/themes/chubby/collections/menu.overrides +0 -0
  78. data/assets/stylesheets/semantic_ui/themes/chubby/collections/menu.variables +40 -0
  79. data/assets/stylesheets/semantic_ui/themes/classic/modules/progress.variables +1 -0
  80. data/assets/stylesheets/semantic_ui/themes/classic/views/card.overrides +1 -1
  81. data/assets/stylesheets/semantic_ui/themes/colored/modules/checkbox.overrides +0 -0
  82. data/assets/stylesheets/semantic_ui/themes/colored/modules/checkbox.variables +17 -0
  83. data/assets/stylesheets/semantic_ui/themes/default/collections/breadcrumb.overrides +0 -0
  84. data/assets/stylesheets/semantic_ui/themes/default/collections/breadcrumb.variables +5 -15
  85. data/assets/stylesheets/semantic_ui/themes/default/collections/form.overrides +0 -0
  86. data/assets/stylesheets/semantic_ui/themes/default/collections/form.variables +31 -35
  87. data/assets/stylesheets/semantic_ui/themes/default/collections/grid.overrides +0 -0
  88. data/assets/stylesheets/semantic_ui/themes/default/collections/grid.variables +34 -28
  89. data/assets/stylesheets/semantic_ui/themes/default/collections/menu.overrides +0 -0
  90. data/assets/stylesheets/semantic_ui/themes/default/collections/menu.variables +259 -163
  91. data/assets/stylesheets/semantic_ui/themes/default/collections/message.overrides +0 -0
  92. data/assets/stylesheets/semantic_ui/themes/default/collections/message.variables +42 -19
  93. data/assets/stylesheets/semantic_ui/themes/default/collections/table.overrides +0 -3
  94. data/assets/stylesheets/semantic_ui/themes/default/collections/table.variables +63 -59
  95. data/assets/stylesheets/semantic_ui/themes/default/elements/button.overrides +0 -0
  96. data/assets/stylesheets/semantic_ui/themes/default/elements/button.variables +90 -50
  97. data/assets/stylesheets/semantic_ui/themes/default/elements/container.overrides +3 -0
  98. data/assets/stylesheets/semantic_ui/themes/default/elements/container.variables +45 -0
  99. data/assets/stylesheets/semantic_ui/themes/default/elements/divider.overrides +15 -0
  100. data/assets/stylesheets/semantic_ui/themes/default/elements/divider.variables +3 -4
  101. data/assets/stylesheets/semantic_ui/themes/default/elements/flag.overrides +0 -0
  102. data/assets/stylesheets/semantic_ui/themes/default/elements/header.overrides +0 -0
  103. data/assets/stylesheets/semantic_ui/themes/default/elements/header.variables +40 -36
  104. data/assets/stylesheets/semantic_ui/themes/default/elements/icon.overrides +4 -3
  105. data/assets/stylesheets/semantic_ui/themes/default/elements/icon.variables +29 -12
  106. data/assets/stylesheets/semantic_ui/themes/default/elements/image.overrides +0 -0
  107. data/assets/stylesheets/semantic_ui/themes/default/elements/image.variables +5 -3
  108. data/assets/stylesheets/semantic_ui/themes/default/elements/input.overrides +0 -0
  109. data/assets/stylesheets/semantic_ui/themes/default/elements/input.variables +10 -24
  110. data/assets/stylesheets/semantic_ui/themes/default/elements/label.overrides +0 -0
  111. data/assets/stylesheets/semantic_ui/themes/default/elements/label.variables +88 -35
  112. data/assets/stylesheets/semantic_ui/themes/default/elements/list.overrides +0 -0
  113. data/assets/stylesheets/semantic_ui/themes/default/elements/list.variables +53 -34
  114. data/assets/stylesheets/semantic_ui/themes/default/elements/loader.overrides +0 -0
  115. data/assets/stylesheets/semantic_ui/themes/default/elements/loader.variables +9 -10
  116. data/assets/stylesheets/semantic_ui/themes/default/elements/rail.overrides +0 -0
  117. data/assets/stylesheets/semantic_ui/themes/default/elements/rail.variables +13 -5
  118. data/assets/stylesheets/semantic_ui/themes/default/elements/reveal.overrides +0 -0
  119. data/assets/stylesheets/semantic_ui/themes/default/elements/reveal.variables +6 -4
  120. data/assets/stylesheets/semantic_ui/themes/default/elements/segment.overrides +0 -0
  121. data/assets/stylesheets/semantic_ui/themes/default/elements/segment.variables +66 -28
  122. data/assets/stylesheets/semantic_ui/themes/default/elements/step.overrides +0 -0
  123. data/assets/stylesheets/semantic_ui/themes/default/elements/step.variables +60 -31
  124. data/assets/stylesheets/semantic_ui/themes/default/globals/reset.overrides +0 -0
  125. data/assets/stylesheets/semantic_ui/themes/default/globals/site.variables +477 -303
  126. data/assets/stylesheets/semantic_ui/themes/default/modules/accordion.overrides +0 -0
  127. data/assets/stylesheets/semantic_ui/themes/default/modules/accordion.variables +6 -7
  128. data/assets/stylesheets/semantic_ui/themes/default/modules/chatroom.overrides +0 -0
  129. data/assets/stylesheets/semantic_ui/themes/default/modules/checkbox.overrides +19 -16
  130. data/assets/stylesheets/semantic_ui/themes/default/modules/checkbox.variables +71 -43
  131. data/assets/stylesheets/semantic_ui/themes/default/modules/dimmer.overrides +0 -0
  132. data/assets/stylesheets/semantic_ui/themes/default/modules/dimmer.variables +12 -9
  133. data/assets/stylesheets/semantic_ui/themes/default/modules/dropdown.overrides +0 -5
  134. data/assets/stylesheets/semantic_ui/themes/default/modules/dropdown.variables +146 -64
  135. data/assets/stylesheets/semantic_ui/themes/default/modules/{video.overrides → embed.overrides} +0 -0
  136. data/assets/stylesheets/semantic_ui/themes/default/modules/embed.variables +53 -0
  137. data/assets/stylesheets/semantic_ui/themes/default/modules/modal.overrides +0 -0
  138. data/assets/stylesheets/semantic_ui/themes/default/modules/modal.variables +24 -18
  139. data/assets/stylesheets/semantic_ui/themes/default/modules/nag.overrides +0 -0
  140. data/assets/stylesheets/semantic_ui/themes/default/modules/popup.overrides +0 -0
  141. data/assets/stylesheets/semantic_ui/themes/default/modules/popup.variables +3 -9
  142. data/assets/stylesheets/semantic_ui/themes/default/modules/progress.variables +13 -7
  143. data/assets/stylesheets/semantic_ui/themes/default/modules/rating.overrides +0 -0
  144. data/assets/stylesheets/semantic_ui/themes/default/modules/rating.variables +71 -33
  145. data/assets/stylesheets/semantic_ui/themes/default/modules/search.overrides +0 -0
  146. data/assets/stylesheets/semantic_ui/themes/default/modules/search.variables +36 -34
  147. data/assets/stylesheets/semantic_ui/themes/default/modules/shape.overrides +0 -0
  148. data/assets/stylesheets/semantic_ui/themes/default/modules/shape.variables +7 -2
  149. data/assets/stylesheets/semantic_ui/themes/default/modules/sidebar.overrides +0 -0
  150. data/assets/stylesheets/semantic_ui/themes/default/modules/sidebar.variables +2 -5
  151. data/assets/stylesheets/semantic_ui/themes/default/modules/sticky.overrides +0 -0
  152. data/assets/stylesheets/semantic_ui/themes/default/modules/sticky.variables +2 -7
  153. data/assets/stylesheets/semantic_ui/themes/default/modules/tab.variables +1 -3
  154. data/assets/stylesheets/semantic_ui/themes/default/modules/transition.overrides +8 -9
  155. data/assets/stylesheets/semantic_ui/themes/default/views/ad.variables +2 -2
  156. data/assets/stylesheets/semantic_ui/themes/default/views/card.variables +33 -23
  157. data/assets/stylesheets/semantic_ui/themes/default/views/comment.overrides +0 -0
  158. data/assets/stylesheets/semantic_ui/themes/default/views/feed.overrides +0 -0
  159. data/assets/stylesheets/semantic_ui/themes/default/views/feed.variables +15 -23
  160. data/assets/stylesheets/semantic_ui/themes/default/views/item.overrides +0 -0
  161. data/assets/stylesheets/semantic_ui/themes/default/views/item.variables +12 -11
  162. data/assets/stylesheets/semantic_ui/themes/default/views/statistic.overrides +0 -0
  163. data/assets/stylesheets/semantic_ui/themes/default/views/statistic.variables +25 -24
  164. data/assets/stylesheets/semantic_ui/themes/flat/collections/form.overrides +4 -0
  165. data/assets/stylesheets/semantic_ui/themes/flat/collections/form.variables +1 -2
  166. data/assets/stylesheets/semantic_ui/themes/flat/globals/site.variables +1 -0
  167. data/assets/stylesheets/semantic_ui/themes/github/collections/form.variables +1 -1
  168. data/assets/stylesheets/semantic_ui/themes/github/collections/menu.variables +10 -15
  169. data/assets/stylesheets/semantic_ui/themes/github/elements/button.variables +2 -2
  170. data/assets/stylesheets/semantic_ui/themes/github/elements/step.variables +2 -2
  171. data/assets/stylesheets/semantic_ui/themes/instagram/views/card.overrides +12 -0
  172. data/assets/stylesheets/semantic_ui/themes/instagram/views/card.variables +23 -0
  173. data/assets/stylesheets/semantic_ui/themes/material/collections/menu.overrides +1 -0
  174. data/assets/stylesheets/semantic_ui/themes/material/collections/menu.variables +10 -0
  175. data/assets/stylesheets/semantic_ui/themes/material/elements/button.overrides +1 -0
  176. data/assets/stylesheets/semantic_ui/themes/material/elements/button.variables +14 -6
  177. data/assets/stylesheets/semantic_ui/themes/material/globals/site.variables +3 -2
  178. data/assets/stylesheets/semantic_ui/themes/material/modules/dropdown.overrides +5 -0
  179. data/assets/stylesheets/semantic_ui/themes/material/modules/dropdown.variables +20 -0
  180. data/assets/stylesheets/semantic_ui/themes/raised/elements/button.variables +5 -5
  181. data/assets/stylesheets/semantic_ui/themes/round/elements/button.variables +1 -1
  182. data/assets/stylesheets/semantic_ui/themes/timeline/views/feed.overrides +4 -12
  183. data/assets/stylesheets/semantic_ui/themes/timeline/views/feed.variables +3 -7
  184. data/lib/generators/semantic_ui/install/templates/config/elements/container.overrides +3 -0
  185. data/lib/generators/semantic_ui/install/templates/config/elements/container.variables +3 -0
  186. data/lib/generators/semantic_ui/install/templates/config/modules/embed.overrides +3 -0
  187. data/lib/generators/semantic_ui/install/templates/config/modules/embed.variables +0 -0
  188. data/lib/generators/semantic_ui/install/templates/semantic_ui.css +2 -1
  189. data/lib/generators/semantic_ui/install/templates/semantic_ui.js +1 -1
  190. data/lib/generators/semantic_ui/install/templates/theme.config +5 -3
  191. data/lib/less/rails/semantic_ui/version.rb +1 -1
  192. data/tasks/update.rake +21 -6
  193. metadata +23 -7
  194. data/assets/fonts/semantic_ui/themes/default/assets/fonts/icons.otf +0 -0
  195. data/assets/javascripts/semantic_ui/definitions/modules/video.js +0 -540
  196. data/assets/stylesheets/semantic_ui/definitions/modules/video.less +0 -135
  197. data/assets/stylesheets/semantic_ui/themes/default/modules/video.variables +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e4343980ee8e7b79009d25aaf6ec3f47e800fc2
4
- data.tar.gz: 5897d1bb42e3a4902f92ee9e1f13aa57faaeb300
3
+ metadata.gz: ae7af5f161f9cf436de8c0a4a2b2b1b8a8f538a3
4
+ data.tar.gz: c1ecc46fb62fcea92e8de9a02a1eb07e5f7897ca
5
5
  SHA512:
6
- metadata.gz: bfd3d585acf357b0d4f0f572d7646a0199deef4fe4181cbaf2b74f6d33e23412fecdffde2261bcafdf9d8649edc8aec6c4034beec4cdcd1d3d9ed8ca95050b62
7
- data.tar.gz: 147569b9c3ff924ec9c0982914205d815340d99e956c92670a5eaa9b33e961213a6c16be148ac6bbb708765f498f40c0d24dfe3fc24b7bd8f2031a722a88096d
6
+ metadata.gz: 013cb7dbb6a031ddc75fb39b0c9be1817cf1d80d88cf6945e86d2354497235263f185ad0365d00e506d9e9900f9309e3f64df3936f4c74df003f88aad5a82218
7
+ data.tar.gz: 1d39a800271be04c61c8edcccdc9a46c42b65c400ba2fb6f087d6c34a7544990c2f00f79271b95d2ed9230b34783b6b40806d02df23ee402961751a257e31350
@@ -3,7 +3,7 @@
3
3
  * http://github.com/semantic-org/semantic-ui/
4
4
  *
5
5
  *
6
- * Copyright 2014 Contributors
6
+ * Copyright 2015 Contributors
7
7
  * Released under the MIT license
8
8
  * http://opensource.org/licenses/MIT
9
9
  *
@@ -63,10 +63,11 @@ $.api = $.fn.api = function(parameters) {
63
63
  requestSettings,
64
64
  url,
65
65
  data,
66
+ requestStartTime,
66
67
 
67
68
  // standard module
68
69
  element = this,
69
- context = $context.get(),
70
+ context = $context[0],
70
71
  instance = $module.data(moduleNamespace),
71
72
  module
72
73
  ;
@@ -74,21 +75,8 @@ $.api = $.fn.api = function(parameters) {
74
75
  module = {
75
76
 
76
77
  initialize: function() {
77
- var
78
- triggerEvent = module.get.event()
79
- ;
80
- // bind events
81
78
  if(!methodInvoked) {
82
- if( triggerEvent ) {
83
- module.debug('Attaching API events to element', triggerEvent);
84
- $module
85
- .on(triggerEvent + eventNamespace, module.event.trigger)
86
- ;
87
- }
88
- else if(settings.on == 'now') {
89
- module.debug('Querying API now', triggerEvent);
90
- module.query();
91
- }
79
+ module.bind.events();
92
80
  }
93
81
  module.instantiate();
94
82
  },
@@ -109,16 +97,81 @@ $.api = $.fn.api = function(parameters) {
109
97
  ;
110
98
  },
111
99
 
100
+ bind: {
101
+ events: function() {
102
+ var
103
+ triggerEvent = module.get.event()
104
+ ;
105
+ if( triggerEvent ) {
106
+ module.verbose('Attaching API events to element', triggerEvent);
107
+ $module
108
+ .on(triggerEvent + eventNamespace, module.event.trigger)
109
+ ;
110
+ }
111
+ else if(settings.on == 'now') {
112
+ module.debug('Querying API now', triggerEvent);
113
+ module.query();
114
+ }
115
+ }
116
+ },
117
+
118
+ read: {
119
+ cachedResponse: function(url) {
120
+ var
121
+ response
122
+ ;
123
+ if(window.Storage === undefined) {
124
+ module.error(error.noStorage);
125
+ return;
126
+ }
127
+ response = sessionStorage.getItem(url);
128
+ module.debug('Using cached response', url, response);
129
+ if(response !== undefined) {
130
+ try {
131
+ response = JSON.parse(response);
132
+ }
133
+ catch(e) {
134
+ // didnt store object
135
+ }
136
+ return response;
137
+ }
138
+ return false;
139
+ }
140
+ },
141
+ write: {
142
+ cachedResponse: function(url, response) {
143
+ if(response && response === '') {
144
+ module.debug('Response empty, not caching', response);
145
+ return;
146
+ }
147
+ if(window.Storage === undefined) {
148
+ module.error(error.noStorage);
149
+ return;
150
+ }
151
+ if( $.isPlainObject(response) ) {
152
+ response = JSON.stringify(response);
153
+ }
154
+ sessionStorage.setItem(url, response);
155
+ module.verbose('Storing cached response for url', url, response);
156
+ }
157
+ },
158
+
112
159
  query: function() {
113
160
 
114
161
  if(module.is.disabled()) {
115
162
  module.debug('Element is disabled API request aborted');
116
163
  return;
117
164
  }
118
- // determine if an api event already occurred
119
- if(module.is.loading() && settings.throttle === 0 ) {
120
- module.debug('Cancelling request, previous request is still pending');
121
- return;
165
+
166
+ if(module.is.loading()) {
167
+ if(settings.interruptRequests) {
168
+ module.debug('Interrupting previous request');
169
+ module.abort();
170
+ }
171
+ else {
172
+ module.debug('Cancelling request, previous request is still pending');
173
+ return;
174
+ }
122
175
  }
123
176
 
124
177
  // pass element metadata to url (value, text)
@@ -127,17 +180,12 @@ $.api = $.fn.api = function(parameters) {
127
180
  }
128
181
 
129
182
  // Add form content
130
- if(settings.serializeForm !== false || $context.is('form')) {
131
- if(settings.serializeForm == 'json') {
132
- $.extend(true, settings.data, module.get.formData());
133
- }
134
- else {
135
- settings.data = module.get.formData();
136
- }
183
+ if(settings.serializeForm) {
184
+ settings.data = module.add.formData(settings.data);
137
185
  }
138
186
 
139
187
  // call beforesend and get any settings changes
140
- requestSettings = module.get.settings();
188
+ requestSettings = module.get.settings();
141
189
 
142
190
  // check if before send cancelled request
143
191
  if(requestSettings === false) {
@@ -149,31 +197,22 @@ $.api = $.fn.api = function(parameters) {
149
197
  module.cancelled = false;
150
198
  }
151
199
 
152
- if(settings.url) {
153
- // override with url if specified
154
- module.debug('Using specified url', url);
155
- url = module.add.urlData( settings.url );
156
- }
157
- else {
158
- // otherwise find url from api endpoints
159
- url = module.add.urlData( module.get.templateURL() );
160
- module.debug('Added URL Data to url', url);
200
+ // get url
201
+ url = module.get.templatedURL();
202
+
203
+ if(!url && !module.is.mocked()) {
204
+ module.error(error.missingURL);
205
+ return;
161
206
  }
162
207
 
163
- // exit conditions reached, missing url parameters
164
- if( !url ) {
165
- if( module.is.form() ) {
166
- url = $module.attr('action') || '';
167
- module.debug('No url or action specified, defaulting to form action', url);
168
- }
169
- else {
170
- module.error(error.missingURL, settings.action);
171
- return;
172
- }
208
+ // replace variables
209
+ url = module.add.urlData( url );
210
+
211
+ // missing url parameters
212
+ if( !url && !module.is.mocked()) {
213
+ return;
173
214
  }
174
215
 
175
- // add loading state
176
- module.set.loading();
177
216
 
178
217
  // look for jQuery ajax parameters in settings
179
218
  ajaxSettings = $.extend(true, {}, settings, {
@@ -187,39 +226,80 @@ $.api = $.fn.api = function(parameters) {
187
226
  });
188
227
 
189
228
  module.debug('Querying URL', ajaxSettings.url);
190
- module.debug('Sending data', data, ajaxSettings.method);
191
229
  module.verbose('Using AJAX settings', ajaxSettings);
192
230
 
193
- if( module.is.loading() ) {
194
- // throttle additional requests
195
- module.timer = setTimeout(function() {
196
- module.request = module.create.request();
197
- module.xhr = module.create.xhr();
198
- settings.onRequest.call(context, module.request, module.xhr);
199
- }, settings.throttle);
231
+ if(settings.cache === 'local' && module.read.cachedResponse(url)) {
232
+ module.debug('Response returned from local cache');
233
+ module.request = module.create.request();
234
+ module.request.resolveWith(context, [ module.read.cachedResponse(url) ]);
235
+ return;
236
+ }
237
+
238
+ if( !settings.throttle ) {
239
+ module.debug('Sending request', data, ajaxSettings.method);
240
+ module.send.request();
200
241
  }
201
242
  else {
202
- // immediately on first request
203
- module.request = module.create.request();
204
- module.xhr = module.create.xhr();
205
- settings.onRequest.call(context, module.request, module.xhr);
243
+ if(!settings.throttleFirstRequest && !module.timer) {
244
+ module.debug('Sending request', data, ajaxSettings.method);
245
+ module.send.request();
246
+ module.timer = setTimeout(function(){}, settings.throttle);
247
+ }
248
+ else {
249
+ module.debug('Throttling request', settings.throttle);
250
+ clearTimeout(module.timer);
251
+ module.timer = setTimeout(function() {
252
+ if(module.timer) {
253
+ delete module.timer;
254
+ }
255
+ module.debug('Sending throttled request', data, ajaxSettings.method);
256
+ module.send.request();
257
+ }, settings.throttle);
258
+ }
206
259
  }
207
260
 
208
261
  },
209
262
 
210
-
211
263
  is: {
212
264
  disabled: function() {
213
- return ($module.filter(settings.filter).length > 0);
265
+ return ($module.filter(selector.disabled).length > 0);
214
266
  },
215
267
  form: function() {
216
268
  return $module.is('form');
217
269
  },
270
+ mocked: function() {
271
+ return (settings.mockResponse || settings.mockResponseAsync);
272
+ },
218
273
  input: function() {
219
274
  return $module.is('input');
220
275
  },
221
276
  loading: function() {
222
277
  return (module.request && module.request.state() == 'pending');
278
+ },
279
+ abortedRequest: function(xhr) {
280
+ if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
281
+ module.verbose('XHR request determined to be aborted');
282
+ return true;
283
+ }
284
+ else {
285
+ module.verbose('XHR request was not aborted');
286
+ return false;
287
+ }
288
+ },
289
+ validResponse: function(response) {
290
+ if( settings.dataType !== 'json' || !$.isFunction(settings.successTest) ) {
291
+ module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
292
+ return true;
293
+ }
294
+ module.debug('Checking JSON returned success', settings.successTest, response);
295
+ if( settings.successTest(response) ) {
296
+ module.debug('Response passed success test', response);
297
+ return true;
298
+ }
299
+ else {
300
+ module.debug('Response failed success test', response);
301
+ return false;
302
+ }
223
303
  }
224
304
  },
225
305
 
@@ -311,6 +391,48 @@ $.api = $.fn.api = function(parameters) {
311
391
  }
312
392
  }
313
393
  return url;
394
+ },
395
+ formData: function(data) {
396
+ var
397
+ canSerialize = ($.fn.serializeObject !== undefined),
398
+ formData = (canSerialize)
399
+ ? $form.serializeObject()
400
+ : $form.serialize(),
401
+ hasOtherData
402
+ ;
403
+ data = data || settings.data;
404
+ hasOtherData = $.isPlainObject(data);
405
+
406
+ if(hasOtherData) {
407
+ if(canSerialize) {
408
+ module.debug('Extending existing data with form data', data, formData);
409
+ data = $.extend(true, {}, data, formData);
410
+ }
411
+ else {
412
+ module.error(error.missingSerialize);
413
+ module.debug('Cant extend data. Replacing data with form data', data, formData);
414
+ data = formData;
415
+ }
416
+ }
417
+ else {
418
+ module.debug('Adding form data', formData);
419
+ data = formData;
420
+ }
421
+ return data;
422
+ }
423
+ },
424
+
425
+ send: {
426
+ request: function() {
427
+ module.set.loading();
428
+ module.request = module.create.request();
429
+ if( module.is.mocked() ) {
430
+ module.mockedXHR = module.create.mockedXHR();
431
+ }
432
+ else {
433
+ module.xhr = module.create.xhr();
434
+ }
435
+ settings.onRequest.call(context, module.request, module.xhr);
314
436
  }
315
437
  },
316
438
 
@@ -325,37 +447,54 @@ $.api = $.fn.api = function(parameters) {
325
447
  always: function() {
326
448
  // calculate if loading time was below minimum threshold
327
449
  },
328
- done: function(response) {
450
+ done: function(response, textStatus, xhr) {
329
451
  var
330
452
  context = this,
331
- elapsedTime = (new Date().getTime() - time),
332
- timeLeft = (settings.loadingDuration - elapsedTime)
453
+ elapsedTime = (new Date().getTime() - requestStartTime),
454
+ timeLeft = (settings.loadingDuration - elapsedTime),
455
+ translatedResponse = ( $.isFunction(settings.onResponse) )
456
+ ? settings.onResponse.call(context, $.extend(true, {}, response))
457
+ : false
333
458
  ;
334
459
  timeLeft = (timeLeft > 0)
335
460
  ? timeLeft
336
461
  : 0
337
462
  ;
463
+ if(translatedResponse) {
464
+ module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
465
+ response = translatedResponse;
466
+ }
467
+ if(timeLeft > 0) {
468
+ module.debug('Response completed early delaying state change by', timeLeft);
469
+ }
338
470
  setTimeout(function() {
339
- module.request.resolveWith(context, [response]);
471
+ if( module.is.validResponse(response) ) {
472
+ module.request.resolveWith(context, [response]);
473
+ }
474
+ else {
475
+ module.request.rejectWith(context, [xhr, 'invalid']);
476
+ }
340
477
  }, timeLeft);
341
478
  },
342
479
  fail: function(xhr, status, httpMessage) {
343
480
  var
344
481
  context = this,
345
- elapsedTime = (new Date().getTime() - time),
482
+ elapsedTime = (new Date().getTime() - requestStartTime),
346
483
  timeLeft = (settings.loadingDuration - elapsedTime)
347
484
  ;
348
485
  timeLeft = (timeLeft > 0)
349
486
  ? timeLeft
350
487
  : 0
351
488
  ;
352
- // page triggers abort on navigation, dont show error
489
+ if(timeLeft > 0) {
490
+ module.debug('Response completed early delaying state change by', timeLeft);
491
+ }
353
492
  setTimeout(function() {
354
- if(status !== 'abort') {
355
- module.request.rejectWith(context, [xhr, status, httpMessage]);
493
+ if( module.is.abortedRequest(xhr) ) {
494
+ module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
356
495
  }
357
496
  else {
358
- module.reset();
497
+ module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
359
498
  }
360
499
  }, timeLeft);
361
500
  }
@@ -366,87 +505,124 @@ $.api = $.fn.api = function(parameters) {
366
505
  settings.onComplete.call(context, response, $module);
367
506
  },
368
507
  done: function(response) {
369
- module.debug('API Response Received', response);
370
- if(settings.dataType == 'json') {
371
- if( $.isFunction(settings.successTest) ) {
372
- module.debug('Checking JSON returned success', settings.successTest, response);
373
- if( settings.successTest(response) ) {
374
- settings.onSuccess.call(context, response, $module);
375
- }
376
- else {
377
- module.debug('JSON test specified by user and response failed', response);
378
- settings.onFailure.call(context, response, $module);
379
- }
380
- }
381
- else {
382
- settings.onSuccess.call(context, response, $module);
383
- }
384
- }
385
- else {
386
- settings.onSuccess.call(context, response, $module);
508
+ module.debug('Successful API Response', response);
509
+ if(settings.cache === 'local' && url) {
510
+ module.write.cachedResponse(url, response);
511
+ module.debug('Saving server response locally', module.cache);
387
512
  }
513
+ settings.onSuccess.call(context, response, $module);
388
514
  },
389
- error: function(xhr, status, httpMessage) {
515
+ fail: function(xhr, status, httpMessage) {
390
516
  var
391
- errorMessage = (settings.error[status] !== undefined)
392
- ? settings.error[status]
393
- : httpMessage,
394
- response
517
+ // pull response from xhr if available
518
+ response = $.isPlainObject(xhr)
519
+ ? (xhr.responseText)
520
+ : false,
521
+ errorMessage = ($.isPlainObject(response) && response.error !== undefined)
522
+ ? response.error // use json error message
523
+ : (settings.error[status] !== undefined) // use server error message
524
+ ? settings.error[status]
525
+ : httpMessage
395
526
  ;
396
- // let em know unless request aborted
397
- if(xhr !== undefined) {
398
- // readyState 4 = done, anything less is not really sent
399
- if(xhr.readyState !== undefined && xhr.readyState == 4) {
527
+ if(status == 'aborted') {
528
+ module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
529
+ settings.onAbort.call(context, status, $module);
530
+ }
531
+ else if(status == 'invalid') {
532
+ module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
533
+ }
534
+ else if(status == 'error') {
400
535
 
401
- // if http status code returned and json returned error, look for it
536
+ if(xhr !== undefined) {
537
+ module.debug('XHR produced a server error', status, httpMessage);
538
+ // make sure we have an error to display to console
402
539
  if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
403
540
  module.error(error.statusMessage + httpMessage, ajaxSettings.url);
404
541
  }
405
- else {
406
- if(status == 'error' && settings.dataType == 'json') {
407
- try {
408
- response = $.parseJSON(xhr.responseText);
409
- if(response && response.error !== undefined) {
410
- errorMessage = response.error;
411
- }
412
- }
413
- catch(e) {
414
- module.error(error.JSONParse);
415
- }
416
- }
417
- }
418
- module.remove.loading();
419
- module.set.error();
420
- // show error state only for duration specified in settings
421
- if(settings.errorDuration) {
422
- setTimeout(module.remove.error, settings.errorDuration);
423
- }
424
- module.debug('API Request error:', errorMessage);
425
542
  settings.onError.call(context, errorMessage, $module);
426
543
  }
427
- else {
428
- settings.onAbort.call(context, errorMessage, $module);
429
- module.debug('Request Aborted (Most likely caused by page change or CORS Policy)', status, httpMessage);
430
- }
431
544
  }
545
+
546
+ if(settings.errorDuration && status !== 'aborted') {
547
+ module.debug('Adding error state');
548
+ module.set.error();
549
+ setTimeout(module.remove.error, settings.errorDuration);
550
+ }
551
+ module.debug('API Request failed', errorMessage, xhr);
552
+ settings.onFailure.call(context, response, $module);
432
553
  }
433
554
  }
434
555
  },
435
556
 
436
557
  create: {
558
+
437
559
  request: function() {
560
+ // api request promise
438
561
  return $.Deferred()
439
562
  .always(module.event.request.complete)
440
563
  .done(module.event.request.done)
441
- .fail(module.event.request.error)
564
+ .fail(module.event.request.fail)
442
565
  ;
443
566
  },
567
+
568
+ mockedXHR: function () {
569
+ var
570
+ // xhr does not simulate these properties of xhr but must return them
571
+ textStatus = false,
572
+ status = false,
573
+ httpMessage = false,
574
+ asyncCallback,
575
+ response,
576
+ mockedXHR
577
+ ;
578
+
579
+ mockedXHR = $.Deferred()
580
+ .always(module.event.xhr.complete)
581
+ .done(module.event.xhr.done)
582
+ .fail(module.event.xhr.fail)
583
+ ;
584
+
585
+ if(settings.mockResponse) {
586
+ if( $.isFunction(settings.mockResponse) ) {
587
+ module.debug('Using mocked callback returning response', settings.mockResponse);
588
+ response = settings.mockResponse.call(context, settings);
589
+ }
590
+ else {
591
+ module.debug('Using specified response', settings.mockResponse);
592
+ response = settings.mockResponse;
593
+ }
594
+ // simulating response
595
+ mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
596
+ }
597
+ else if( $.isFunction(settings.mockResponseAsync) ) {
598
+ asyncCallback = function(response) {
599
+ module.debug('Async callback returned response', response);
600
+
601
+ if(response) {
602
+ mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
603
+ }
604
+ else {
605
+ mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
606
+ }
607
+ };
608
+ module.debug('Using async mocked response', settings.mockResponseAsync);
609
+ settings.mockResponseAsync.call(context, settings, asyncCallback);
610
+ }
611
+ return mockedXHR;
612
+ },
613
+
444
614
  xhr: function() {
445
- return $.ajax(ajaxSettings)
615
+ var
616
+ xhr
617
+ ;
618
+ // ajax request promise
619
+ xhr = $.ajax(ajaxSettings)
446
620
  .always(module.event.xhr.always)
447
621
  .done(module.event.xhr.done)
448
622
  .fail(module.event.xhr.fail)
449
623
  ;
624
+ module.verbose('Created server request', xhr);
625
+ return xhr;
450
626
  }
451
627
  },
452
628
 
@@ -458,6 +634,7 @@ $.api = $.fn.api = function(parameters) {
458
634
  loading: function() {
459
635
  module.verbose('Adding loading state to element', $context);
460
636
  $context.addClass(className.loading);
637
+ requestStartTime = new Date().getTime();
461
638
  }
462
639
  },
463
640
 
@@ -483,7 +660,7 @@ $.api = $.fn.api = function(parameters) {
483
660
  var
484
661
  runSettings
485
662
  ;
486
- runSettings = settings.beforeSend.call($module, settings);
663
+ runSettings = settings.beforeSend.call(context, settings);
487
664
  if(runSettings) {
488
665
  if(runSettings.success !== undefined) {
489
666
  module.debug('Legacy success callback detected', runSettings);
@@ -551,34 +728,24 @@ $.api = $.fn.api = function(parameters) {
551
728
  return settings.on;
552
729
  }
553
730
  },
554
- formData: function() {
555
- var
556
- formData
557
- ;
558
- if($module.serializeObject !== undefined) {
559
- formData = $form.serializeObject();
560
- }
561
- else {
562
- module.error(error.missingSerialize);
563
- formData = $form.serialize();
564
- }
565
- module.debug('Retrieved form data', formData);
566
- return formData;
567
- },
568
- templateURL: function(action) {
569
- var
570
- url
571
- ;
731
+ templatedURL: function(action) {
572
732
  action = action || $module.data(metadata.action) || settings.action || false;
733
+ url = $module.data(metadata.url) || settings.url || false;
734
+ if(url) {
735
+ module.debug('Using specified url', url);
736
+ return url;
737
+ }
573
738
  if(action) {
574
739
  module.debug('Looking up url for action', action, settings.api);
575
- if(settings.api[action] !== undefined) {
576
- url = settings.api[action];
577
- module.debug('Found template url', url);
578
- }
579
- else if( !module.is.form() ) {
740
+ if(settings.api[action] === undefined && !module.is.mocked()) {
580
741
  module.error(error.missingAction, settings.action, settings.api);
742
+ return;
581
743
  }
744
+ url = settings.api[action];
745
+ }
746
+ else if( module.is.form() ) {
747
+ url = $module.attr('action') || false;
748
+ module.debug('No url or action specified, defaulting to form action', url);
582
749
  }
583
750
  return url;
584
751
  }
@@ -591,7 +758,6 @@ $.api = $.fn.api = function(parameters) {
591
758
  if( xhr && xhr.state() !== 'resolved') {
592
759
  module.debug('Cancelling API request');
593
760
  xhr.abort();
594
- module.request.rejectWith(settings.apiSettings);
595
761
  }
596
762
  },
597
763
 
@@ -670,7 +836,7 @@ $.api = $.fn.api = function(parameters) {
670
836
  });
671
837
  }
672
838
  clearTimeout(module.performance.timer);
673
- module.performance.timer = setTimeout(module.performance.display, 100);
839
+ module.performance.timer = setTimeout(module.performance.display, 500);
674
840
  },
675
841
  display: function() {
676
842
  var
@@ -780,49 +946,88 @@ $.api = $.fn.api = function(parameters) {
780
946
 
781
947
  $.api.settings = {
782
948
 
783
- name : 'API',
784
- namespace : 'api',
949
+ name : 'API',
950
+ namespace : 'api',
951
+
952
+ debug : true,
953
+ verbose : false,
954
+ performance : true,
955
+
956
+ // object containing all templates endpoints
957
+ api : {},
785
958
 
786
- debug : true,
787
- verbose : false,
788
- performance : true,
959
+ // whether to cache responses
960
+ cache : true,
961
+
962
+ // whether new requests should abort previous requests
963
+ interruptRequests : true,
789
964
 
790
965
  // event binding
791
- on : 'auto',
792
- filter : '.disabled',
793
- stateContext : false,
966
+ on : 'auto',
967
+
968
+ // context for applying state classes
969
+ stateContext : false,
970
+
971
+ // duration for loading state
972
+ loadingDuration : 0,
973
+
974
+ // duration for error state
975
+ errorDuration : 2000,
976
+
977
+ // API action to use
978
+ action : false,
979
+
980
+ // templated URL to use
981
+ url : false,
794
982
 
795
- // state
796
- loadingDuration : 0,
797
- errorDuration : 2000,
983
+ // base URL to apply to all endpoints
984
+ base : '',
798
985
 
799
- // templating
800
- action : false,
801
- url : false,
802
- base : '',
986
+ // data that will
987
+ urlData : {},
803
988
 
804
- // data
805
- urlData : {},
989
+ // whether to add default data to url data
990
+ defaultData : true,
806
991
 
807
- // ui
808
- defaultData : true,
809
- serializeForm : false,
810
- throttle : 0,
992
+ // whether to serialize closest form
993
+ serializeForm : false,
811
994
 
812
- // jQ ajax
813
- method : 'get',
814
- data : {},
815
- dataType : 'json',
995
+ // how long to wait before request should occur
996
+ throttle : 0,
816
997
 
817
- // callbacks
998
+ // whether to throttle first request or only repeated
999
+ throttleFirstRequest : true,
1000
+
1001
+ // standard ajax settings
1002
+ method : 'get',
1003
+ data : {},
1004
+ dataType : 'json',
1005
+
1006
+ // mock response
1007
+ mockResponse : false,
1008
+ mockResponseAsync : false,
1009
+
1010
+ // callbacks before request
818
1011
  beforeSend : function(settings) { return settings; },
819
1012
  beforeXHR : function(xhr) {},
820
-
821
1013
  onRequest : function(promise, xhr) {},
1014
+
1015
+ // after request
1016
+ onResponse : false, // function(response) { },
1017
+
1018
+ // response was successful, if JSON passed validation
822
1019
  onSuccess : function(response, $module) {},
1020
+
1021
+ // request finished without aborting
823
1022
  onComplete : function(response, $module) {},
824
- onFailure : function(errorMessage, $module) {},
1023
+
1024
+ // failed JSON success test
1025
+ onFailure : function(response, $module) {},
1026
+
1027
+ // server error
825
1028
  onError : function(errorMessage, $module) {},
1029
+
1030
+ // request aborted
826
1031
  onAbort : function(errorMessage, $module) {},
827
1032
 
828
1033
  successTest : false,
@@ -836,9 +1041,10 @@ $.api.settings = {
836
1041
  legacyParameters : 'You are using legacy API success callback names',
837
1042
  method : 'The method you called is not defined',
838
1043
  missingAction : 'API action used but no url was defined',
839
- missingSerialize : 'Required dependency jquery-serialize-object missing, using basic serialize',
1044
+ missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object',
840
1045
  missingURL : 'No URL specified for api event',
841
1046
  noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.',
1047
+ noStorage : 'Caching respopnses locally requires session storage',
842
1048
  parseError : 'There was an error parsing your request',
843
1049
  requiredParameter : 'Missing a required URL parameter: ',
844
1050
  statusMessage : 'Server gave an error: ',
@@ -846,8 +1052,8 @@ $.api.settings = {
846
1052
  },
847
1053
 
848
1054
  regExp : {
849
- required: /\{\$*[A-z0-9]+\}/g,
850
- optional: /\{\/\$*[A-z0-9]+\}/g,
1055
+ required : /\{\$*[A-z0-9]+\}/g,
1056
+ optional : /\{\/\$*[A-z0-9]+\}/g,
851
1057
  },
852
1058
 
853
1059
  className: {
@@ -856,16 +1062,16 @@ $.api.settings = {
856
1062
  },
857
1063
 
858
1064
  selector: {
859
- form: 'form'
1065
+ disabled : '.disabled',
1066
+ form : 'form'
860
1067
  },
861
1068
 
862
1069
  metadata: {
863
- action : 'action'
1070
+ action : 'action',
1071
+ url : 'url'
864
1072
  }
865
1073
  };
866
1074
 
867
1075
 
868
- $.api.settings.api = {};
869
-
870
1076
 
871
- })( jQuery, window , document );
1077
+ })( jQuery, window , document );