solidus_api_v2 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/CHANGELOG.md +38 -0
  5. data/Gemfile +13 -0
  6. data/LICENSE +26 -0
  7. data/README.md +98 -0
  8. data/Rakefile +37 -0
  9. data/app/controllers/concerns/spree/api/v2/renderable.rb +51 -0
  10. data/app/controllers/spree/api/v2/base_controller.rb +31 -0
  11. data/app/controllers/spree/api/v2/children_controller.rb +29 -0
  12. data/app/controllers/spree/api/v2/countries_controller.rb +21 -0
  13. data/app/controllers/spree/api/v2/images_controller.rb +29 -0
  14. data/app/controllers/spree/api/v2/line_items_controller.rb +36 -0
  15. data/app/controllers/spree/api/v2/option_types_controller.rb +31 -0
  16. data/app/controllers/spree/api/v2/option_values_controller.rb +29 -0
  17. data/app/controllers/spree/api/v2/orders_controller.rb +11 -0
  18. data/app/controllers/spree/api/v2/prices_controller.rb +27 -0
  19. data/app/controllers/spree/api/v2/products_controller.rb +37 -0
  20. data/app/controllers/spree/api/v2/states_controller.rb +29 -0
  21. data/app/controllers/spree/api/v2/taxonomies_controller.rb +21 -0
  22. data/app/controllers/spree/api/v2/taxons_controller.rb +40 -0
  23. data/app/controllers/spree/api/v2/variants_controller.rb +35 -0
  24. data/app/models/spree/base_decorator.rb +5 -0
  25. data/app/models/spree/image_decorator.rb +3 -0
  26. data/app/models/spree/price_decorator.rb +3 -0
  27. data/app/models/spree/state_decorator.rb +3 -0
  28. data/app/serializers/spree/address_serializer.rb +9 -0
  29. data/app/serializers/spree/base_serializer.rb +13 -0
  30. data/app/serializers/spree/country_serializer.rb +7 -0
  31. data/app/serializers/spree/error_serializer.rb +52 -0
  32. data/app/serializers/spree/image_serializer.rb +13 -0
  33. data/app/serializers/spree/line_item_serializer.rb +13 -0
  34. data/app/serializers/spree/option_type_serializer.rb +8 -0
  35. data/app/serializers/spree/option_value_serializer.rb +8 -0
  36. data/app/serializers/spree/order_serializer.rb +21 -0
  37. data/app/serializers/spree/price_serializer.rb +7 -0
  38. data/app/serializers/spree/product_serializer.rb +12 -0
  39. data/app/serializers/spree/role_serializer.rb +5 -0
  40. data/app/serializers/spree/state_serializer.rb +7 -0
  41. data/app/serializers/spree/store_serializer.rb +6 -0
  42. data/app/serializers/spree/taxon_serializer.rb +16 -0
  43. data/app/serializers/spree/taxonomy_serializer.rb +7 -0
  44. data/app/serializers/spree/user_serializer.rb +5 -0
  45. data/app/serializers/spree/variant_serializer.rb +12 -0
  46. data/bin/rails +7 -0
  47. data/circle.yml +13 -0
  48. data/config/locales/en.yml +25 -0
  49. data/config/routes.rb +53 -0
  50. data/docs/.nojekyll +0 -0
  51. data/docs/Dockerfile +12 -0
  52. data/docs/Gemfile +13 -0
  53. data/docs/README.md +12 -0
  54. data/docs/Rakefile +9 -0
  55. data/docs/config.rb +39 -0
  56. data/docs/font-selection.json +148 -0
  57. data/docs/source/fonts/slate.eot +0 -0
  58. data/docs/source/fonts/slate.svg +14 -0
  59. data/docs/source/fonts/slate.ttf +0 -0
  60. data/docs/source/fonts/slate.woff +0 -0
  61. data/docs/source/fonts/slate.woff2 +0 -0
  62. data/docs/source/images/logo.png +0 -0
  63. data/docs/source/images/navbar.png +0 -0
  64. data/docs/source/includes/_authentication.md +61 -0
  65. data/docs/source/includes/_countries.md +133 -0
  66. data/docs/source/includes/_errors.md +17 -0
  67. data/docs/source/includes/_filtering.md +11 -0
  68. data/docs/source/includes/_images.md +201 -0
  69. data/docs/source/includes/_line_items.md +137 -0
  70. data/docs/source/includes/_option_types.md +267 -0
  71. data/docs/source/includes/_option_values.md +227 -0
  72. data/docs/source/includes/_orders.md +75 -0
  73. data/docs/source/includes/_pagination.md +10 -0
  74. data/docs/source/includes/_prices.md +188 -0
  75. data/docs/source/includes/_products.md +403 -0
  76. data/docs/source/includes/_states.md +96 -0
  77. data/docs/source/includes/_taxonomies.md +325 -0
  78. data/docs/source/includes/_taxons.md +414 -0
  79. data/docs/source/includes/_variants.md +430 -0
  80. data/docs/source/index.md +53 -0
  81. data/docs/source/javascripts/all.js +4 -0
  82. data/docs/source/javascripts/all_nosearch.js +3 -0
  83. data/docs/source/javascripts/app/_lang.js +162 -0
  84. data/docs/source/javascripts/app/_search.js +74 -0
  85. data/docs/source/javascripts/app/_toc.js +55 -0
  86. data/docs/source/javascripts/lib/_energize.js +169 -0
  87. data/docs/source/javascripts/lib/_imagesloaded.min.js +7 -0
  88. data/docs/source/javascripts/lib/_jquery.highlight.js +108 -0
  89. data/docs/source/javascripts/lib/_jquery.tocify.js +1042 -0
  90. data/docs/source/javascripts/lib/_jquery_ui.js +566 -0
  91. data/docs/source/javascripts/lib/_lunr.js +1910 -0
  92. data/docs/source/layouts/layout.erb +102 -0
  93. data/docs/source/stylesheets/_icon-font.scss +38 -0
  94. data/docs/source/stylesheets/_normalize.css +427 -0
  95. data/docs/source/stylesheets/_syntax.scss.erb +27 -0
  96. data/docs/source/stylesheets/_variables.scss +109 -0
  97. data/docs/source/stylesheets/print.css.scss +142 -0
  98. data/docs/source/stylesheets/screen.css.scss +622 -0
  99. data/lib/solidus_api_v2.rb +5 -0
  100. data/lib/spree_api_v2/engine.rb +21 -0
  101. data/lib/spree_api_v2.rb +4 -0
  102. data/solidus_api_v2.gemspec +36 -0
  103. data/spec/controllers/spree/api/v2/children_controller_spec.rb +28 -0
  104. data/spec/controllers/spree/api/v2/countries_controller_spec.rb +25 -0
  105. data/spec/controllers/spree/api/v2/images_controller_spec.rb +93 -0
  106. data/spec/controllers/spree/api/v2/line_items_controller_spec.rb +86 -0
  107. data/spec/controllers/spree/api/v2/option_types_controller_spec.rb +73 -0
  108. data/spec/controllers/spree/api/v2/option_values_controller_spec.rb +88 -0
  109. data/spec/controllers/spree/api/v2/orders_controller_spec.rb +15 -0
  110. data/spec/controllers/spree/api/v2/prices_controller_spec.rb +55 -0
  111. data/spec/controllers/spree/api/v2/products_controller_spec.rb +95 -0
  112. data/spec/controllers/spree/api/v2/states_controller_spec.rb +42 -0
  113. data/spec/controllers/spree/api/v2/taxonomies_controller_spec.rb +31 -0
  114. data/spec/controllers/spree/api/v2/taxons_controller_spec.rb +54 -0
  115. data/spec/controllers/spree/api/v2/variants_controller_spec.rb +108 -0
  116. data/spec/models/spree/base_decorator_spec.rb +9 -0
  117. data/spec/models/spree/price_decorator_spec.rb +3 -0
  118. data/spec/serializers/spree/address_serializer_spec.rb +35 -0
  119. data/spec/serializers/spree/country_serializer_spec.rb +27 -0
  120. data/spec/serializers/spree/error_serializer_spec.rb +116 -0
  121. data/spec/serializers/spree/image_serializer_spec.rb +30 -0
  122. data/spec/serializers/spree/line_item_serializer_spec.rb +40 -0
  123. data/spec/serializers/spree/option_type_serializer_spec.rb +27 -0
  124. data/spec/serializers/spree/option_value_serializer_spec.rb +29 -0
  125. data/spec/serializers/spree/order_serializer_spec.rb +69 -0
  126. data/spec/serializers/spree/price_serializer_spec.rb +28 -0
  127. data/spec/serializers/spree/product_serializer_spec.rb +47 -0
  128. data/spec/serializers/spree/role_serializer_spec.rb +17 -0
  129. data/spec/serializers/spree/state_serializer_spec.rb +25 -0
  130. data/spec/serializers/spree/store_serializer_spec.rb +25 -0
  131. data/spec/serializers/spree/taxon_serializer_spec.rb +44 -0
  132. data/spec/serializers/spree/taxonomy_serializer_spec.rb +27 -0
  133. data/spec/serializers/spree/user_serializer_spec.rb +17 -0
  134. data/spec/serializers/spree/variant_serializer_spec.rb +55 -0
  135. data/spec/spec_helper.rb +51 -0
  136. data/spec/support/shoulda_matchers.rb +6 -0
  137. data/spree_api_v2.gemspec +36 -0
  138. metadata +437 -0
