praxis 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (266) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/CHANGELOG.md +16 -0
  4. data/lib/api_browser/Gruntfile.js +125 -16
  5. data/lib/api_browser/app/index.html +5 -1
  6. data/lib/api_browser/app/js/directives/fixed_if_fits.js +28 -17
  7. data/lib/api_browser/app/js/directives/highlight.js +14 -0
  8. data/lib/api_browser/app/js/directives/request_examples.js +29 -0
  9. data/lib/api_browser/app/js/factories/Documentation.js +6 -0
  10. data/lib/api_browser/app/js/factories/Example.js +47 -0
  11. data/lib/api_browser/app/js/factories/prepare_template.js +15 -0
  12. data/lib/api_browser/app/js/factories/template_for.js +2 -12
  13. data/lib/api_browser/app/sass/modules/_sidebar.scss +2 -0
  14. data/lib/api_browser/app/views/action.html +6 -24
  15. data/lib/api_browser/app/views/examples/general.html +26 -0
  16. data/lib/api_browser/{bower.json → bower_template.json} +13 -3
  17. data/lib/api_browser/package.json +3 -1
  18. data/lib/praxis/application.rb +2 -0
  19. data/lib/praxis/docs/generator.rb +4 -2
  20. data/lib/praxis/extensions/field_selection/field_selector.rb +1 -0
  21. data/lib/praxis/media_type.rb +1 -1
  22. data/lib/praxis/plugin.rb +4 -0
  23. data/lib/praxis/plugin_concern.rb +2 -1
  24. data/lib/praxis/tasks/api_docs.rb +9 -2
  25. data/lib/praxis/version.rb +1 -1
  26. data/praxis.gemspec +2 -2
  27. data/spec/praxis/action_definition_spec.rb +26 -1
  28. data/spec/praxis/extensions/field_selection/field_selector_spec.rb +4 -0
  29. data/spec/praxis/media_type_spec.rb +4 -3
  30. data/spec/support/spec_media_types.rb +5 -1
  31. metadata +12 -242
  32. data/lib/api_browser/app/bower_components/angular-mocks/.bower.json +0 -19
  33. data/lib/api_browser/app/bower_components/angular-mocks/README.md +0 -63
  34. data/lib/api_browser/app/bower_components/angular-mocks/angular-mocks.js +0 -2452
  35. data/lib/api_browser/app/bower_components/angular-mocks/bower.json +0 -9
  36. data/lib/api_browser/app/bower_components/angular-mocks/ngAnimateMock.js +0 -2
  37. data/lib/api_browser/app/bower_components/angular-mocks/ngMock.js +0 -2
  38. data/lib/api_browser/app/bower_components/angular-mocks/ngMockE2E.js +0 -2
  39. data/lib/api_browser/app/bower_components/angular-mocks/package.json +0 -27
  40. data/lib/api_browser/app/bower_components/angular-sanitize/.bower.json +0 -19
  41. data/lib/api_browser/app/bower_components/angular-sanitize/README.md +0 -68
  42. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.js +0 -683
  43. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.min.js +0 -16
  44. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.min.js.map +0 -8
  45. data/lib/api_browser/app/bower_components/angular-sanitize/bower.json +0 -9
  46. data/lib/api_browser/app/bower_components/angular-sanitize/index.js +0 -2
  47. data/lib/api_browser/app/bower_components/angular-sanitize/package.json +0 -26
  48. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/.bower.json +0 -31
  49. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/bower.json +0 -19
  50. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-csp.css +0 -6
  51. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.js +0 -4840
  52. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.min.js +0 -10
  53. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap.js +0 -4461
  54. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap.min.js +0 -9
  55. data/lib/api_browser/app/bower_components/angular-ui-router/.bower.json +0 -33
  56. data/lib/api_browser/app/bower_components/angular-ui-router/CHANGELOG.md +0 -228
  57. data/lib/api_browser/app/bower_components/angular-ui-router/CONTRIBUTING.md +0 -65
  58. data/lib/api_browser/app/bower_components/angular-ui-router/LICENSE +0 -21
  59. data/lib/api_browser/app/bower_components/angular-ui-router/README.md +0 -245
  60. data/lib/api_browser/app/bower_components/angular-ui-router/api/angular-ui-router.d.ts +0 -126
  61. data/lib/api_browser/app/bower_components/angular-ui-router/bower.json +0 -23
  62. data/lib/api_browser/app/bower_components/angular-ui-router/release/angular-ui-router.js +0 -4370
  63. data/lib/api_browser/app/bower_components/angular-ui-router/release/angular-ui-router.min.js +0 -7
  64. data/lib/api_browser/app/bower_components/angular-ui-router/src/common.js +0 -292
  65. data/lib/api_browser/app/bower_components/angular-ui-router/src/resolve.js +0 -252
  66. data/lib/api_browser/app/bower_components/angular-ui-router/src/state.js +0 -1465
  67. data/lib/api_browser/app/bower_components/angular-ui-router/src/stateDirectives.js +0 -285
  68. data/lib/api_browser/app/bower_components/angular-ui-router/src/stateFilters.js +0 -39
  69. data/lib/api_browser/app/bower_components/angular-ui-router/src/templateFactory.js +0 -110
  70. data/lib/api_browser/app/bower_components/angular-ui-router/src/urlMatcherFactory.js +0 -1050
  71. data/lib/api_browser/app/bower_components/angular-ui-router/src/urlRouter.js +0 -427
  72. data/lib/api_browser/app/bower_components/angular-ui-router/src/view.js +0 -71
  73. data/lib/api_browser/app/bower_components/angular-ui-router/src/viewDirective.js +0 -303
  74. data/lib/api_browser/app/bower_components/angular-ui-router/src/viewScroll.js +0 -52
  75. data/lib/api_browser/app/bower_components/angular/.bower.json +0 -17
  76. data/lib/api_browser/app/bower_components/angular/README.md +0 -64
  77. data/lib/api_browser/app/bower_components/angular/angular-csp.css +0 -21
  78. data/lib/api_browser/app/bower_components/angular/angular.js +0 -28133
  79. data/lib/api_browser/app/bower_components/angular/angular.min.js +0 -289
  80. data/lib/api_browser/app/bower_components/angular/angular.min.js.gzip +0 -0
  81. data/lib/api_browser/app/bower_components/angular/angular.min.js.map +0 -8
  82. data/lib/api_browser/app/bower_components/angular/bower.json +0 -8
  83. data/lib/api_browser/app/bower_components/angular/index.js +0 -2
  84. data/lib/api_browser/app/bower_components/angular/package.json +0 -25
  85. data/lib/api_browser/app/bower_components/bootstrap-sass/.bower.json +0 -41
  86. data/lib/api_browser/app/bower_components/bootstrap-sass/CHANGELOG.md +0 -108
  87. data/lib/api_browser/app/bower_components/bootstrap-sass/CONTRIBUTING.md +0 -79
  88. data/lib/api_browser/app/bower_components/bootstrap-sass/README.md +0 -218
  89. data/lib/api_browser/app/bower_components/bootstrap-sass/bower.json +0 -22
  90. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
  91. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.svg +0 -229
  92. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
  93. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
  94. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap.js +0 -12
  95. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/affix.js +0 -126
  96. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/alert.js +0 -98
  97. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/button.js +0 -115
  98. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/carousel.js +0 -217
  99. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/collapse.js +0 -179
  100. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/dropdown.js +0 -154
  101. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/modal.js +0 -246
  102. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/popover.js +0 -117
  103. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/scrollspy.js +0 -158
  104. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/tab.js +0 -135
  105. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/tooltip.js +0 -386
  106. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap/transition.js +0 -56
  107. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap.scss +0 -1
  108. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_alerts.scss +0 -67
  109. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_badges.scss +0 -51
  110. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_breadcrumbs.scss +0 -23
  111. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_button-groups.scss +0 -227
  112. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_buttons.scss +0 -155
  113. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_carousel.scss +0 -232
  114. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_close.scss +0 -35
  115. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_code.scss +0 -53
  116. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_component-animations.scss +0 -29
  117. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_dropdowns.scss +0 -188
  118. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_forms.scss +0 -374
  119. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_glyphicons.scss +0 -237
  120. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_grid.scss +0 -79
  121. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_input-groups.scss +0 -136
  122. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_jumbotron.scss +0 -46
  123. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_labels.scss +0 -64
  124. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_list-group.scss +0 -88
  125. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_media.scss +0 -56
  126. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_mixins.scss +0 -848
  127. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_modals.scss +0 -129
  128. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_navbar.scss +0 -616
  129. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_navs.scss +0 -242
  130. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_normalize.scss +0 -406
  131. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_pager.scss +0 -55
  132. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_pagination.scss +0 -85
  133. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_panels.scss +0 -182
  134. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_popovers.scss +0 -133
  135. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_print.scss +0 -105
  136. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_progress-bars.scss +0 -80
  137. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_responsive-utilities.scss +0 -198
  138. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_scaffolding.scss +0 -119
  139. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_tables.scss +0 -231
  140. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_theme.scss +0 -247
  141. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_thumbnails.scss +0 -38
  142. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_tooltip.scss +0 -95
  143. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_type.scss +0 -281
  144. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_utilities.scss +0 -56
  145. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_variables.scss +0 -646
  146. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/_wells.scss +0 -29
  147. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap/bootstrap.scss +0 -49
  148. data/lib/api_browser/app/bower_components/jquery/.bower.json +0 -38
  149. data/lib/api_browser/app/bower_components/jquery/MIT-LICENSE.txt +0 -21
  150. data/lib/api_browser/app/bower_components/jquery/bower.json +0 -27
  151. data/lib/api_browser/app/bower_components/jquery/dist/jquery.js +0 -9190
  152. data/lib/api_browser/app/bower_components/jquery/dist/jquery.min.js +0 -5
  153. data/lib/api_browser/app/bower_components/jquery/dist/jquery.min.map +0 -1
  154. data/lib/api_browser/app/bower_components/jquery/src/ajax.js +0 -806
  155. data/lib/api_browser/app/bower_components/jquery/src/ajax/jsonp.js +0 -89
  156. data/lib/api_browser/app/bower_components/jquery/src/ajax/load.js +0 -75
  157. data/lib/api_browser/app/bower_components/jquery/src/ajax/parseJSON.js +0 -13
  158. data/lib/api_browser/app/bower_components/jquery/src/ajax/parseXML.js +0 -28
  159. data/lib/api_browser/app/bower_components/jquery/src/ajax/script.js +0 -64
  160. data/lib/api_browser/app/bower_components/jquery/src/ajax/var/nonce.js +0 -5
  161. data/lib/api_browser/app/bower_components/jquery/src/ajax/var/rquery.js +0 -3
  162. data/lib/api_browser/app/bower_components/jquery/src/ajax/xhr.js +0 -135
  163. data/lib/api_browser/app/bower_components/jquery/src/attributes.js +0 -11
  164. data/lib/api_browser/app/bower_components/jquery/src/attributes/attr.js +0 -143
  165. data/lib/api_browser/app/bower_components/jquery/src/attributes/classes.js +0 -158
  166. data/lib/api_browser/app/bower_components/jquery/src/attributes/prop.js +0 -96
  167. data/lib/api_browser/app/bower_components/jquery/src/attributes/support.js +0 -35
  168. data/lib/api_browser/app/bower_components/jquery/src/attributes/val.js +0 -163
  169. data/lib/api_browser/app/bower_components/jquery/src/callbacks.js +0 -205
  170. data/lib/api_browser/app/bower_components/jquery/src/core.js +0 -498
  171. data/lib/api_browser/app/bower_components/jquery/src/core/access.js +0 -60
  172. data/lib/api_browser/app/bower_components/jquery/src/core/init.js +0 -123
  173. data/lib/api_browser/app/bower_components/jquery/src/core/parseHTML.js +0 -39
  174. data/lib/api_browser/app/bower_components/jquery/src/core/ready.js +0 -97
  175. data/lib/api_browser/app/bower_components/jquery/src/core/var/rsingleTag.js +0 -4
  176. data/lib/api_browser/app/bower_components/jquery/src/css.js +0 -451
  177. data/lib/api_browser/app/bower_components/jquery/src/css/addGetHookIf.js +0 -24
  178. data/lib/api_browser/app/bower_components/jquery/src/css/curCSS.js +0 -57
  179. data/lib/api_browser/app/bower_components/jquery/src/css/defaultDisplay.js +0 -70
  180. data/lib/api_browser/app/bower_components/jquery/src/css/hiddenVisibleSelectors.js +0 -15
  181. data/lib/api_browser/app/bower_components/jquery/src/css/support.js +0 -91
  182. data/lib/api_browser/app/bower_components/jquery/src/css/swap.js +0 -28
  183. data/lib/api_browser/app/bower_components/jquery/src/css/var/cssExpand.js +0 -3
  184. data/lib/api_browser/app/bower_components/jquery/src/css/var/getStyles.js +0 -5
  185. data/lib/api_browser/app/bower_components/jquery/src/css/var/isHidden.js +0 -13
  186. data/lib/api_browser/app/bower_components/jquery/src/css/var/rmargin.js +0 -3
  187. data/lib/api_browser/app/bower_components/jquery/src/css/var/rnumnonpx.js +0 -5
  188. data/lib/api_browser/app/bower_components/jquery/src/data.js +0 -179
  189. data/lib/api_browser/app/bower_components/jquery/src/data/Data.js +0 -181
  190. data/lib/api_browser/app/bower_components/jquery/src/data/accepts.js +0 -20
  191. data/lib/api_browser/app/bower_components/jquery/src/data/var/data_priv.js +0 -5
  192. data/lib/api_browser/app/bower_components/jquery/src/data/var/data_user.js +0 -5
  193. data/lib/api_browser/app/bower_components/jquery/src/deferred.js +0 -149
  194. data/lib/api_browser/app/bower_components/jquery/src/deprecated.js +0 -13
  195. data/lib/api_browser/app/bower_components/jquery/src/dimensions.js +0 -50
  196. data/lib/api_browser/app/bower_components/jquery/src/effects.js +0 -649
  197. data/lib/api_browser/app/bower_components/jquery/src/effects/Tween.js +0 -114
  198. data/lib/api_browser/app/bower_components/jquery/src/effects/animatedSelector.js +0 -13
  199. data/lib/api_browser/app/bower_components/jquery/src/event.js +0 -868
  200. data/lib/api_browser/app/bower_components/jquery/src/event/alias.js +0 -39
  201. data/lib/api_browser/app/bower_components/jquery/src/event/support.js +0 -9
  202. data/lib/api_browser/app/bower_components/jquery/src/exports/amd.js +0 -24
  203. data/lib/api_browser/app/bower_components/jquery/src/exports/global.js +0 -32
  204. data/lib/api_browser/app/bower_components/jquery/src/intro.js +0 -44
  205. data/lib/api_browser/app/bower_components/jquery/src/jquery.js +0 -36
  206. data/lib/api_browser/app/bower_components/jquery/src/manipulation.js +0 -582
  207. data/lib/api_browser/app/bower_components/jquery/src/manipulation/_evalUrl.js +0 -18
  208. data/lib/api_browser/app/bower_components/jquery/src/manipulation/support.js +0 -31
  209. data/lib/api_browser/app/bower_components/jquery/src/manipulation/var/rcheckableType.js +0 -3
  210. data/lib/api_browser/app/bower_components/jquery/src/offset.js +0 -204
  211. data/lib/api_browser/app/bower_components/jquery/src/outro.js +0 -1
  212. data/lib/api_browser/app/bower_components/jquery/src/queue.js +0 -142
  213. data/lib/api_browser/app/bower_components/jquery/src/queue/delay.js +0 -22
  214. data/lib/api_browser/app/bower_components/jquery/src/selector-native.js +0 -172
  215. data/lib/api_browser/app/bower_components/jquery/src/selector-sizzle.js +0 -14
  216. data/lib/api_browser/app/bower_components/jquery/src/selector.js +0 -1
  217. data/lib/api_browser/app/bower_components/jquery/src/serialize.js +0 -111
  218. data/lib/api_browser/app/bower_components/jquery/src/sizzle/dist/sizzle.js +0 -2044
  219. data/lib/api_browser/app/bower_components/jquery/src/sizzle/dist/sizzle.min.js +0 -3
  220. data/lib/api_browser/app/bower_components/jquery/src/sizzle/dist/sizzle.min.map +0 -1
  221. data/lib/api_browser/app/bower_components/jquery/src/traversing.js +0 -200
  222. data/lib/api_browser/app/bower_components/jquery/src/traversing/findFilter.js +0 -100
  223. data/lib/api_browser/app/bower_components/jquery/src/traversing/var/rneedsContext.js +0 -6
  224. data/lib/api_browser/app/bower_components/jquery/src/var/arr.js +0 -3
  225. data/lib/api_browser/app/bower_components/jquery/src/var/class2type.js +0 -4
  226. data/lib/api_browser/app/bower_components/jquery/src/var/concat.js +0 -5
  227. data/lib/api_browser/app/bower_components/jquery/src/var/hasOwn.js +0 -5
  228. data/lib/api_browser/app/bower_components/jquery/src/var/indexOf.js +0 -5
  229. data/lib/api_browser/app/bower_components/jquery/src/var/pnum.js +0 -3
  230. data/lib/api_browser/app/bower_components/jquery/src/var/push.js +0 -5
  231. data/lib/api_browser/app/bower_components/jquery/src/var/rnotwhite.js +0 -3
  232. data/lib/api_browser/app/bower_components/jquery/src/var/slice.js +0 -5
  233. data/lib/api_browser/app/bower_components/jquery/src/var/strundefined.js +0 -3
  234. data/lib/api_browser/app/bower_components/jquery/src/var/support.js +0 -4
  235. data/lib/api_browser/app/bower_components/jquery/src/var/toString.js +0 -5
  236. data/lib/api_browser/app/bower_components/jquery/src/wrap.js +0 -78
  237. data/lib/api_browser/app/bower_components/lodash/.bower.json +0 -30
  238. data/lib/api_browser/app/bower_components/lodash/LICENSE.txt +0 -22
  239. data/lib/api_browser/app/bower_components/lodash/bower.json +0 -20
  240. data/lib/api_browser/app/bower_components/lodash/lodash.js +0 -12235
  241. data/lib/api_browser/app/bower_components/lodash/lodash.min.js +0 -98
  242. data/lib/api_browser/app/bower_components/showdown/.bower.json +0 -39
  243. data/lib/api_browser/app/bower_components/showdown/.jshintignore +0 -2
  244. data/lib/api_browser/app/bower_components/showdown/.travis.yml +0 -8
  245. data/lib/api_browser/app/bower_components/showdown/Gruntfile.js +0 -100
  246. data/lib/api_browser/app/bower_components/showdown/README.md +0 -317
  247. data/lib/api_browser/app/bower_components/showdown/bower.json +0 -26
  248. data/lib/api_browser/app/bower_components/showdown/compressed/Showdown.js +0 -1606
  249. data/lib/api_browser/app/bower_components/showdown/compressed/Showdown.js.map +0 -1
  250. data/lib/api_browser/app/bower_components/showdown/compressed/Showdown.min.js +0 -2
  251. data/lib/api_browser/app/bower_components/showdown/compressed/extensions/github.min.js +0 -2
  252. data/lib/api_browser/app/bower_components/showdown/compressed/extensions/github.min.js.map +0 -1
  253. data/lib/api_browser/app/bower_components/showdown/compressed/extensions/prettify.min.js +0 -2
  254. data/lib/api_browser/app/bower_components/showdown/compressed/extensions/prettify.min.js.map +0 -1
  255. data/lib/api_browser/app/bower_components/showdown/compressed/extensions/table.min.js +0 -2
  256. data/lib/api_browser/app/bower_components/showdown/compressed/extensions/table.min.js.map +0 -1
  257. data/lib/api_browser/app/bower_components/showdown/compressed/extensions/twitter.min.js +0 -2
  258. data/lib/api_browser/app/bower_components/showdown/compressed/extensions/twitter.min.js.map +0 -1
  259. data/lib/api_browser/app/bower_components/showdown/license.txt +0 -34
  260. data/lib/api_browser/app/bower_components/showdown/package.json +0 -47
  261. data/lib/api_browser/app/bower_components/showdown/src/extensions/github.js +0 -25
  262. data/lib/api_browser/app/bower_components/showdown/src/extensions/prettify.js +0 -29
  263. data/lib/api_browser/app/bower_components/showdown/src/extensions/table.js +0 -106
  264. data/lib/api_browser/app/bower_components/showdown/src/extensions/twitter.js +0 -42
  265. data/lib/api_browser/app/bower_components/showdown/src/ng-showdown.js +0 -150
  266. data/lib/api_browser/app/bower_components/showdown/src/showdown.js +0 -1454