@@ -0,0 +1,430 @@
1
+ # Variants
2
+
3
+ ## List Variants
4
+
5
+ ```shell
6
+ curl "https://kabuni.com/api/v2/variants"
7
+ ```
8
+
9
+ ```json
10
+ {
11
+ "data": [
12
+ {
13
+ "id": "1",
14
+ "type": "spree_variants",
15
+ "attributes": {
16
+ "sku": "ROR-00011",
17
+ "weight": "0.0",
18
+ "height": "1.0",
19
+ "width": "3.0",
20
+ "depth": "2.0",
21
+ "is_master": true,
22
+ "position": 1,
23
+ "name": "Ruby on Rails Tote",
24
+ "price": "15.99",
25
+ "display_price" : "$15.99 CAD"
26
+ },
27
+ "relationships": {
28
+ "prices": {
29
+ "data": [
30
+ {
31
+ "type": "spree_prices",
32
+ "id": "1"
33
+ },
34
+ {
35
+ "type": "spree_prices",
36
+ "id": "2"
37
+ }
38
+ ]
39
+ },
40
+ "option_values": {
41
+ "data": [
42
+ {
43
+ "type": "spree_option_values",
44
+ "id": "1"
45
+ }
46
+ ]
47
+ },
48
+ "images": {
49
+ "data": [
50
+ {
51
+ "type": "spree_images",
52
+ "id": "1"
53
+ }
54
+ ]
55
+ },
56
+ "product": {
57
+ "data": {
58
+ "type": "spree_products",
59
+ "id": "1"
60
+ }
61
+ }
62
+ }
63
+ }
64
+ ]
65
+ }
66
+ ```
67
+
68
+ List all variants in the DB including master variants.
69
+
70
+ ## Show Variant
71
+
72
+ ```shell
73
+ curl "https://kabuni.com/api/v2/variants/1"
74
+ ```
75
+
76
+ ```json
77
+ {
78
+ "data": {
79
+ "id": "1",
80
+ "type": "spree_variants",
81
+ "attributes": {
82
+ "sku": "ROR-00011",
83
+ "weight": "0.0",
84
+ "height": "1.0",
85
+ "width": "3.0",
86
+ "depth": "2.0",
87
+ "is_master": true,
88
+ "position": 1,
89
+ "name": "Ruby on Rails Tote",
90
+ "price": "15.99",
91
+ "display_price" : "$15.99 CAD"
92
+ },
93
+ "relationships": {
94
+ "prices": {
95
+ "data": [
96
+ {
97
+ "type": "spree_prices",
98
+ "id": "1"
99
+ },
100
+ {
101
+ "type": "spree_prices",
102
+ "id": "2"
103
+ }
104
+ ]
105
+ },
106
+ "option_values": {
107
+ "data": [
108
+ {
109
+ "type": "spree_option_values",
110
+ "id": "1"
111
+ }
112
+ ]
113
+ },
114
+ "images": {
115
+ "data": [
116
+ {
117
+ "type": "spree_images",
118
+ "id": "1"
119
+ }
120
+ ]
121
+ },
122
+ "product": {
123
+ "data": {
124
+ "type": "spree_products",
125
+ "id": "1"
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ Fetch a variant by its `id`.
134
+
135
+ ## List Prices of a Variant
136
+
137
+ ```shell
138
+ curl "https://kabuni.com/api/v2/variants/1/prices"
139
+ ```
140
+
141
+ ```json
142
+ {
143
+ "data": [
144
+ {
145
+ "id": "1",
146
+ "type": "spree_prices",
147
+ "attributes": {
148
+ "amount": "15.99",
149
+ "price": "15.99",
150
+ "display_amount": "$15.99 CAD",
151
+ "display_price": "$15.99 CAD",
152
+ "currency": "CAD"
153
+ },
154
+ "relationships": {
155
+ "variant": {
156
+ "data": {
157
+ "type": "spree_variants",
158
+ "id": "1"
159
+ }
160
+ }
161
+ }
162
+ },
163
+ {
164
+ "id": "2",
165
+ "type": "spree_prices",
166
+ "attributes": {
167
+ "amount": "14.0",
168
+ "price": "14.0",
169
+ "display_amount": "€14,00 EUR",
170
+ "display_price": "€14,00 EUR",
171
+ "currency": "EUR"
172
+ },
173
+ "relationships": {
174
+ "variant": {
175
+ "data": {
176
+ "type": "spree_variants",
177
+ "id": "1"
178
+ }
179
+ }
180
+ }
181
+ }
182
+ ]
183
+ }
184
+ ```
185
+
186
+ List all of the prices for a variant.
187
+
188
+ ## Show Price of a Variant
189
+
190
+ ```shell
191
+ curl "https://kabuni.com/api/v2/variants/1/prices/1"
192
+ ```
193
+
194
+ ```json
195
+ {
196
+ "data": {
197
+ "id": "1",
198
+ "type": "spree_prices",
199
+ "attributes": {
200
+ "amount": "15.99",
201
+ "price": "15.99",
202
+ "display_amount": "$15.99 CAD",
203
+ "display_price": "$15.99 CAD",
204
+ "currency": "CAD"
205
+ },
206
+ "relationships": {
207
+ "variant": {
208
+ "data": {
209
+ "type": "spree_variants",
210
+ "id": "1"
211
+ }
212
+ }
213
+ }
214
+ }
215
+ }
216
+ ```
217
+
218
+ Fetch a price for a variant by the price and variants `id`.
219
+
220
+ ## Show Product of a Variant
221
+
222
+ ```shell
223
+ curl "https://kabuni.com/api/v2/variants/1/product"
224
+ ```
225
+
226
+ ```json
227
+ {
228
+ "data": {
229
+ "id": "1",
230
+ "type": "spree_products",
231
+ "attributes": {
232
+ "name": "Ruby on Rails Tote",
233
+ "description": "Dolorem molestias sint maxime id at rem qui exercitationem. Neque voluptas corrupti magni suscipit iusto voluptatum. Ea quibusdam dolorem inventore praesentium sed dicta eveniet et. Rerum inventore laudantium quisquam earum consequatur dignissimos.",
234
+ "slug": "ruby-on-rails-tote",
235
+ "meta_description": null,
236
+ "meta_keywords": null,
237
+ "store_name": "Whole New Home"
238
+ },
239
+ "relationships": {
240
+ "master": {
241
+ "data": {
242
+ "type": "spree_variants",
243
+ "id": "1"
244
+ }
245
+ },
246
+ "variants": {
247
+ "data": []
248
+ },
249
+ "taxons": {
250
+ "data": [
251
+ {
252
+ "type": "spree_taxons",
253
+ "id": "18"
254
+ },
255
+ ]
256
+ },
257
+ "option_types": {
258
+ "data": [
259
+ {
260
+ "type": "spree_option_types",
261
+ "id": "1"
262
+ }
263
+ ]
264
+ },
265
+ "images": {
266
+ "data": [
267
+ {
268
+ "type": "spree_images",
269
+ "id": "1"
270
+ }
271
+ ]
272
+ }
273
+ }
274
+ }
275
+ }
276
+ ```
277
+
278
+ Fetch the product the a variant belongs to by the variant's `id`.
279
+
280
+ ## List Option Values of a Variant
281
+
282
+ ```shell
283
+ curl "https://kabuni.com/api/v2/variants/1/option_values"
284
+ ```
285
+
286
+ ```json
287
+ {
288
+ "data": [
289
+ {
290
+ "id": "1",
291
+ "type": "spree_option_values",
292
+ "attributes": {
293
+ "name": "Small",
294
+ "presentation": "S",
295
+ "position": 1
296
+ },
297
+ "relationships": {
298
+ "option_type": {
299
+ "data": {
300
+ "type": "spree_option_types",
301
+ "id": "1"
302
+ }
303
+ },
304
+ "variants": {
305
+ "data": [
306
+ {
307
+ "type": "spree_variants",
308
+ "id": "1"
309
+ }
310
+ ]
311
+ }
312
+ }
313
+ }
314
+ ]
315
+ }
316
+ ```
317
+
318
+ List all of the option values that belong to a variant via the variant's `id`.
319
+
320
+ ## Show Option Value of a Variant
321
+
322
+ ```shell
323
+ curl "https://kabuni.com/api/v2/variants/1/option_values/1"
324
+ ```
325
+
326
+ ```json
327
+ {
328
+ "data": {
329
+ "id": "1",
330
+ "type": "spree_option_values",
331
+ "attributes": {
332
+ "name": "Small",
333
+ "presentation": "S",
334
+ "position": 1
335
+ },
336
+ "relationships": {
337
+ "option_type": {
338
+ "data": {
339
+ "type": "spree_option_types",
340
+ "id": "1"
341
+ }
342
+ },
343
+ "variants": {
344
+ "data": [
345
+ {
346
+ "type": "spree_variants",
347
+ "id": "1"
348
+ }
349
+ ]
350
+ }
351
+ }
352
+ }
353
+ }
354
+ ```
355
+
356
+ Fetch an option value via the option value's `id` and the variant's `id`.
357
+
358
+ ## List Images of a Variant
359
+
360
+ ```shell
361
+ curl "https://kabuni.com/api/v2/variants/1/images"
362
+ ```
363
+
364
+ ```json
365
+ {
366
+ "data": [
367
+ {
368
+ "id": "21",
369
+ "type": "spree_images",
370
+ "attributes": {
371
+ "position": 1,
372
+ "alt": null,
373
+ "links": {
374
+ "original": "/spree/products/21/original/ror_tote.jpeg?1442035828",
375
+ "mini": "/spree/products/21/mini/tot_tote.jpeg?1442035828",
376
+ "small": "/spree/products/21/small/ror_tote.jpeg?1442035828",
377
+ "product": "/spree/products/21/product/ror_tote.jpeg?1442035828",
378
+ "large": "/spree/products/21/large/ror_tote.jpeg?1442035828"
379
+ }
380
+ },
381
+ "relationships": {
382
+ "viewable": {
383
+ "data": {
384
+ "type": "spree_variants",
385
+ "id": "1"
386
+ }
387
+ }
388
+ }
389
+ }
390
+ ]
391
+ }
392
+ ```
393
+
394
+ List all of the images of a variant via the variant's `id`.
395
+
396
+ ## Show Image of a Variant
397
+
398
+ ```shell
399
+ curl "https://kabuni.com/api/v2/variants/1/images/21"
400
+ ```
401
+
402
+ ```json
403
+ {
404
+ "data": {
405
+ "id": "21",
406
+ "type": "spree_images",
407
+ "attributes": {
408
+ "position": 1,
409
+ "alt": null,
410
+ "links": {
411
+ "original": "/spree/products/21/original/ror_tote.jpeg?1442035828",
412
+ "mini": "/spree/products/21/mini/tot_tote.jpeg?1442035828",
413
+ "small": "/spree/products/21/small/ror_tote.jpeg?1442035828",
414
+ "product": "/spree/products/21/product/ror_tote.jpeg?1442035828",
415
+ "large": "/spree/products/21/large/ror_tote.jpeg?1442035828"
416
+ }
417
+ },
418
+ "relationships": {
419
+ "viewable": {
420
+ "data": {
421
+ "type": "spree_variants",
422
+ "id": "1"
423
+ }
424
+ }
425
+ }
426
+ }
427
+ }
428
+ ```
429
+
430
+ Fetch an image of a variant via the image and the variant's `id`s.
@@ -0,0 +1,53 @@
1
+ ---
2
+ title: Spree API V2 Reference
3
+
4
+ language_tabs:
5
+ - shell
6
+
7
+ toc_footers:
8
+ - <a href="https://github.com/spree-contrib/spree_api_v2"> Source Code </a>
9
+ - <a href="https://guides.spreecommerce.com/api/" target="_blank"> Spree API Documentation </a>
10
+ - <a href="http://jsonapi.org/" target="_blank"> JSON API Documentation </a>
11
+ - <a href="https://github.com/tripit/slate" target="_blank"> Documentation Powered by Slate </a>
12
+ - <a href="https://kabuni.com?utm_source=SpreeApiV2Docs&utm_medium=sponsor&utm_campaign=opensource"> Kabuni, Proud Sponsor </a>
13
+
14
+ includes:
15
+ - authentication
16
+ - errors
17
+ - pagination
18
+ - filtering
19
+ - countries
20
+ - images
21
+ - line_items
22
+ - option_types
23
+ - option_values
24
+ - orders
25
+ - prices
26
+ - products
27
+ - states
28
+ - taxonomies
29
+ - taxons
30
+ - variants
31
+
32
+ search: true
33
+ ---
34
+
35
+ # Introduction
36
+
37
+ Welcome to the Spree API V2 API!
38
+ You can use our API to grab data from our database and make updates.
39
+
40
+ We currently only have a language binding in Shell.
41
+ You can view code examples in the dark area to the right.
42
+
43
+ This example API documentation page was created with [Slate](http://github.com/tripit/slate).
44
+ Feel free to edit it and use it as a base for your own API's documentation.
45
+
46
+ This JSON API is formatted after the [JSON API spec](http://jsonapi.org).
47
+ Please follow its guidelines to learn about:
48
+
49
+ - Pagination
50
+ - Including Relationships
51
+ - Sorting
52
+ - Error Objects
53
+ - The Document Structure
@@ -0,0 +1,4 @@
1
+ //= require ./lib/_energize
2
+ //= require ./app/_lang
3
+ //= require ./app/_search
4
+ //= require ./app/_toc
@@ -0,0 +1,3 @@
1
+ //= require ./lib/_energize
2
+ //= require ./app/_lang
3
+ //= require ./app/_toc
@@ -0,0 +1,162 @@
1
+ /*
2
+ Copyright 2008-2013 Concur Technologies, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License"); you may
5
+ not use this file except in compliance with the License. You may obtain
6
+ a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ License for the specific language governing permissions and limitations
14
+ under the License.
15
+ */
16
+ (function (global) {
17
+ 'use strict';
18
+
19
+ var languages = [];
20
+
21
+ global.setupLanguages = setupLanguages;
22
+ global.activateLanguage = activateLanguage;
23
+
24
+ function activateLanguage(language) {
25
+ if (!language) return;
26
+ if (language === "") return;
27
+
28
+ $(".lang-selector a").removeClass('active');
29
+ $(".lang-selector a[data-language-name='" + language + "']").addClass('active');
30
+ for (var i=0; i < languages.length; i++) {
31
+ $(".highlight." + languages[i]).hide();
32
+ }
33
+ $(".highlight." + language).show();
34
+
35
+ global.toc.calculateHeights();
36
+
37
+ // scroll to the new location of the position
38
+ if ($(window.location.hash).get(0)) {
39
+ $(window.location.hash).get(0).scrollIntoView(true);
40
+ }
41
+ }
42
+
43
+ // parseURL and stringifyURL are from https://github.com/sindresorhus/query-string
44
+ // MIT licensed
45
+ // https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license
46
+ function parseURL(str) {
47
+ if (typeof str !== 'string') {
48
+ return {};
49
+ }
50
+
51
+ str = str.trim().replace(/^(\?|#|&)/, '');
52
+
53
+ if (!str) {
54
+ return {};
55
+ }
56
+
57
+ return str.split('&').reduce(function (ret, param) {
58
+ var parts = param.replace(/\+/g, ' ').split('=');
59
+ var key = parts[0];
60
+ var val = parts[1];
61
+
62
+ key = decodeURIComponent(key);
63
+ // missing `=` should be `null`:
64
+ // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
65
+ val = val === undefined ? null : decodeURIComponent(val);
66
+
67
+ if (!ret.hasOwnProperty(key)) {
68
+ ret[key] = val;
69
+ } else if (Array.isArray(ret[key])) {
70
+ ret[key].push(val);
71
+ } else {
72
+ ret[key] = [ret[key], val];
73
+ }
74
+
75
+ return ret;
76
+ }, {});
77
+ };
78
+
79
+ function stringifyURL(obj) {
80
+ return obj ? Object.keys(obj).sort().map(function (key) {
81
+ var val = obj[key];
82
+
83
+ if (Array.isArray(val)) {
84
+ return val.sort().map(function (val2) {
85
+ return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
86
+ }).join('&');
87
+ }
88
+
89
+ return encodeURIComponent(key) + '=' + encodeURIComponent(val);
90
+ }).join('&') : '';
91
+ };
92
+
93
+ // gets the language set in the query string
94
+ function getLanguageFromQueryString() {
95
+ if (location.search.length >= 1) {
96
+ var language = parseURL(location.search).language
97
+ if (language) {
98
+ return language;
99
+ } else if (jQuery.inArray(location.search.substr(1), languages) != -1) {
100
+ return location.search.substr(1);
101
+ }
102
+ }
103
+
104
+ return false;
105
+ }
106
+
107
+ // returns a new query string with the new language in it
108
+ function generateNewQueryString(language) {
109
+ var url = parseURL(location.search);
110
+ if (url.language) {
111
+ url.language = language;
112
+ return stringifyURL(url);
113
+ }
114
+ return language;
115
+ }
116
+
117
+ // if a button is clicked, add the state to the history
118
+ function pushURL(language) {
119
+ if (!history) { return; }
120
+ var hash = window.location.hash;
121
+ if (hash) {
122
+ hash = hash.replace(/^#+/, '');
123
+ }
124
+ history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash);
125
+
126
+ // save language as next default
127
+ localStorage.setItem("language", language);
128
+ }
129
+
130
+ function setupLanguages(l) {
131
+ var defaultLanguage = localStorage.getItem("language");
132
+
133
+ languages = l;
134
+
135
+ var presetLanguage = getLanguageFromQueryString();
136
+ if (presetLanguage) {
137
+ // the language is in the URL, so use that language!
138
+ activateLanguage(presetLanguage);
139
+
140
+ localStorage.setItem("language", presetLanguage);
141
+ } else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) {
142
+ // the language was the last selected one saved in localstorage, so use that language!
143
+ activateLanguage(defaultLanguage);
144
+ } else {
145
+ // no language selected, so use the default
146
+ activateLanguage(languages[0]);
147
+ }
148
+ }
149
+
150
+ // if we click on a language tab, activate that language
151
+ $(function() {
152
+ $(".lang-selector a").on("click", function() {
153
+ var language = $(this).data("language-name");
154
+ pushURL(language);
155
+ activateLanguage(language);
156
+ return false;
157
+ });
158
+ window.onpopstate = function() {
159
+ activateLanguage(getLanguageFromQueryString());
160
+ };
161
+ });
162
+ })(window);