@@ -1,285 +0,0 @@
1
- function parseStateRef(ref, current) {
2
- var preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed;
3
- if (preparsed) ref = current + '(' + preparsed[1] + ')';
4
- parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/);
5
- if (!parsed || parsed.length !== 4) throw new Error("Invalid state ref '" + ref + "'");
6
- return { state: parsed[1], paramExpr: parsed[3] || null };
7
- }
8
-
9
- function stateContext(el) {
10
- var stateData = el.parent().inheritedData('$uiView');
11
-
12
- if (stateData && stateData.state && stateData.state.name) {
13
- return stateData.state;
14
- }
15
- }
16
-
17
- /**
18
- * @ngdoc directive
19
- * @name ui.router.state.directive:ui-sref
20
- *
21
- * @requires ui.router.state.$state
22
- * @requires $timeout
23
- *
24
- * @restrict A
25
- *
26
- * @description
27
- * A directive that binds a link (`<a>` tag) to a state. If the state has an associated
28
- * URL, the directive will automatically generate & update the `href` attribute via
29
- * the {@link ui.router.state.$state#methods_href $state.href()} method. Clicking
30
- * the link will trigger a state transition with optional parameters.
31
- *
32
- * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be
33
- * handled natively by the browser.
34
- *
35
- * You can also use relative state paths within ui-sref, just like the relative
36
- * paths passed to `$state.go()`. You just need to be aware that the path is relative
37
- * to the state that the link lives in, in other words the state that loaded the
38
- * template containing the link.
39
- *
40
- * You can specify options to pass to {@link ui.router.state.$state#go $state.go()}
41
- * using the `ui-sref-opts` attribute. Options are restricted to `location`, `inherit`,
42
- * and `reload`.
43
- *
44
- * @example
45
- * Here's an example of how you'd use ui-sref and how it would compile. If you have the
46
- * following template:
47
- * <pre>
48
- * <a ui-sref="home">Home</a> | <a ui-sref="about">About</a> | <a ui-sref="{page: 2}">Next page</a>
49
- *
50
- * <ul>
51
- * <li ng-repeat="contact in contacts">
52
- * <a ui-sref="contacts.detail({ id: contact.id })">{{ contact.name }}</a>
53
- * </li>
54
- * </ul>
55
- * </pre>
56
- *
57
- * Then the compiled html would be (assuming Html5Mode is off and current state is contacts):
58
- * <pre>
59
- * <a href="#/home" ui-sref="home">Home</a> | <a href="#/about" ui-sref="about">About</a> | <a href="#/contacts?page=2" ui-sref="{page: 2}">Next page</a>
60
- *
61
- * <ul>
62
- * <li ng-repeat="contact in contacts">
63
- * <a href="#/contacts/1" ui-sref="contacts.detail({ id: contact.id })">Joe</a>
64
- * </li>
65
- * <li ng-repeat="contact in contacts">
66
- * <a href="#/contacts/2" ui-sref="contacts.detail({ id: contact.id })">Alice</a>
67
- * </li>
68
- * <li ng-repeat="contact in contacts">
69
- * <a href="#/contacts/3" ui-sref="contacts.detail({ id: contact.id })">Bob</a>
70
- * </li>
71
- * </ul>
72
- *
73
- * <a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
74
- * </pre>
75
- *
76
- * @param {string} ui-sref 'stateName' can be any valid absolute or relative state
77
- * @param {Object} ui-sref-opts options to pass to {@link ui.router.state.$state#go $state.go()}
78
- */
79
- $StateRefDirective.$inject = ['$state', '$timeout'];
80
- function $StateRefDirective($state, $timeout) {
81
- var allowedOptions = ['location', 'inherit', 'reload', 'absolute'];
82
-
83
- return {
84
- restrict: 'A',
85
- require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
86
- link: function(scope, element, attrs, uiSrefActive) {
87
- var ref = parseStateRef(attrs.uiSref, $state.current.name);
88
- var params = null, url = null, base = stateContext(element) || $state.$current;
89
- // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
90
- var hrefKind = Object.prototype.toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
91
- 'xlink:href' : 'href';
92
- var newHref = null, isAnchor = element.prop("tagName").toUpperCase() === "A";
93
- var isForm = element[0].nodeName === "FORM";
94
- var attr = isForm ? "action" : hrefKind, nav = true;
95
-
96
- var options = { relative: base, inherit: true };
97
- var optionsOverride = scope.$eval(attrs.uiSrefOpts) || {};
98
-
99
- angular.forEach(allowedOptions, function(option) {
100
- if (option in optionsOverride) {
101
- options[option] = optionsOverride[option];
102
- }
103
- });
104
-
105
- var update = function(newVal) {
106
- if (newVal) params = angular.copy(newVal);
107
- if (!nav) return;
108
-
109
- newHref = $state.href(ref.state, params, options);
110
-
111
- var activeDirective = uiSrefActive[1] || uiSrefActive[0];
112
- if (activeDirective) {
113
- activeDirective.$$addStateInfo(ref.state, params);
114
- }
115
- if (newHref === null) {
116
- nav = false;
117
- return false;
118
- }
119
- attrs.$set(attr, newHref);
120
- };
121
-
122
- if (ref.paramExpr) {
123
- scope.$watch(ref.paramExpr, function(newVal, oldVal) {
124
- if (newVal !== params) update(newVal);
125
- }, true);
126
- params = angular.copy(scope.$eval(ref.paramExpr));
127
- }
128
- update();
129
-
130
- if (isForm) return;
131
-
132
- element.bind("click", function(e) {
133
- var button = e.which || e.button;
134
- if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {
135
- // HACK: This is to allow ng-clicks to be processed before the transition is initiated:
136
- var transition = $timeout(function() {
137
- $state.go(ref.state, params, options);
138
- });
139
- e.preventDefault();
140
-
141
- // if the state has no URL, ignore one preventDefault from the <a> directive.
142
- var ignorePreventDefaultCount = isAnchor && !newHref ? 1: 0;
143
- e.preventDefault = function() {
144
- if (ignorePreventDefaultCount-- <= 0)
145
- $timeout.cancel(transition);
146
- };
147
- }
148
- });
149
- }
150
- };
151
- }
152
-
153
- /**
154
- * @ngdoc directive
155
- * @name ui.router.state.directive:ui-sref-active
156
- *
157
- * @requires ui.router.state.$state
158
- * @requires ui.router.state.$stateParams
159
- * @requires $interpolate
160
- *
161
- * @restrict A
162
- *
163
- * @description
164
- * A directive working alongside ui-sref to add classes to an element when the
165
- * related ui-sref directive's state is active, and removing them when it is inactive.
166
- * The primary use-case is to simplify the special appearance of navigation menus
167
- * relying on `ui-sref`, by having the "active" state's menu button appear different,
168
- * distinguishing it from the inactive menu items.
169
- *
170
- * ui-sref-active can live on the same element as ui-sref or on a parent element. The first
171
- * ui-sref-active found at the same level or above the ui-sref will be used.
172
- *
173
- * Will activate when the ui-sref's target state or any child state is active. If you
174
- * need to activate only when the ui-sref target state is active and *not* any of
175
- * it's children, then you will use
176
- * {@link ui.router.state.directive:ui-sref-active-eq ui-sref-active-eq}
177
- *
178
- * @example
179
- * Given the following template:
180
- * <pre>
181
- * <ul>
182
- * <li ui-sref-active="active" class="item">
183
- * <a href ui-sref="app.user({user: 'bilbobaggins'})">@bilbobaggins</a>
184
- * </li>
185
- * </ul>
186
- * </pre>
187
- *
188
- *
189
- * When the app state is "app.user" (or any children states), and contains the state parameter "user" with value "bilbobaggins",
190
- * the resulting HTML will appear as (note the 'active' class):
191
- * <pre>
192
- * <ul>
193
- * <li ui-sref-active="active" class="item active">
194
- * <a ui-sref="app.user({user: 'bilbobaggins'})" href="/users/bilbobaggins">@bilbobaggins</a>
195
- * </li>
196
- * </ul>
197
- * </pre>
198
- *
199
- * The class name is interpolated **once** during the directives link time (any further changes to the
200
- * interpolated value are ignored).
201
- *
202
- * Multiple classes may be specified in a space-separated format:
203
- * <pre>
204
- * <ul>
205
- * <li ui-sref-active='class1 class2 class3'>
206
- * <a ui-sref="app.user">link</a>
207
- * </li>
208
- * </ul>
209
- * </pre>
210
- */
211
-
212
- /**
213
- * @ngdoc directive
214
- * @name ui.router.state.directive:ui-sref-active-eq
215
- *
216
- * @requires ui.router.state.$state
217
- * @requires ui.router.state.$stateParams
218
- * @requires $interpolate
219
- *
220
- * @restrict A
221
- *
222
- * @description
223
- * The same as {@link ui.router.state.directive:ui-sref-active ui-sref-active} but will only activate
224
- * when the exact target state used in the `ui-sref` is active; no child states.
225
- *
226
- */
227
- $StateRefActiveDirective.$inject = ['$state', '$stateParams', '$interpolate'];
228
- function $StateRefActiveDirective($state, $stateParams, $interpolate) {
229
- return {
230
- restrict: "A",
231
- controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
232
- var states = [], activeClass;
233
-
234
- // There probably isn't much point in $observing this
235
- // uiSrefActive and uiSrefActiveEq share the same directive object with some
236
- // slight difference in logic routing
237
- activeClass = $interpolate($attrs.uiSrefActiveEq || $attrs.uiSrefActive || '', false)($scope);
238
-
239
- // Allow uiSref to communicate with uiSrefActive[Equals]
240
- this.$$addStateInfo = function (newState, newParams) {
241
- var state = $state.get(newState, stateContext($element));
242
-
243
- states.push({
244
- state: state || { name: newState },
245
- params: newParams
246
- });
247
-
248
- update();
249
- };
250
-
251
- $scope.$on('$stateChangeSuccess', update);
252
-
253
- // Update route state
254
- function update() {
255
- if (anyMatch()) {
256
- $element.addClass(activeClass);
257
- } else {
258
- $element.removeClass(activeClass);
259
- }
260
- }
261
-
262
- function anyMatch() {
263
- for (var i = 0; i < states.length; i++) {
264
- if (isMatch(states[i].state, states[i].params)) {
265
- return true;
266
- }
267
- }
268
- return false;
269
- }
270
-
271
- function isMatch(state, params) {
272
- if (typeof $attrs.uiSrefActiveEq !== 'undefined') {
273
- return $state.is(state.name, params);
274
- } else {
275
- return $state.includes(state.name, params);
276
- }
277
- }
278
- }]
279
- };
280
- }
281
-
282
- angular.module('ui.router.state')
283
- .directive('uiSref', $StateRefDirective)
284
- .directive('uiSrefActive', $StateRefActiveDirective)
285
- .directive('uiSrefActiveEq', $StateRefActiveDirective);
@@ -1,39 +0,0 @@
1
- /**
2
- * @ngdoc filter
3
- * @name ui.router.state.filter:isState
4
- *
5
- * @requires ui.router.state.$state
6
- *
7
- * @description
8
- * Translates to {@link ui.router.state.$state#methods_is $state.is("stateName")}.
9
- */
10
- $IsStateFilter.$inject = ['$state'];
11
- function $IsStateFilter($state) {
12
- var isFilter = function (state) {
13
- return $state.is(state);
14
- };
15
- isFilter.$stateful = true;
16
- return isFilter;
17
- }
18
-
19
- /**
20
- * @ngdoc filter
21
- * @name ui.router.state.filter:includedByState
22
- *
23
- * @requires ui.router.state.$state
24
- *
25
- * @description
26
- * Translates to {@link ui.router.state.$state#methods_includes $state.includes('fullOrPartialStateName')}.
27
- */
28
- $IncludedByStateFilter.$inject = ['$state'];
29
- function $IncludedByStateFilter($state) {
30
- var includesFilter = function (state) {
31
- return $state.includes(state);
32
- };
33
- includesFilter.$stateful = true;
34
- return includesFilter;
35
- }
36
-
37
- angular.module('ui.router.state')
38
- .filter('isState', $IsStateFilter)
39
- .filter('includedByState', $IncludedByStateFilter);
@@ -1,110 +0,0 @@
1
- /**
2
- * @ngdoc object
3
- * @name ui.router.util.$templateFactory
4
- *
5
- * @requires $http
6
- * @requires $templateCache
7
- * @requires $injector
8
- *
9
- * @description
10
- * Service. Manages loading of templates.
11
- */
12
- $TemplateFactory.$inject = ['$http', '$templateCache', '$injector'];
13
- function $TemplateFactory( $http, $templateCache, $injector) {
14
-
15
- /**
16
- * @ngdoc function
17
- * @name ui.router.util.$templateFactory#fromConfig
18
- * @methodOf ui.router.util.$templateFactory
19
- *
20
- * @description
21
- * Creates a template from a configuration object.
22
- *
23
- * @param {object} config Configuration object for which to load a template.
24
- * The following properties are search in the specified order, and the first one
25
- * that is defined is used to create the template:
26
- *
27
- * @param {string|object} config.template html string template or function to
28
- * load via {@link ui.router.util.$templateFactory#fromString fromString}.
29
- * @param {string|object} config.templateUrl url to load or a function returning
30
- * the url to load via {@link ui.router.util.$templateFactory#fromUrl fromUrl}.
31
- * @param {Function} config.templateProvider function to invoke via
32
- * {@link ui.router.util.$templateFactory#fromProvider fromProvider}.
33
- * @param {object} params Parameters to pass to the template function.
34
- * @param {object} locals Locals to pass to `invoke` if the template is loaded
35
- * via a `templateProvider`. Defaults to `{ params: params }`.
36
- *
37
- * @return {string|object} The template html as a string, or a promise for
38
- * that string,or `null` if no template is configured.
39
- */
40
- this.fromConfig = function (config, params, locals) {
41
- return (
42
- isDefined(config.template) ? this.fromString(config.template, params) :
43
- isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :
44
- isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, locals) :
45
- null
46
- );
47
- };
48
-
49
- /**
50
- * @ngdoc function
51
- * @name ui.router.util.$templateFactory#fromString
52
- * @methodOf ui.router.util.$templateFactory
53
- *
54
- * @description
55
- * Creates a template from a string or a function returning a string.
56
- *
57
- * @param {string|object} template html template as a string or function that
58
- * returns an html template as a string.
59
- * @param {object} params Parameters to pass to the template function.
60
- *
61
- * @return {string|object} The template html as a string, or a promise for that
62
- * string.
63
- */
64
- this.fromString = function (template, params) {
65
- return isFunction(template) ? template(params) : template;
66
- };
67
-
68
- /**
69
- * @ngdoc function
70
- * @name ui.router.util.$templateFactory#fromUrl
71
- * @methodOf ui.router.util.$templateFactory
72
- *
73
- * @description
74
- * Loads a template from the a URL via `$http` and `$templateCache`.
75
- *
76
- * @param {string|Function} url url of the template to load, or a function
77
- * that returns a url.
78
- * @param {Object} params Parameters to pass to the url function.
79
- * @return {string|Promise.<string>} The template html as a string, or a promise
80
- * for that string.
81
- */
82
- this.fromUrl = function (url, params) {
83
- if (isFunction(url)) url = url(params);
84
- if (url == null) return null;
85
- else return $http
86
- .get(url, { cache: $templateCache, headers: { Accept: 'text/html' }})
87
- .then(function(response) { return response.data; });
88
- };
89
-
90
- /**
91
- * @ngdoc function
92
- * @name ui.router.util.$templateFactory#fromProvider
93
- * @methodOf ui.router.util.$templateFactory
94
- *
95
- * @description
96
- * Creates a template by invoking an injectable provider function.
97
- *
98
- * @param {Function} provider Function to invoke via `$injector.invoke`
99
- * @param {Object} params Parameters for the template.
100
- * @param {Object} locals Locals to pass to `invoke`. Defaults to
101
- * `{ params: params }`.
102
- * @return {string|Promise.<string>} The template html as a string, or a promise
103
- * for that string.
104
- */
105
- this.fromProvider = function (provider, params, locals) {
106
- return $injector.invoke(provider, null, locals || { params: params });
107
- };
108
- }
109
-
110
- angular.module('ui.router.util').service('$templateFactory', $TemplateFactory);
@@ -1,1050 +0,0 @@
1
- var $$UMFP; // reference to $UrlMatcherFactoryProvider
2
-
3
- /**
4
- * @ngdoc object
5
- * @name ui.router.util.type:UrlMatcher
6
- *
7
- * @description
8
- * Matches URLs against patterns and extracts named parameters from the path or the search
9
- * part of the URL. A URL pattern consists of a path pattern, optionally followed by '?' and a list
10
- * of search parameters. Multiple search parameter names are separated by '&'. Search parameters
11
- * do not influence whether or not a URL is matched, but their values are passed through into
12
- * the matched parameters returned by {@link ui.router.util.type:UrlMatcher#methods_exec exec}.
13
- *
14
- * Path parameter placeholders can be specified using simple colon/catch-all syntax or curly brace
15
- * syntax, which optionally allows a regular expression for the parameter to be specified:
16
- *
17
- * * `':'` name - colon placeholder
18
- * * `'*'` name - catch-all placeholder
19
- * * `'{' name '}'` - curly placeholder
20
- * * `'{' name ':' regexp|type '}'` - curly placeholder with regexp or type name. Should the
21
- * regexp itself contain curly braces, they must be in matched pairs or escaped with a backslash.
22
- *
23
- * Parameter names may contain only word characters (latin letters, digits, and underscore) and
24
- * must be unique within the pattern (across both path and search parameters). For colon
25
- * placeholders or curly placeholders without an explicit regexp, a path parameter matches any
26
- * number of characters other than '/'. For catch-all placeholders the path parameter matches
27
- * any number of characters.
28
- *
29
- * Examples:
30
- *
31
- * * `'/hello/'` - Matches only if the path is exactly '/hello/'. There is no special treatment for
32
- * trailing slashes, and patterns have to match the entire path, not just a prefix.
33
- * * `'/user/:id'` - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or
34
- * '/user/bob/details'. The second path segment will be captured as the parameter 'id'.
35
- * * `'/user/{id}'` - Same as the previous example, but using curly brace syntax.
36
- * * `'/user/{id:[^/]*}'` - Same as the previous example.
37
- * * `'/user/{id:[0-9a-fA-F]{1,8}}'` - Similar to the previous example, but only matches if the id
38
- * parameter consists of 1 to 8 hex digits.
39
- * * `'/files/{path:.*}'` - Matches any URL starting with '/files/' and captures the rest of the
40
- * path into the parameter 'path'.
41
- * * `'/files/*path'` - ditto.
42
- * * `'/calendar/{start:date}'` - Matches "/calendar/2014-11-12" (because the pattern defined
43
- * in the built-in `date` Type matches `2014-11-12`) and provides a Date object in $stateParams.start
44
- *
45
- * @param {string} pattern The pattern to compile into a matcher.
46
- * @param {Object} config A configuration object hash:
47
- * @param {Object=} parentMatcher Used to concatenate the pattern/config onto
48
- * an existing UrlMatcher
49
- *
50
- * * `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`.
51
- * * `strict` - `false` if matching against a URL with a trailing slash should be treated as equivalent to a URL without a trailing slash, the default value is `true`.
52
- *
53
- * @property {string} prefix A static prefix of this pattern. The matcher guarantees that any
54
- * URL matching this matcher (i.e. any string for which {@link ui.router.util.type:UrlMatcher#methods_exec exec()} returns
55
- * non-null) will start with this prefix.
56
- *
57
- * @property {string} source The pattern that was passed into the constructor
58
- *
59
- * @property {string} sourcePath The path portion of the source property
60
- *
61
- * @property {string} sourceSearch The search portion of the source property
62
- *
63
- * @property {string} regex The constructed regex that will be used to match against the url when
64
- * it is time to determine which url will match.
65
- *
66
- * @returns {Object} New `UrlMatcher` object
67
- */
68
- function UrlMatcher(pattern, config, parentMatcher) {
69
- config = extend({ params: {} }, isObject(config) ? config : {});
70
-
71
- // Find all placeholders and create a compiled pattern, using either classic or curly syntax:
72
- // '*' name
73
- // ':' name
74
- // '{' name '}'
75
- // '{' name ':' regexp '}'
76
- // The regular expression is somewhat complicated due to the need to allow curly braces
77
- // inside the regular expression. The placeholder regexp breaks down as follows:
78
- // ([:*])([\w\[\]]+) - classic placeholder ($1 / $2) (search version has - for snake-case)
79
- // \{([\w\[\]]+)(?:\:( ... ))?\} - curly brace placeholder ($3) with optional regexp/type ... ($4) (search version has - for snake-case
80
- // (?: ... | ... | ... )+ - the regexp consists of any number of atoms, an atom being either
81
- // [^{}\\]+ - anything other than curly braces or backslash
82
- // \\. - a backslash escape
83
- // \{(?:[^{}\\]+|\\.)*\} - a matched set of curly braces containing other atoms
84
- var placeholder = /([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,
85
- searchPlaceholder = /([:]?)([\w\[\]-]+)|\{([\w\[\]-]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,
86
- compiled = '^', last = 0, m,
87
- segments = this.segments = [],
88
- parentParams = parentMatcher ? parentMatcher.params : {},
89
- params = this.params = parentMatcher ? parentMatcher.params.$$new() : new $$UMFP.ParamSet(),
90
- paramNames = [];
91
-
92
- function addParameter(id, type, config, location) {
93
- paramNames.push(id);
94
- if (parentParams[id]) return parentParams[id];
95
- if (!/^\w+(-+\w+)*(?:\[\])?$/.test(id)) throw new Error("Invalid parameter name '" + id + "' in pattern '" + pattern + "'");
96
- if (params[id]) throw new Error("Duplicate parameter name '" + id + "' in pattern '" + pattern + "'");
97
- params[id] = new $$UMFP.Param(id, type, config, location);
98
- return params[id];
99
- }
100
-
101
- function quoteRegExp(string, pattern, squash, optional) {
102
- var surroundPattern = ['',''], result = string.replace(/[\\\[\]\^$*+?.()|{}]/g, "\\$&");
103
- if (!pattern) return result;
104
- switch(squash) {
105
- case false: surroundPattern = ['(', ')' + (optional ? "?" : "")]; break;
106
- case true: surroundPattern = ['?(', ')?']; break;
107
- default: surroundPattern = ['(' + squash + "|", ')?']; break;
108
- }
109
- return result + surroundPattern[0] + pattern + surroundPattern[1];
110
- }
111
-
112
- this.source = pattern;
113
-
114
- // Split into static segments separated by path parameter placeholders.
115
- // The number of segments is always 1 more than the number of parameters.
116
- function matchDetails(m, isSearch) {
117
- var id, regexp, segment, type, cfg, arrayMode;
118
- id = m[2] || m[3]; // IE[78] returns '' for unmatched groups instead of null
119
- cfg = config.params[id];
120
- segment = pattern.substring(last, m.index);
121
- regexp = isSearch ? m[4] : m[4] || (m[1] == '*' ? '.*' : null);
122
- type = $$UMFP.type(regexp || "string") || inherit($$UMFP.type("string"), { pattern: new RegExp(regexp, config.caseInsensitive ? 'i' : undefined) });
123
- return {
124
- id: id, regexp: regexp, segment: segment, type: type, cfg: cfg
125
- };
126
- }
127
-
128
- var p, param, segment;
129
- while ((m = placeholder.exec(pattern))) {
130
- p = matchDetails(m, false);
131
- if (p.segment.indexOf('?') >= 0) break; // we're into the search part
132
-
133
- param = addParameter(p.id, p.type, p.cfg, "path");
134
- compiled += quoteRegExp(p.segment, param.type.pattern.source, param.squash, param.isOptional);
135
- segments.push(p.segment);
136
- last = placeholder.lastIndex;
137
- }
138
- segment = pattern.substring(last);
139
-
140
- // Find any search parameter names and remove them from the last segment
141
- var i = segment.indexOf('?');
142
-
143
- if (i >= 0) {
144
- var search = this.sourceSearch = segment.substring(i);
145
- segment = segment.substring(0, i);
146
- this.sourcePath = pattern.substring(0, last + i);
147
-
148
- if (search.length > 0) {
149
- last = 0;
150
- while ((m = searchPlaceholder.exec(search))) {
151
- p = matchDetails(m, true);
152
- param = addParameter(p.id, p.type, p.cfg, "search");
153
- last = placeholder.lastIndex;
154
- // check if ?&
155
- }
156
- }
157
- } else {
158
- this.sourcePath = pattern;
159
- this.sourceSearch = '';
160
- }
161
-
162
- compiled += quoteRegExp(segment) + (config.strict === false ? '\/?' : '') + '$';
163
- segments.push(segment);
164
-
165
- this.regexp = new RegExp(compiled, config.caseInsensitive ? 'i' : undefined);
166
- this.prefix = segments[0];
167
- this.$$paramNames = paramNames;
168
- }
169
-
170
- /**
171
- * @ngdoc function
172
- * @name ui.router.util.type:UrlMatcher#concat
173
- * @methodOf ui.router.util.type:UrlMatcher
174
- *
175
- * @description
176
- * Returns a new matcher for a pattern constructed by appending the path part and adding the
177
- * search parameters of the specified pattern to this pattern. The current pattern is not
178
- * modified. This can be understood as creating a pattern for URLs that are relative to (or
179
- * suffixes of) the current pattern.
180
- *
181
- * @example
182
- * The following two matchers are equivalent:
183
- * <pre>
184
- * new UrlMatcher('/user/{id}?q').concat('/details?date');
185
- * new UrlMatcher('/user/{id}/details?q&date');
186
- * </pre>
187
- *
188
- * @param {string} pattern The pattern to append.
189
- * @param {Object} config An object hash of the configuration for the matcher.
190
- * @returns {UrlMatcher} A matcher for the concatenated pattern.
191
- */
192
- UrlMatcher.prototype.concat = function (pattern, config) {
193
- // Because order of search parameters is irrelevant, we can add our own search
194
- // parameters to the end of the new pattern. Parse the new pattern by itself
195
- // and then join the bits together, but it's much easier to do this on a string level.
196
- var defaultConfig = {
197
- caseInsensitive: $$UMFP.caseInsensitive(),
198
- strict: $$UMFP.strictMode(),
199
- squash: $$UMFP.defaultSquashPolicy()
200
- };
201
- return new UrlMatcher(this.sourcePath + pattern + this.sourceSearch, extend(defaultConfig, config), this);
202
- };
203
-
204
- UrlMatcher.prototype.toString = function () {
205
- return this.source;
206
- };
207
-
208
- /**
209
- * @ngdoc function
210
- * @name ui.router.util.type:UrlMatcher#exec
211
- * @methodOf ui.router.util.type:UrlMatcher
212
- *
213
- * @description
214
- * Tests the specified path against this matcher, and returns an object containing the captured
215
- * parameter values, or null if the path does not match. The returned object contains the values
216
- * of any search parameters that are mentioned in the pattern, but their value may be null if
217
- * they are not present in `searchParams`. This means that search parameters are always treated
218
- * as optional.
219
- *
220
- * @example
221
- * <pre>
222
- * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', {
223
- * x: '1', q: 'hello'
224
- * });
225
- * // returns { id: 'bob', q: 'hello', r: null }
226
- * </pre>
227
- *
228
- * @param {string} path The URL path to match, e.g. `$location.path()`.
229
- * @param {Object} searchParams URL search parameters, e.g. `$location.search()`.
230
- * @returns {Object} The captured parameter values.
231
- */
232
- UrlMatcher.prototype.exec = function (path, searchParams) {
233
- var m = this.regexp.exec(path);
234
- if (!m) return null;
235
- searchParams = searchParams || {};
236
-
237
- var paramNames = this.parameters(), nTotal = paramNames.length,
238
- nPath = this.segments.length - 1,
239
- values = {}, i, j, cfg, paramName;
240
-
241
- if (nPath !== m.length - 1) throw new Error("Unbalanced capture group in route '" + this.source + "'");
242
-
243
- function decodePathArray(string) {
244
- function reverseString(str) { return str.split("").reverse().join(""); }
245
- function unquoteDashes(str) { return str.replace(/\\-/g, "-"); }
246
-
247
- var split = reverseString(string).split(/-(?!\\)/);
248
- var allReversed = map(split, reverseString);
249
- return map(allReversed, unquoteDashes).reverse();
250
- }
251
-
252
- for (i = 0; i < nPath; i++) {
253
- paramName = paramNames[i];
254
- var param = this.params[paramName];
255
- var paramVal = m[i+1];
256
- // if the param value matches a pre-replace pair, replace the value before decoding.
257
- for (j = 0; j < param.replace; j++) {
258
- if (param.replace[j].from === paramVal) paramVal = param.replace[j].to;
259
- }
260
- if (paramVal && param.array === true) paramVal = decodePathArray(paramVal);
261
- values[paramName] = param.value(paramVal);
262
- }
263
- for (/**/; i < nTotal; i++) {
264
- paramName = paramNames[i];
265
- values[paramName] = this.params[paramName].value(searchParams[paramName]);
266
- }
267
-
268
- return values;
269
- };
270
-
271
- /**
272
- * @ngdoc function
273
- * @name ui.router.util.type:UrlMatcher#parameters
274
- * @methodOf ui.router.util.type:UrlMatcher
275
- *
276
- * @description
277
- * Returns the names of all path and search parameters of this pattern in an unspecified order.
278
- *
279
- * @returns {Array.<string>} An array of parameter names. Must be treated as read-only. If the
280
- * pattern has no parameters, an empty array is returned.
281
- */
282
- UrlMatcher.prototype.parameters = function (param) {
283
- if (!isDefined(param)) return this.$$paramNames;
284
- return this.params[param] || null;
285
- };
286
-
287
- /**
288
- * @ngdoc function
289
- * @name ui.router.util.type:UrlMatcher#validate
290
- * @methodOf ui.router.util.type:UrlMatcher
291
- *
292
- * @description
293
- * Checks an object hash of parameters to validate their correctness according to the parameter
294
- * types of this `UrlMatcher`.
295
- *
296
- * @param {Object} params The object hash of parameters to validate.
297
- * @returns {boolean} Returns `true` if `params` validates, otherwise `false`.
298
- */
299
- UrlMatcher.prototype.validates = function (params) {
300
- return this.params.$$validates(params);
301
- };
302
-
303
- /**
304
- * @ngdoc function
305
- * @name ui.router.util.type:UrlMatcher#format
306
- * @methodOf ui.router.util.type:UrlMatcher
307
- *
308
- * @description
309
- * Creates a URL that matches this pattern by substituting the specified values
310
- * for the path and search parameters. Null values for path parameters are
311
- * treated as empty strings.
312
- *
313
- * @example
314
- * <pre>
315
- * new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });
316
- * // returns '/user/bob?q=yes'
317
- * </pre>
318
- *
319
- * @param {Object} values the values to substitute for the parameters in this pattern.
320
- * @returns {string} the formatted URL (path and optionally search part).
321
- */
322
- UrlMatcher.prototype.format = function (values) {
323
- values = values || {};
324
- var segments = this.segments, params = this.parameters(), paramset = this.params;
325
- if (!this.validates(values)) return null;
326
-
327
- var i, search = false, nPath = segments.length - 1, nTotal = params.length, result = segments[0];
328
-
329
- function encodeDashes(str) { // Replace dashes with encoded "\-"
330
- return encodeURIComponent(str).replace(/-/g, function(c) { return '%5C%' + c.charCodeAt(0).toString(16).toUpperCase(); });
331
- }
332
-
333
- for (i = 0; i < nTotal; i++) {
334
- var isPathParam = i < nPath;
335
- var name = params[i], param = paramset[name], value = param.value(values[name]);
336
- var isDefaultValue = param.isOptional && param.type.equals(param.value(), value);
337
- var squash = isDefaultValue ? param.squash : false;
338
- var encoded = param.type.encode(value);
339
-
340
- if (isPathParam) {
341
- var nextSegment = segments[i + 1];
342
- if (squash === false) {
343
- if (encoded != null) {
344
- if (isArray(encoded)) {
345
- result += map(encoded, encodeDashes).join("-");
346
- } else {
347
- result += encodeURIComponent(encoded);
348
- }
349
- }
350
- result += nextSegment;
351
- } else if (squash === true) {
352
- var capture = result.match(/\/$/) ? /\/?(.*)/ : /(.*)/;
353
- result += nextSegment.match(capture)[1];
354
- } else if (isString(squash)) {
355
- result += squash + nextSegment;
356
- }
357
- } else {
358
- if (encoded == null || (isDefaultValue && squash !== false)) continue;
359
- if (!isArray(encoded)) encoded = [ encoded ];
360
- encoded = map(encoded, encodeURIComponent).join('&' + name + '=');
361
- result += (search ? '&' : '?') + (name + '=' + encoded);
362
- search = true;
363
- }
364
- }
365
-
366
- return result;
367
- };
368
-
369
- /**
370
- * @ngdoc object
371
- * @name ui.router.util.type:Type
372
- *
373
- * @description
374
- * Implements an interface to define custom parameter types that can be decoded from and encoded to
375
- * string parameters matched in a URL. Used by {@link ui.router.util.type:UrlMatcher `UrlMatcher`}
376
- * objects when matching or formatting URLs, or comparing or validating parameter values.
377
- *
378
- * See {@link ui.router.util.$urlMatcherFactory#methods_type `$urlMatcherFactory#type()`} for more
379
- * information on registering custom types.
380
- *
381
- * @param {Object} config A configuration object which contains the custom type definition. The object's
382
- * properties will override the default methods and/or pattern in `Type`'s public interface.
383
- * @example
384
- * <pre>
385
- * {
386
- * decode: function(val) { return parseInt(val, 10); },
387
- * encode: function(val) { return val && val.toString(); },
388
- * equals: function(a, b) { return this.is(a) && a === b; },
389
- * is: function(val) { return angular.isNumber(val) isFinite(val) && val % 1 === 0; },
390
- * pattern: /\d+/
391
- * }
392
- * </pre>
393
- *
394
- * @property {RegExp} pattern The regular expression pattern used to match values of this type when
395
- * coming from a substring of a URL.
396
- *
397
- * @returns {Object} Returns a new `Type` object.
398
- */
399
- function Type(config) {
400
- extend(this, config);
401
- }
402
-
403
- /**
404
- * @ngdoc function
405
- * @name ui.router.util.type:Type#is
406
- * @methodOf ui.router.util.type:Type
407
- *
408
- * @description
409
- * Detects whether a value is of a particular type. Accepts a native (decoded) value
410
- * and determines whether it matches the current `Type` object.
411
- *
412
- * @param {*} val The value to check.
413
- * @param {string} key Optional. If the type check is happening in the context of a specific
414
- * {@link ui.router.util.type:UrlMatcher `UrlMatcher`} object, this is the name of the
415
- * parameter in which `val` is stored. Can be used for meta-programming of `Type` objects.
416
- * @returns {Boolean} Returns `true` if the value matches the type, otherwise `false`.
417
- */
418
- Type.prototype.is = function(val, key) {
419
- return true;
420
- };
421
-
422
- /**
423
- * @ngdoc function
424
- * @name ui.router.util.type:Type#encode
425
- * @methodOf ui.router.util.type:Type
426
- *
427
- * @description
428
- * Encodes a custom/native type value to a string that can be embedded in a URL. Note that the
429
- * return value does *not* need to be URL-safe (i.e. passed through `encodeURIComponent()`), it
430
- * only needs to be a representation of `val` that has been coerced to a string.
431
- *
432
- * @param {*} val The value to encode.
433
- * @param {string} key The name of the parameter in which `val` is stored. Can be used for
434
- * meta-programming of `Type` objects.
435
- * @returns {string} Returns a string representation of `val` that can be encoded in a URL.
436
- */
437
- Type.prototype.encode = function(val, key) {
438
- return val;
439
- };
440
-
441
- /**
442
- * @ngdoc function
443
- * @name ui.router.util.type:Type#decode
444
- * @methodOf ui.router.util.type:Type
445
- *
446
- * @description
447
- * Converts a parameter value (from URL string or transition param) to a custom/native value.
448
- *
449
- * @param {string} val The URL parameter value to decode.
450
- * @param {string} key The name of the parameter in which `val` is stored. Can be used for
451
- * meta-programming of `Type` objects.
452
- * @returns {*} Returns a custom representation of the URL parameter value.
453
- */
454
- Type.prototype.decode = function(val, key) {
455
- return val;
456
- };
457
-
458
- /**
459
- * @ngdoc function
460
- * @name ui.router.util.type:Type#equals
461
- * @methodOf ui.router.util.type:Type
462
- *
463
- * @description
464
- * Determines whether two decoded values are equivalent.
465
- *
466
- * @param {*} a A value to compare against.
467
- * @param {*} b A value to compare against.
468
- * @returns {Boolean} Returns `true` if the values are equivalent/equal, otherwise `false`.
469
- */
470
- Type.prototype.equals = function(a, b) {
471
- return a == b;
472
- };
473
-
474
- Type.prototype.$subPattern = function() {
475
- var sub = this.pattern.toString();
476
- return sub.substr(1, sub.length - 2);
477
- };
478
-
479
- Type.prototype.pattern = /.*/;
480
-
481
- Type.prototype.toString = function() { return "{Type:" + this.name + "}"; };
482
-
483
- /** Given an encoded string, or a decoded object, returns a decoded object */
484
- Type.prototype.$normalize = function(val) {
485
- return this.is(val) ? val : this.decode(val);
486
- };
487
-
488
- /*
489
- * Wraps an existing custom Type as an array of Type, depending on 'mode'.
490
- * e.g.:
491
- * - urlmatcher pattern "/path?{queryParam[]:int}"
492
- * - url: "/path?queryParam=1&queryParam=2
493
- * - $stateParams.queryParam will be [1, 2]
494
- * if `mode` is "auto", then
495
- * - url: "/path?queryParam=1 will create $stateParams.queryParam: 1
496
- * - url: "/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]
497
- */
498
- Type.prototype.$asArray = function(mode, isSearch) {
499
- if (!mode) return this;
500
- if (mode === "auto" && !isSearch) throw new Error("'auto' array mode is for query parameters only");
501
-
502
- function ArrayType(type, mode) {
503
- function bindTo(type, callbackName) {
504
- return function() {
505
- return type[callbackName].apply(type, arguments);
506
- };
507
- }
508
-
509
- // Wrap non-array value as array
510
- function arrayWrap(val) { return isArray(val) ? val : (isDefined(val) ? [ val ] : []); }
511
- // Unwrap array value for "auto" mode. Return undefined for empty array.
512
- function arrayUnwrap(val) {
513
- switch(val.length) {
514
- case 0: return undefined;
515
- case 1: return mode === "auto" ? val[0] : val;
516
- default: return val;
517
- }
518
- }
519
- function falsey(val) { return !val; }
520
-
521
- // Wraps type (.is/.encode/.decode) functions to operate on each value of an array
522
- function arrayHandler(callback, allTruthyMode) {
523
- return function handleArray(val) {
524
- val = arrayWrap(val);
525
- var result = map(val, callback);
526
- if (allTruthyMode === true)
527
- return filter(result, falsey).length === 0;
528
- return arrayUnwrap(result);
529
- };
530
- }
531
-
532
- // Wraps type (.equals) functions to operate on each value of an array
533
- function arrayEqualsHandler(callback) {
534
- return function handleArray(val1, val2) {
535
- var left = arrayWrap(val1), right = arrayWrap(val2);
536
- if (left.length !== right.length) return false;
537
- for (var i = 0; i < left.length; i++) {
538
- if (!callback(left[i], right[i])) return false;
539
- }
540
- return true;
541
- };
542
- }
543
-
544
- this.encode = arrayHandler(bindTo(type, 'encode'));
545
- this.decode = arrayHandler(bindTo(type, 'decode'));
546
- this.is = arrayHandler(bindTo(type, 'is'), true);
547
- this.equals = arrayEqualsHandler(bindTo(type, 'equals'));
548
- this.pattern = type.pattern;
549
- this.$normalize = arrayHandler(bindTo(type, '$normalize'));
550
- this.name = type.name;
551
- this.$arrayMode = mode;
552
- }
553
-
554
- return new ArrayType(this, mode);
555
- };
556
-
557
-
558
-
559
- /**
560
- * @ngdoc object
561
- * @name ui.router.util.$urlMatcherFactory
562
- *
563
- * @description
564
- * Factory for {@link ui.router.util.type:UrlMatcher `UrlMatcher`} instances. The factory
565
- * is also available to providers under the name `$urlMatcherFactoryProvider`.
566
- */
567
- function $UrlMatcherFactory() {
568
- $$UMFP = this;
569
-
570
- var isCaseInsensitive = false, isStrictMode = true, defaultSquashPolicy = false;
571
-
572
- function valToString(val) { return val != null ? val.toString().replace(/\//g, "%2F") : val; }
573
- function valFromString(val) { return val != null ? val.toString().replace(/%2F/g, "/") : val; }
574
-
575
- var $types = {}, enqueue = true, typeQueue = [], injector, defaultTypes = {
576
- string: {
577
- encode: valToString,
578
- decode: valFromString,
579
- // TODO: in 1.0, make string .is() return false if value is undefined/null by default.
580
- // In 0.2.x, string params are optional by default for backwards compat
581
- is: function(val) { return val == null || !isDefined(val) || typeof val === "string"; },
582
- pattern: /[^/]*/
583
- },
584
- int: {
585
- encode: valToString,
586
- decode: function(val) { return parseInt(val, 10); },
587
- is: function(val) { return isDefined(val) && this.decode(val.toString()) === val; },
588
- pattern: /\d+/
589
- },
590
- bool: {
591
- encode: function(val) { return val ? 1 : 0; },
592
- decode: function(val) { return parseInt(val, 10) !== 0; },
593
- is: function(val) { return val === true || val === false; },
594
- pattern: /0|1/
595
- },
596
- date: {
597
- encode: function (val) {
598
- if (!this.is(val))
599
- return undefined;
600
- return [ val.getFullYear(),
601
- ('0' + (val.getMonth() + 1)).slice(-2),
602
- ('0' + val.getDate()).slice(-2)
603
- ].join("-");
604
- },
605
- decode: function (val) {
606
- if (this.is(val)) return val;
607
- var match = this.capture.exec(val);
608
- return match ? new Date(match[1], match[2] - 1, match[3]) : undefined;
609
- },
610
- is: function(val) { return val instanceof Date && !isNaN(val.valueOf()); },
611
- equals: function (a, b) { return this.is(a) && this.is(b) && a.toISOString() === b.toISOString(); },
612
- pattern: /[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,
613
- capture: /([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/
614
- },
615
- json: {
616
- encode: angular.toJson,
617
- decode: angular.fromJson,
618
- is: angular.isObject,
619
- equals: angular.equals,
620
- pattern: /[^/]*/
621
- },
622
- any: { // does not encode/decode
623
- encode: angular.identity,
624
- decode: angular.identity,
625
- equals: angular.equals,
626
- pattern: /.*/
627
- }
628
- };
629
-
630
- function getDefaultConfig() {
631
- return {
632
- strict: isStrictMode,
633
- caseInsensitive: isCaseInsensitive
634
- };
635
- }
636
-
637
- function isInjectable(value) {
638
- return (isFunction(value) || (isArray(value) && isFunction(value[value.length - 1])));
639
- }
640
-
641
- /**
642
- * [Internal] Get the default value of a parameter, which may be an injectable function.
643
- */
644
- $UrlMatcherFactory.$$getDefaultValue = function(config) {
645
- if (!isInjectable(config.value)) return config.value;
646
- if (!injector) throw new Error("Injectable functions cannot be called at configuration time");
647
- return injector.invoke(config.value);
648
- };
649
-
650
- /**
651
- * @ngdoc function
652
- * @name ui.router.util.$urlMatcherFactory#caseInsensitive
653
- * @methodOf ui.router.util.$urlMatcherFactory
654
- *
655
- * @description
656
- * Defines whether URL matching should be case sensitive (the default behavior), or not.
657
- *
658
- * @param {boolean} value `false` to match URL in a case sensitive manner; otherwise `true`;
659
- * @returns {boolean} the current value of caseInsensitive
660
- */
661
- this.caseInsensitive = function(value) {
662
- if (isDefined(value))
663
- isCaseInsensitive = value;
664
- return isCaseInsensitive;
665
- };
666
-
667
- /**
668
- * @ngdoc function
669
- * @name ui.router.util.$urlMatcherFactory#strictMode
670
- * @methodOf ui.router.util.$urlMatcherFactory
671
- *
672
- * @description
673
- * Defines whether URLs should match trailing slashes, or not (the default behavior).
674
- *
675
- * @param {boolean=} value `false` to match trailing slashes in URLs, otherwise `true`.
676
- * @returns {boolean} the current value of strictMode
677
- */
678
- this.strictMode = function(value) {
679
- if (isDefined(value))
680
- isStrictMode = value;
681
- return isStrictMode;
682
- };
683
-
684
- /**
685
- * @ngdoc function
686
- * @name ui.router.util.$urlMatcherFactory#defaultSquashPolicy
687
- * @methodOf ui.router.util.$urlMatcherFactory
688
- *
689
- * @description
690
- * Sets the default behavior when generating or matching URLs with default parameter values.
691
- *
692
- * @param {string} value A string that defines the default parameter URL squashing behavior.
693
- * `nosquash`: When generating an href with a default parameter value, do not squash the parameter value from the URL
694
- * `slash`: When generating an href with a default parameter value, squash (remove) the parameter value, and, if the
695
- * parameter is surrounded by slashes, squash (remove) one slash from the URL
696
- * any other string, e.g. "~": When generating an href with a default parameter value, squash (remove)
697
- * the parameter value from the URL and replace it with this string.
698
- */
699
- this.defaultSquashPolicy = function(value) {
700
- if (!isDefined(value)) return defaultSquashPolicy;
701
- if (value !== true && value !== false && !isString(value))
702
- throw new Error("Invalid squash policy: " + value + ". Valid policies: false, true, arbitrary-string");
703
- defaultSquashPolicy = value;
704
- return value;
705
- };
706
-
707
- /**
708
- * @ngdoc function
709
- * @name ui.router.util.$urlMatcherFactory#compile
710
- * @methodOf ui.router.util.$urlMatcherFactory
711
- *
712
- * @description
713
- * Creates a {@link ui.router.util.type:UrlMatcher `UrlMatcher`} for the specified pattern.
714
- *
715
- * @param {string} pattern The URL pattern.
716
- * @param {Object} config The config object hash.
717
- * @returns {UrlMatcher} The UrlMatcher.
718
- */
719
- this.compile = function (pattern, config) {
720
- return new UrlMatcher(pattern, extend(getDefaultConfig(), config));
721
- };
722
-
723
- /**
724
- * @ngdoc function
725
- * @name ui.router.util.$urlMatcherFactory#isMatcher
726
- * @methodOf ui.router.util.$urlMatcherFactory
727
- *
728
- * @description
729
- * Returns true if the specified object is a `UrlMatcher`, or false otherwise.
730
- *
731
- * @param {Object} object The object to perform the type check against.
732
- * @returns {Boolean} Returns `true` if the object matches the `UrlMatcher` interface, by
733
- * implementing all the same methods.
734
- */
735
- this.isMatcher = function (o) {
736
- if (!isObject(o)) return false;
737
- var result = true;
738
-
739
- forEach(UrlMatcher.prototype, function(val, name) {
740
- if (isFunction(val)) {
741
- result = result && (isDefined(o[name]) && isFunction(o[name]));
742
- }
743
- });
744
- return result;
745
- };
746
-
747
- /**
748
- * @ngdoc function
749
- * @name ui.router.util.$urlMatcherFactory#type
750
- * @methodOf ui.router.util.$urlMatcherFactory
751
- *
752
- * @description
753
- * Registers a custom {@link ui.router.util.type:Type `Type`} object that can be used to
754
- * generate URLs with typed parameters.
755
- *
756
- * @param {string} name The type name.
757
- * @param {Object|Function} definition The type definition. See
758
- * {@link ui.router.util.type:Type `Type`} for information on the values accepted.
759
- * @param {Object|Function} definitionFn (optional) A function that is injected before the app
760
- * runtime starts. The result of this function is merged into the existing `definition`.
761
- * See {@link ui.router.util.type:Type `Type`} for information on the values accepted.
762
- *
763
- * @returns {Object} Returns `$urlMatcherFactoryProvider`.
764
- *
765
- * @example
766
- * This is a simple example of a custom type that encodes and decodes items from an
767
- * array, using the array index as the URL-encoded value:
768
- *
769
- * <pre>
770
- * var list = ['John', 'Paul', 'George', 'Ringo'];
771
- *
772
- * $urlMatcherFactoryProvider.type('listItem', {
773
- * encode: function(item) {
774
- * // Represent the list item in the URL using its corresponding index
775
- * return list.indexOf(item);
776
- * },
777
- * decode: function(item) {
778
- * // Look up the list item by index
779
- * return list[parseInt(item, 10)];
780
- * },
781
- * is: function(item) {
782
- * // Ensure the item is valid by checking to see that it appears
783
- * // in the list
784
- * return list.indexOf(item) > -1;
785
- * }
786
- * });
787
- *
788
- * $stateProvider.state('list', {
789
- * url: "/list/{item:listItem}",
790
- * controller: function($scope, $stateParams) {
791
- * console.log($stateParams.item);
792
- * }
793
- * });
794
- *
795
- * // ...
796
- *
797
- * // Changes URL to '/list/3', logs "Ringo" to the console
798
- * $state.go('list', { item: "Ringo" });
799
- * </pre>
800
- *
801
- * This is a more complex example of a type that relies on dependency injection to
802
- * interact with services, and uses the parameter name from the URL to infer how to
803
- * handle encoding and decoding parameter values:
804
- *
805
- * <pre>
806
- * // Defines a custom type that gets a value from a service,
807
- * // where each service gets different types of values from
808
- * // a backend API:
809
- * $urlMatcherFactoryProvider.type('dbObject', {}, function(Users, Posts) {
810
- *
811
- * // Matches up services to URL parameter names
812
- * var services = {
813
- * user: Users,
814
- * post: Posts
815
- * };
816
- *
817
- * return {
818
- * encode: function(object) {
819
- * // Represent the object in the URL using its unique ID
820
- * return object.id;
821
- * },
822
- * decode: function(value, key) {
823
- * // Look up the object by ID, using the parameter
824
- * // name (key) to call the correct service
825
- * return services[key].findById(value);
826
- * },
827
- * is: function(object, key) {
828
- * // Check that object is a valid dbObject
829
- * return angular.isObject(object) && object.id && services[key];
830
- * }
831
- * equals: function(a, b) {
832
- * // Check the equality of decoded objects by comparing
833
- * // their unique IDs
834
- * return a.id === b.id;
835
- * }
836
- * };
837
- * });
838
- *
839
- * // In a config() block, you can then attach URLs with
840
- * // type-annotated parameters:
841
- * $stateProvider.state('users', {
842
- * url: "/users",
843
- * // ...
844
- * }).state('users.item', {
845
- * url: "/{user:dbObject}",
846
- * controller: function($scope, $stateParams) {
847
- * // $stateParams.user will now be an object returned from
848
- * // the Users service
849
- * },
850
- * // ...
851
- * });
852
- * </pre>
853
- */
854
- this.type = function (name, definition, definitionFn) {
855
- if (!isDefined(definition)) return $types[name];
856
- if ($types.hasOwnProperty(name)) throw new Error("A type named '" + name + "' has already been defined.");
857
-
858
- $types[name] = new Type(extend({ name: name }, definition));
859
- if (definitionFn) {
860
- typeQueue.push({ name: name, def: definitionFn });
861
- if (!enqueue) flushTypeQueue();
862
- }
863
- return this;
864
- };
865
-
866
- // `flushTypeQueue()` waits until `$urlMatcherFactory` is injected before invoking the queued `definitionFn`s
867
- function flushTypeQueue() {
868
- while(typeQueue.length) {
869
- var type = typeQueue.shift();
870
- if (type.pattern) throw new Error("You cannot override a type's .pattern at runtime.");
871
- angular.extend($types[type.name], injector.invoke(type.def));
872
- }
873
- }
874
-
875
- // Register default types. Store them in the prototype of $types.
876
- forEach(defaultTypes, function(type, name) { $types[name] = new Type(extend({name: name}, type)); });
877
- $types = inherit($types, {});
878
-
879
- /* No need to document $get, since it returns this */
880
- this.$get = ['$injector', function ($injector) {
881
- injector = $injector;
882
- enqueue = false;
883
- flushTypeQueue();
884
-
885
- forEach(defaultTypes, function(type, name) {
886
- if (!$types[name]) $types[name] = new Type(type);
887
- });
888
- return this;
889
- }];
890
-
891
- this.Param = function Param(id, type, config, location) {
892
- var self = this;
893
- config = unwrapShorthand(config);
894
- type = getType(config, type, location);
895
- var arrayMode = getArrayMode();
896
- type = arrayMode ? type.$asArray(arrayMode, location === "search") : type;
897
- if (type.name === "string" && !arrayMode && location === "path" && config.value === undefined)
898
- config.value = ""; // for 0.2.x; in 0.3.0+ do not automatically default to ""
899
- var isOptional = config.value !== undefined;
900
- var squash = getSquashPolicy(config, isOptional);
901
- var replace = getReplace(config, arrayMode, isOptional, squash);
902
-
903
- function unwrapShorthand(config) {
904
- var keys = isObject(config) ? objectKeys(config) : [];
905
- var isShorthand = indexOf(keys, "value") === -1 && indexOf(keys, "type") === -1 &&
906
- indexOf(keys, "squash") === -1 && indexOf(keys, "array") === -1;
907
- if (isShorthand) config = { value: config };
908
- config.$$fn = isInjectable(config.value) ? config.value : function () { return config.value; };
909
- return config;
910
- }
911
-
912
- function getType(config, urlType, location) {
913
- if (config.type && urlType) throw new Error("Param '"+id+"' has two type configurations.");
914
- if (urlType) return urlType;
915
- if (!config.type) return (location === "config" ? $types.any : $types.string);
916
- return config.type instanceof Type ? config.type : new Type(config.type);
917
- }
918
-
919
- // array config: param name (param[]) overrides default settings. explicit config overrides param name.
920
- function getArrayMode() {
921
- var arrayDefaults = { array: (location === "search" ? "auto" : false) };
922
- var arrayParamNomenclature = id.match(/\[\]$/) ? { array: true } : {};
923
- return extend(arrayDefaults, arrayParamNomenclature, config).array;
924
- }
925
-
926
- /**
927
- * returns false, true, or the squash value to indicate the "default parameter url squash policy".
928
- */
929
- function getSquashPolicy(config, isOptional) {
930
- var squash = config.squash;
931
- if (!isOptional || squash === false) return false;
932
- if (!isDefined(squash) || squash == null) return defaultSquashPolicy;
933
- if (squash === true || isString(squash)) return squash;
934
- throw new Error("Invalid squash policy: '" + squash + "'. Valid policies: false, true, or arbitrary string");
935
- }
936
-
937
- function getReplace(config, arrayMode, isOptional, squash) {
938
- var replace, configuredKeys, defaultPolicy = [
939
- { from: "", to: (isOptional || arrayMode ? undefined : "") },
940
- { from: null, to: (isOptional || arrayMode ? undefined : "") }
941
- ];
942
- replace = isArray(config.replace) ? config.replace : [];
943
- if (isString(squash))
944
- replace.push({ from: squash, to: undefined });
945
- configuredKeys = map(replace, function(item) { return item.from; } );
946
- return filter(defaultPolicy, function(item) { return indexOf(configuredKeys, item.from) === -1; }).concat(replace);
947
- }
948
-
949
- /**
950
- * [Internal] Get the default value of a parameter, which may be an injectable function.
951
- */
952
- function $$getDefaultValue() {
953
- if (!injector) throw new Error("Injectable functions cannot be called at configuration time");
954
- var defaultValue = injector.invoke(config.$$fn);
955
- if (defaultValue !== null && defaultValue !== undefined && !self.type.is(defaultValue))
956
- throw new Error("Default value (" + defaultValue + ") for parameter '" + self.id + "' is not an instance of Type (" + self.type.name + ")");
957
- return defaultValue;
958
- }
959
-
960
- /**
961
- * [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the
962
- * default value, which may be the result of an injectable function.
963
- */
964
- function $value(value) {
965
- function hasReplaceVal(val) { return function(obj) { return obj.from === val; }; }
966
- function $replace(value) {
967
- var replacement = map(filter(self.replace, hasReplaceVal(value)), function(obj) { return obj.to; });
968
- return replacement.length ? replacement[0] : value;
969
- }
970
- value = $replace(value);
971
- return !isDefined(value) ? $$getDefaultValue() : self.type.$normalize(value);
972
- }
973
-
974
- function toString() { return "{Param:" + id + " " + type + " squash: '" + squash + "' optional: " + isOptional + "}"; }
975
-
976
- extend(this, {
977
- id: id,
978
- type: type,
979
- location: location,
980
- array: arrayMode,
981
- squash: squash,
982
- replace: replace,
983
- isOptional: isOptional,
984
- value: $value,
985
- dynamic: undefined,
986
- config: config,
987
- toString: toString
988
- });
989
- };
990
-
991
- function ParamSet(params) {
992
- extend(this, params || {});
993
- }
994
-
995
- ParamSet.prototype = {
996
- $$new: function() {
997
- return inherit(this, extend(new ParamSet(), { $$parent: this}));
998
- },
999
- $$keys: function () {
1000
- var keys = [], chain = [], parent = this,
1001
- ignore = objectKeys(ParamSet.prototype);
1002
- while (parent) { chain.push(parent); parent = parent.$$parent; }
1003
- chain.reverse();
1004
- forEach(chain, function(paramset) {
1005
- forEach(objectKeys(paramset), function(key) {
1006
- if (indexOf(keys, key) === -1 && indexOf(ignore, key) === -1) keys.push(key);
1007
- });
1008
- });
1009
- return keys;
1010
- },
1011
- $$values: function(paramValues) {
1012
- var values = {}, self = this;
1013
- forEach(self.$$keys(), function(key) {
1014
- values[key] = self[key].value(paramValues && paramValues[key]);
1015
- });
1016
- return values;
1017
- },
1018
- $$equals: function(paramValues1, paramValues2) {
1019
- var equal = true, self = this;
1020
- forEach(self.$$keys(), function(key) {
1021
- var left = paramValues1 && paramValues1[key], right = paramValues2 && paramValues2[key];
1022
- if (!self[key].type.equals(left, right)) equal = false;
1023
- });
1024
- return equal;
1025
- },
1026
- $$validates: function $$validate(paramValues) {
1027
- var keys = this.$$keys(), i, param, rawVal, normalized, encoded;
1028
- for (i = 0; i < keys.length; i++) {
1029
- param = this[keys[i]];
1030
- rawVal = paramValues[keys[i]];
1031
- if ((rawVal === undefined || rawVal === null) && param.isOptional)
1032
- break; // There was no parameter value, but the param is optional
1033
- normalized = param.type.$normalize(rawVal);
1034
- if (!param.type.is(normalized))
1035
- return false; // The value was not of the correct Type, and could not be decoded to the correct Type
1036
- encoded = param.type.encode(normalized);
1037
- if (angular.isString(encoded) && !param.type.pattern.exec(encoded))
1038
- return false; // The value was of the correct type, but when encoded, did not match the Type's regexp
1039
- }
1040
- return true;
1041
- },
1042
- $$parent: undefined
1043
- };
1044
-
1045
- this.ParamSet = ParamSet;
1046
- }
1047
-
1048
- // Register as a provider so it's available to other providers
1049
- angular.module('ui.router.util').provider('$urlMatcherFactory', $UrlMatcherFactory);
1050
- angular.module('ui.router.util').run(['$urlMatcherFactory', function($urlMatcherFactory) { }]);