jax 0.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (446) hide show
  1. data/.gitignore +12 -0
  2. data/.gitmodules +3 -0
  3. data/.rvmrc +7 -0
  4. data/Gemfile +4 -0
  5. data/README.rdoc +32 -0
  6. data/Rakefile +144 -0
  7. data/bin/jax +11 -0
  8. data/builtin/shaders/basic/common.ejs +11 -0
  9. data/builtin/shaders/basic/fragment.ejs +5 -0
  10. data/builtin/shaders/basic/vertex.ejs +13 -0
  11. data/builtin/shaders/depthmap/common.ejs +1 -0
  12. data/builtin/shaders/depthmap/fragment.ejs +5 -0
  13. data/builtin/shaders/depthmap/vertex.ejs +7 -0
  14. data/builtin/shaders/fog/common.ejs +7 -0
  15. data/builtin/shaders/fog/fragment.ejs +23 -0
  16. data/builtin/shaders/fog/manifest.yml +12 -0
  17. data/builtin/shaders/fog/material.js +34 -0
  18. data/builtin/shaders/fog/vertex.ejs +10 -0
  19. data/builtin/shaders/functions/depth_map.ejs +24 -0
  20. data/builtin/shaders/functions/lights.ejs +155 -0
  21. data/builtin/shaders/lighting/common.ejs +5 -0
  22. data/builtin/shaders/lighting/fragment.ejs +34 -0
  23. data/builtin/shaders/lighting/manifest.yml +4 -0
  24. data/builtin/shaders/lighting/material.js +26 -0
  25. data/builtin/shaders/lighting/vertex.ejs +7 -0
  26. data/builtin/shaders/normal_map/common.ejs +12 -0
  27. data/builtin/shaders/normal_map/fragment.ejs +26 -0
  28. data/builtin/shaders/normal_map/manifest.yml +17 -0
  29. data/builtin/shaders/normal_map/material.js +16 -0
  30. data/builtin/shaders/normal_map/vertex.ejs +57 -0
  31. data/builtin/shaders/paraboloid-depthmap/common.ejs +6 -0
  32. data/builtin/shaders/paraboloid-depthmap/fragment.ejs +8 -0
  33. data/builtin/shaders/paraboloid-depthmap/material.js +15 -0
  34. data/builtin/shaders/paraboloid-depthmap/vertex.ejs +26 -0
  35. data/builtin/shaders/shadow_map/common.ejs +14 -0
  36. data/builtin/shaders/shadow_map/fragment.ejs +66 -0
  37. data/builtin/shaders/shadow_map/manifest.yml +1 -0
  38. data/builtin/shaders/shadow_map/material.js +26 -0
  39. data/builtin/shaders/shadow_map/vertex.ejs +46 -0
  40. data/builtin/shaders/texture/common.ejs +4 -0
  41. data/builtin/shaders/texture/fragment.ejs +11 -0
  42. data/builtin/shaders/texture/manifest.yml +17 -0
  43. data/builtin/shaders/texture/material.js +18 -0
  44. data/builtin/shaders/texture/vertex.ejs +9 -0
  45. data/guides/assets/images/book_icon.gif +0 -0
  46. data/guides/assets/images/bullet.gif +0 -0
  47. data/guides/assets/images/chapters_icon.gif +0 -0
  48. data/guides/assets/images/check_bullet.gif +0 -0
  49. data/guides/assets/images/credits_pic_blank.gif +0 -0
  50. data/guides/assets/images/edge_badge.png +0 -0
  51. data/guides/assets/images/feature_tile.gif +0 -0
  52. data/guides/assets/images/footer_tile.gif +0 -0
  53. data/guides/assets/images/getting_started/clean_passing_jasmine_suite.png +0 -0
  54. data/guides/assets/images/getting_started/rock.png +0 -0
  55. data/guides/assets/images/getting_started/rock_normal.png +0 -0
  56. data/guides/assets/images/grey_bullet.gif +0 -0
  57. data/guides/assets/images/header_backdrop.png +0 -0
  58. data/guides/assets/images/header_tile.gif +0 -0
  59. data/guides/assets/images/icons/README +5 -0
  60. data/guides/assets/images/icons/callouts/1.png +0 -0
  61. data/guides/assets/images/icons/callouts/10.png +0 -0
  62. data/guides/assets/images/icons/callouts/11.png +0 -0
  63. data/guides/assets/images/icons/callouts/12.png +0 -0
  64. data/guides/assets/images/icons/callouts/13.png +0 -0
  65. data/guides/assets/images/icons/callouts/14.png +0 -0
  66. data/guides/assets/images/icons/callouts/15.png +0 -0
  67. data/guides/assets/images/icons/callouts/2.png +0 -0
  68. data/guides/assets/images/icons/callouts/3.png +0 -0
  69. data/guides/assets/images/icons/callouts/4.png +0 -0
  70. data/guides/assets/images/icons/callouts/5.png +0 -0
  71. data/guides/assets/images/icons/callouts/6.png +0 -0
  72. data/guides/assets/images/icons/callouts/7.png +0 -0
  73. data/guides/assets/images/icons/callouts/8.png +0 -0
  74. data/guides/assets/images/icons/callouts/9.png +0 -0
  75. data/guides/assets/images/icons/caution.png +0 -0
  76. data/guides/assets/images/icons/example.png +0 -0
  77. data/guides/assets/images/icons/home.png +0 -0
  78. data/guides/assets/images/icons/important.png +0 -0
  79. data/guides/assets/images/icons/next.png +0 -0
  80. data/guides/assets/images/icons/note.png +0 -0
  81. data/guides/assets/images/icons/prev.png +0 -0
  82. data/guides/assets/images/icons/tip.png +0 -0
  83. data/guides/assets/images/icons/up.png +0 -0
  84. data/guides/assets/images/icons/warning.png +0 -0
  85. data/guides/assets/images/nav_arrow.gif +0 -0
  86. data/guides/assets/images/tab_grey.gif +0 -0
  87. data/guides/assets/images/tab_info.gif +0 -0
  88. data/guides/assets/images/tab_note.gif +0 -0
  89. data/guides/assets/images/tab_red.gif +0 -0
  90. data/guides/assets/images/tab_yellow.gif +0 -0
  91. data/guides/assets/images/tab_yellow.png +0 -0
  92. data/guides/assets/javascripts/guides.js +7 -0
  93. data/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js +59 -0
  94. data/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js +75 -0
  95. data/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js +59 -0
  96. data/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js +65 -0
  97. data/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js +100 -0
  98. data/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js +97 -0
  99. data/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js +91 -0
  100. data/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js +55 -0
  101. data/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js +41 -0
  102. data/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js +52 -0
  103. data/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js +67 -0
  104. data/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js +52 -0
  105. data/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js +57 -0
  106. data/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js +58 -0
  107. data/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js +72 -0
  108. data/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js +88 -0
  109. data/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js +33 -0
  110. data/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js +74 -0
  111. data/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js +64 -0
  112. data/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js +55 -0
  113. data/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js +94 -0
  114. data/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js +51 -0
  115. data/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js +66 -0
  116. data/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js +56 -0
  117. data/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js +69 -0
  118. data/guides/assets/javascripts/syntaxhighlighter/shCore.js +17 -0
  119. data/guides/assets/stylesheets/fixes.css +16 -0
  120. data/guides/assets/stylesheets/main.css +445 -0
  121. data/guides/assets/stylesheets/print.css +52 -0
  122. data/guides/assets/stylesheets/reset.css +43 -0
  123. data/guides/assets/stylesheets/style.css +13 -0
  124. data/guides/assets/stylesheets/syntaxhighlighter/shCore.css +226 -0
  125. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css +328 -0
  126. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css +331 -0
  127. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css +339 -0
  128. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css +324 -0
  129. data/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +328 -0
  130. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css +324 -0
  131. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css +324 -0
  132. data/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css +324 -0
  133. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css +117 -0
  134. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css +120 -0
  135. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css +128 -0
  136. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css +113 -0
  137. data/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +117 -0
  138. data/guides/assets/stylesheets/syntaxhighlighter/shThemeJaxGuides.css +116 -0
  139. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css +113 -0
  140. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css +113 -0
  141. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css +113 -0
  142. data/guides/jax_guides.rb +41 -0
  143. data/guides/jax_guides/common.rb +7 -0
  144. data/guides/jax_guides/generator.rb +287 -0
  145. data/guides/jax_guides/helpers.rb +29 -0
  146. data/guides/jax_guides/indexer.rb +69 -0
  147. data/guides/jax_guides/levenshtein.rb +31 -0
  148. data/guides/jax_guides/textile_extensions.rb +61 -0
  149. data/guides/source/getting_started.textile +1171 -0
  150. data/guides/source/index.html.erb +50 -0
  151. data/guides/source/layout.html.erb +158 -0
  152. data/guides/source/lighting.textile +5 -0
  153. data/guides/source/materials.textile +5 -0
  154. data/guides/source/shaders.textile +5 -0
  155. data/guides/source/testing.textile +5 -0
  156. data/guides/w3c_validator.rb +91 -0
  157. data/jax.gems +1 -0
  158. data/jax.gemspec +40 -0
  159. data/lib/jax.rb +28 -0
  160. data/lib/jax/application.rb +92 -0
  161. data/lib/jax/application/configuration.rb +27 -0
  162. data/lib/jax/generators/app.rb +17 -0
  163. data/lib/jax/generators/app/app_generator.rb +78 -0
  164. data/lib/jax/generators/app/templates/Gemfile.tt +3 -0
  165. data/lib/jax/generators/app/templates/Rakefile +6 -0
  166. data/lib/jax/generators/app/templates/app/controllers/application_controller.js.tt +5 -0
  167. data/lib/jax/generators/app/templates/app/helpers/application_helper.js.tt +3 -0
  168. data/lib/jax/generators/app/templates/app/models/.empty_directory +0 -0
  169. data/lib/jax/generators/app/templates/app/resources/.empty_directory +0 -0
  170. data/lib/jax/generators/app/templates/app/views/.empty_directory +0 -0
  171. data/lib/jax/generators/app/templates/config/application.rb.tt +6 -0
  172. data/lib/jax/generators/app/templates/config/boot.rb +13 -0
  173. data/lib/jax/generators/app/templates/config/routes.rb.tt +5 -0
  174. data/lib/jax/generators/app/templates/public/javascripts/jax.js +7561 -0
  175. data/lib/jax/generators/app/templates/public/webgl_not_supported.html +26 -0
  176. data/lib/jax/generators/app/templates/script/jax +7 -0
  177. data/lib/jax/generators/app/templates/spec/javascripts/controllers/application_controller_spec.js +11 -0
  178. data/lib/jax/generators/app/templates/spec/javascripts/helpers/application_helper_spec.js +12 -0
  179. data/lib/jax/generators/app/templates/spec/javascripts/support/jasmine.yml +90 -0
  180. data/lib/jax/generators/app/templates/spec/javascripts/support/jasmine_config.rb +23 -0
  181. data/lib/jax/generators/app/templates/spec/javascripts/support/jasmine_runner.rb +32 -0
  182. data/lib/jax/generators/app/templates/spec/javascripts/support/spec_helpers/jax_spec_helper.js +216 -0
  183. data/lib/jax/generators/app/templates/spec/javascripts/support/spec_layout.html.erb +63 -0
  184. data/lib/jax/generators/commands.rb +81 -0
  185. data/lib/jax/generators/controller/USAGE +9 -0
  186. data/lib/jax/generators/controller/controller_generator.rb +59 -0
  187. data/lib/jax/generators/controller/templates/controller_source.js.tt +16 -0
  188. data/lib/jax/generators/controller/templates/controller_test.js.tt +11 -0
  189. data/lib/jax/generators/controller/templates/helper.js.tt +3 -0
  190. data/lib/jax/generators/controller/templates/helper_test.js.tt +12 -0
  191. data/lib/jax/generators/controller/templates/view.js.tt +4 -0
  192. data/lib/jax/generators/light_source/USAGE +14 -0
  193. data/lib/jax/generators/light_source/light_source_generator.rb +47 -0
  194. data/lib/jax/generators/light_source/templates/light.yml.tt +39 -0
  195. data/lib/jax/generators/material/USAGE +29 -0
  196. data/lib/jax/generators/material/material_generator.rb +81 -0
  197. data/lib/jax/generators/material/templates/append.yml.tt +7 -0
  198. data/lib/jax/generators/material/templates/material.yml.tt +33 -0
  199. data/lib/jax/generators/model/USAGE +5 -0
  200. data/lib/jax/generators/model/model_generator.rb +42 -0
  201. data/lib/jax/generators/model/templates/model.js.tt +11 -0
  202. data/lib/jax/generators/model/templates/test.js.tt +11 -0
  203. data/lib/jax/generators/script_jax_loader.rb +32 -0
  204. data/lib/jax/monkeypatch/jasmine.rb +3 -0
  205. data/lib/jax/monkeypatch/jasmine/config.rb +21 -0
  206. data/lib/jax/monkeypatch/jasmine/server.rb +50 -0
  207. data/lib/jax/packager.rb +58 -0
  208. data/lib/jax/packager/sprockets_template.rb +49 -0
  209. data/lib/jax/resource_compiler.rb +50 -0
  210. data/lib/jax/routes.rb +61 -0
  211. data/lib/jax/shader.rb +158 -0
  212. data/lib/jax/tasks/rake.rb +34 -0
  213. data/lib/jax/version.rb +12 -0
  214. data/public/images/brickwall.jpg +0 -0
  215. data/public/images/jacks.jpg +0 -0
  216. data/public/images/normal_map.jpg +0 -0
  217. data/public/images/rock.png +0 -0
  218. data/public/images/rockNormal.png +0 -0
  219. data/public/images/rss.png +0 -0
  220. data/public/webgl_not_supported.html +26 -0
  221. data/spec/example_app/Gemfile +1 -0
  222. data/spec/example_app/Rakefile +15 -0
  223. data/spec/example_app/app/controllers/application_controller.js +5 -0
  224. data/spec/example_app/app/controllers/courthouse_controller.js +24 -0
  225. data/spec/example_app/app/controllers/lighting_controller.js +69 -0
  226. data/spec/example_app/app/controllers/shadows_controller.js +130 -0
  227. data/spec/example_app/app/controllers/textures_controller.js +52 -0
  228. data/spec/example_app/app/helpers/application_helper.js +3 -0
  229. data/spec/example_app/app/helpers/textures_helper.js +3 -0
  230. data/spec/example_app/app/models/character.js +23 -0
  231. data/spec/example_app/app/models/door.js +10 -0
  232. data/spec/example_app/app/models/scene.js +19 -0
  233. data/spec/example_app/app/resources/characters/judge.yml +3 -0
  234. data/spec/example_app/app/resources/doors/courthouse_door.yml +5 -0
  235. data/spec/example_app/app/resources/light_sources/directional_light.yml +13 -0
  236. data/spec/example_app/app/resources/light_sources/point_light.yml +31 -0
  237. data/spec/example_app/app/resources/light_sources/spot_light.yml +15 -0
  238. data/spec/example_app/app/resources/light_sources/sun.yml +7 -0
  239. data/spec/example_app/app/resources/light_sources/textures_point.yml +34 -0
  240. data/spec/example_app/app/resources/materials/bricks.yml +36 -0
  241. data/spec/example_app/app/resources/materials/lighting_with_shadows.yml +27 -0
  242. data/spec/example_app/app/resources/scenes/courthouse.yml +4 -0
  243. data/spec/example_app/app/views/courthouse/index.js +4 -0
  244. data/spec/example_app/app/views/lighting/index.js +4 -0
  245. data/spec/example_app/app/views/shadows/index.js +6 -0
  246. data/spec/example_app/app/views/textures/index.js +4 -0
  247. data/spec/example_app/config/application.rb +6 -0
  248. data/spec/example_app/config/boot.rb +13 -0
  249. data/spec/example_app/config/routes.rb +6 -0
  250. data/spec/example_app/public/images/185__normalmap.png +0 -0
  251. data/spec/example_app/public/images/face_norm.jpg +0 -0
  252. data/spec/example_app/public/images/rock.png +0 -0
  253. data/spec/example_app/public/images/rockNormal.png +0 -0
  254. data/spec/example_app/public/images/rss.png +0 -0
  255. data/spec/example_app/public/webgl_not_supported.html +26 -0
  256. data/spec/example_app/script/jax +7 -0
  257. data/spec/example_app/spec/javascripts/controllers/textures_controller_spec.js +11 -0
  258. data/spec/example_app/spec/javascripts/helpers/application_helper_spec.js +12 -0
  259. data/spec/example_app/spec/javascripts/resources/directional_light_spec.js +16 -0
  260. data/spec/example_app/spec/javascripts/resources/point_light_spec.js +17 -0
  261. data/spec/example_app/spec/javascripts/resources/spot_light_spec.js +18 -0
  262. data/spec/example_app/spec/javascripts/support/jasmine.yml +89 -0
  263. data/spec/example_app/spec/javascripts/support/jasmine_runner.rb +32 -0
  264. data/spec/example_app/spec/javascripts/support/spec_helpers/jax_spec_helper.js +93 -0
  265. data/spec/example_app/spec/javascripts/support/spec_layout.html.erb +84 -0
  266. data/spec/generators/app_generator_spec.rb +46 -0
  267. data/spec/generators/controller_generator_spec.rb +68 -0
  268. data/spec/generators/light_generator_spec.rb +51 -0
  269. data/spec/generators/material_generator_spec.rb +35 -0
  270. data/spec/generators/model_generator_spec.rb +43 -0
  271. data/spec/javascripts/Player.js +58 -0
  272. data/spec/javascripts/helpers/SpecHelper.js +216 -0
  273. data/spec/javascripts/jax/builtin/materials/core_materials_spec.js +41 -0
  274. data/spec/javascripts/jax/builtin/materials/dual_paraboloid_spec.js +37 -0
  275. data/spec/javascripts/jax/builtin/materials/fog_spec.js +19 -0
  276. data/spec/javascripts/jax/builtin/materials/lighting_spec.js +19 -0
  277. data/spec/javascripts/jax/builtin/materials/normal_map_spec.js +19 -0
  278. data/spec/javascripts/jax/builtin/materials/shadow_map_spec.js +19 -0
  279. data/spec/javascripts/jax/builtin/materials/texture_spec.js +19 -0
  280. data/spec/javascripts/jax/builtin/meshes/cube_spec.js +10 -0
  281. data/spec/javascripts/jax/builtin/meshes/plane_spec.js +8 -0
  282. data/spec/javascripts/jax/builtin/meshes/quad_spec.js +8 -0
  283. data/spec/javascripts/jax/builtin/meshes/sphere_spec.js +8 -0
  284. data/spec/javascripts/jax/builtin/meshes/teapot_spec.js +8 -0
  285. data/spec/javascripts/jax/builtin/meshes/torus_spec.js +8 -0
  286. data/spec/javascripts/jax/compatibility_spec.js +50 -0
  287. data/spec/javascripts/jax/context_spec.js +82 -0
  288. data/spec/javascripts/jax/controller_spec.js +145 -0
  289. data/spec/javascripts/jax/core/delegation_spec.js +48 -0
  290. data/spec/javascripts/jax/core/events_spec.js +17 -0
  291. data/spec/javascripts/jax/core/matrix_stack_spec.js +28 -0
  292. data/spec/javascripts/jax/core/utils_spec.js +256 -0
  293. data/spec/javascripts/jax/helper_spec.js +33 -0
  294. data/spec/javascripts/jax/model_spec.js +87 -0
  295. data/spec/javascripts/jax/optimizations/material_limitations_spec.js +87 -0
  296. data/spec/javascripts/jax/optimizations/shaders/basic_spec.js +68 -0
  297. data/spec/javascripts/jax/prototype/extensions_spec.js +34 -0
  298. data/spec/javascripts/jax/route_set_spec.js +67 -0
  299. data/spec/javascripts/jax/view_manager_spec.js +17 -0
  300. data/spec/javascripts/jax/webgl/camera_spec.js +159 -0
  301. data/spec/javascripts/jax/webgl/framebuffer_spec.js +46 -0
  302. data/spec/javascripts/jax/webgl/lighting_spec.js +61 -0
  303. data/spec/javascripts/jax/webgl/material_spec.js +118 -0
  304. data/spec/javascripts/jax/webgl/mesh_spec.js +86 -0
  305. data/spec/javascripts/jax/webgl/shader/manifest_spec.js +60 -0
  306. data/spec/javascripts/jax/webgl/shader_chain_spec.js +192 -0
  307. data/spec/javascripts/jax/webgl/shader_spec.js +276 -0
  308. data/spec/javascripts/jax/webgl/tangent_space_spec.js +142 -0
  309. data/spec/javascripts/jax/webgl/texture_spec.js +162 -0
  310. data/spec/javascripts/jax/webgl_spec.js +5 -0
  311. data/spec/javascripts/jax/world_spec.js +88 -0
  312. data/spec/javascripts/jax_spec.js +27 -0
  313. data/spec/javascripts/support/jasmine.yml +85 -0
  314. data/spec/javascripts/support/jasmine_runner.rb +32 -0
  315. data/spec/lib/jax/routes_spec.rb +24 -0
  316. data/spec/lib/jax/shader_spec.rb +57 -0
  317. data/spec/lib/jax/tasks/jax_rake_spec.rb +79 -0
  318. data/spec/spec_helper.rb +11 -0
  319. data/spec/support/file_exist_matcher.rb +23 -0
  320. data/spec/support/spec_shell.rb +97 -0
  321. data/src/jax.js +84 -0
  322. data/src/jax/anim_frame.js +47 -0
  323. data/src/jax/builtin/all.js +7 -0
  324. data/src/jax/builtin/meshes/cube.js +62 -0
  325. data/src/jax/builtin/meshes/plane.js +36 -0
  326. data/src/jax/builtin/meshes/quad.js +80 -0
  327. data/src/jax/builtin/meshes/sphere.js +46 -0
  328. data/src/jax/builtin/meshes/teapot.js +38 -0
  329. data/src/jax/builtin/meshes/torus.js +46 -0
  330. data/src/jax/compatibility.js +140 -0
  331. data/src/jax/context.js +253 -0
  332. data/src/jax/controller.js +157 -0
  333. data/src/jax/core.js +39 -0
  334. data/src/jax/core/math.js +40 -0
  335. data/src/jax/core/matrix_stack.js +306 -0
  336. data/src/jax/core/util.js +226 -0
  337. data/src/jax/events.js +179 -0
  338. data/src/jax/geometry.js +3 -0
  339. data/src/jax/geometry/plane.js +59 -0
  340. data/src/jax/helper.js +8 -0
  341. data/src/jax/model.js +163 -0
  342. data/src/jax/prototype/class.js +78 -0
  343. data/src/jax/prototype/core.js +112 -0
  344. data/src/jax/prototype/extensions.js +124 -0
  345. data/src/jax/route_set.js +125 -0
  346. data/src/jax/vendor/ejs.js +4 -0
  347. data/src/jax/vendor/glMatrix.js +3 -0
  348. data/src/jax/view.js +37 -0
  349. data/src/jax/view_manager.js +46 -0
  350. data/src/jax/webgl.js +98 -0
  351. data/src/jax/webgl/camera.js +526 -0
  352. data/src/jax/webgl/core.js +6 -0
  353. data/src/jax/webgl/core/buffer.js +161 -0
  354. data/src/jax/webgl/core/edge.js +6 -0
  355. data/src/jax/webgl/core/events.js +25 -0
  356. data/src/jax/webgl/core/face.js +8 -0
  357. data/src/jax/webgl/core/framebuffer.js +206 -0
  358. data/src/jax/webgl/material.js +375 -0
  359. data/src/jax/webgl/mesh.js +412 -0
  360. data/src/jax/webgl/scene.js +11 -0
  361. data/src/jax/webgl/scene/frustum.js +260 -0
  362. data/src/jax/webgl/scene/light_manager.js +112 -0
  363. data/src/jax/webgl/scene/light_source.js +248 -0
  364. data/src/jax/webgl/shader.js +282 -0
  365. data/src/jax/webgl/shader/delegator.js +13 -0
  366. data/src/jax/webgl/shader/delegator/attribute.js +53 -0
  367. data/src/jax/webgl/shader/delegator/uniform.js +71 -0
  368. data/src/jax/webgl/shader/manifest.js +64 -0
  369. data/src/jax/webgl/shader/program.js +140 -0
  370. data/src/jax/webgl/shader_chain.js +256 -0
  371. data/src/jax/webgl/texture.js +312 -0
  372. data/src/jax/webgl/world.js +119 -0
  373. data/vendor/ejs/.svn/all-wcprops +17 -0
  374. data/vendor/ejs/.svn/entries +114 -0
  375. data/vendor/ejs/.svn/text-base/Eratta.txt.svn-base +3 -0
  376. data/vendor/ejs/.svn/text-base/license.txt.svn-base +21 -0
  377. data/vendor/ejs/Eratta.txt +3 -0
  378. data/vendor/ejs/example/.svn/all-wcprops +29 -0
  379. data/vendor/ejs/example/.svn/entries +164 -0
  380. data/vendor/ejs/example/.svn/prop-base/ejs.gif.svn-base +5 -0
  381. data/vendor/ejs/example/.svn/text-base/demo.html.svn-base +54 -0
  382. data/vendor/ejs/example/.svn/text-base/ejs.gif.svn-base +0 -0
  383. data/vendor/ejs/example/.svn/text-base/example.css.svn-base +31 -0
  384. data/vendor/ejs/example/.svn/text-base/example.js.svn-base +88 -0
  385. data/vendor/ejs/example/demo.html +54 -0
  386. data/vendor/ejs/example/ejs.gif +0 -0
  387. data/vendor/ejs/example/example.css +31 -0
  388. data/vendor/ejs/example/example.js +88 -0
  389. data/vendor/ejs/lib/.svn/all-wcprops +11 -0
  390. data/vendor/ejs/lib/.svn/entries +62 -0
  391. data/vendor/ejs/lib/.svn/text-base/ejs_fulljslint.js.svn-base +3774 -0
  392. data/vendor/ejs/lib/ejs_fulljslint.js +3774 -0
  393. data/vendor/ejs/license.txt +21 -0
  394. data/vendor/ejs/script/.svn/all-wcprops +17 -0
  395. data/vendor/ejs/script/.svn/entries +96 -0
  396. data/vendor/ejs/script/.svn/prop-base/yuicompressor-2.2.4.jar.svn-base +5 -0
  397. data/vendor/ejs/script/.svn/text-base/production.bat.svn-base +4 -0
  398. data/vendor/ejs/script/.svn/text-base/yuicompressor-2.2.4.jar.svn-base +0 -0
  399. data/vendor/ejs/script/production.bat +4 -0
  400. data/vendor/ejs/script/yuicompressor-2.2.4.jar +0 -0
  401. data/vendor/ejs/src/.svn/all-wcprops +17 -0
  402. data/vendor/ejs/src/.svn/entries +96 -0
  403. data/vendor/ejs/src/.svn/text-base/ejs.js.svn-base +505 -0
  404. data/vendor/ejs/src/.svn/text-base/view.js.svn-base +200 -0
  405. data/vendor/ejs/src/ejs.js +505 -0
  406. data/vendor/ejs/src/view.js +200 -0
  407. data/vendor/ejs/test/.svn/all-wcprops +23 -0
  408. data/vendor/ejs/test/.svn/entries +139 -0
  409. data/vendor/ejs/test/.svn/text-base/index.html.svn-base +18 -0
  410. data/vendor/ejs/test/.svn/text-base/setup_test.html.svn-base +44 -0
  411. data/vendor/ejs/test/.svn/text-base/sidebar.html.svn-base +28 -0
  412. data/vendor/ejs/test/included/.svn/all-wcprops +23 -0
  413. data/vendor/ejs/test/included/.svn/entries +130 -0
  414. data/vendor/ejs/test/included/.svn/text-base/prototype.js.svn-base +4184 -0
  415. data/vendor/ejs/test/included/.svn/text-base/test.css.svn-base +44 -0
  416. data/vendor/ejs/test/included/.svn/text-base/unittest.js.svn-base +564 -0
  417. data/vendor/ejs/test/included/prototype.js +4184 -0
  418. data/vendor/ejs/test/included/test.css +44 -0
  419. data/vendor/ejs/test/included/unittest.js +564 -0
  420. data/vendor/ejs/test/index.html +18 -0
  421. data/vendor/ejs/test/setup_test.html +44 -0
  422. data/vendor/ejs/test/sidebar.html +28 -0
  423. data/vendor/ejs/test/templates/.svn/all-wcprops +11 -0
  424. data/vendor/ejs/test/templates/.svn/entries +62 -0
  425. data/vendor/ejs/test/templates/.svn/text-base/test.ejs.svn-base +3 -0
  426. data/vendor/ejs/test/templates/test.ejs +3 -0
  427. data/vendor/ejs/test/tests/.svn/all-wcprops +23 -0
  428. data/vendor/ejs/test/tests/.svn/entries +130 -0
  429. data/vendor/ejs/test/tests/.svn/text-base/rendering.js.svn-base +94 -0
  430. data/vendor/ejs/test/tests/.svn/text-base/templating.js.svn-base +43 -0
  431. data/vendor/ejs/test/tests/.svn/text-base/views.js.svn-base +100 -0
  432. data/vendor/ejs/test/tests/rendering.js +94 -0
  433. data/vendor/ejs/test/tests/templating.js +43 -0
  434. data/vendor/ejs/test/tests/views.js +100 -0
  435. data/vendor/glmatrix/benchmark/js/CanvasMatrix.js +722 -0
  436. data/vendor/glmatrix/benchmark/js/EWGL_math.js +742 -0
  437. data/vendor/glmatrix/benchmark/js/mjs.js +1230 -0
  438. data/vendor/glmatrix/benchmark/matrix_benchmark.html +419 -0
  439. data/vendor/glmatrix/glMatrix-min.js +32 -0
  440. data/vendor/glmatrix/glMatrix.js +1815 -0
  441. data/vendor/glmatrix/unit tests/glMatrix-test.js +74 -0
  442. data/vendor/glmatrix/unit tests/qunit.css +119 -0
  443. data/vendor/glmatrix/unit tests/qunit.js +1069 -0
  444. data/vendor/glmatrix/unit tests/test_glMatrix.html +21 -0
  445. data/vendor/yuicompressor-2.4.2.jar +0 -0
  446. metadata +748 -0
@@ -0,0 +1,31 @@
1
+ div.example, div.output {
2
+ min-width: 250px;
3
+ min-height: 100px;
4
+ border: 1px solid black;
5
+ margin: 5px;
6
+ padding-top: 0px;
7
+ }
8
+
9
+ hr {
10
+ clear: both;
11
+ }
12
+
13
+ div.example h3 {
14
+ width: 100%;
15
+ color: white;
16
+ background-color: #000066;
17
+ padding: 0px;
18
+ margin: 0px;
19
+ }
20
+
21
+ div.output h3{
22
+ width: 100%;
23
+ color: white;
24
+ background-color: #006600;
25
+ padding: 0px;
26
+ margin: 0px;
27
+ }
28
+
29
+ a img {
30
+ border: 0;
31
+ }
@@ -0,0 +1,88 @@
1
+
2
+ function testUsingText() {
3
+ /*
4
+ * Some DOM Element on your web page is to be the recipient
5
+ * of the processed EJS fragment. This element is assigned
6
+ * to *output*.
7
+ */
8
+ var output = $('output_results');
9
+
10
+ /* Create some fragment of EJS code. Variables from the
11
+ * current scope can be used inside the current EJS code.
12
+ */
13
+ var animals = ['sloth', 'bear', 'monkey'];
14
+ var ejs = "<ul>[% animals.each(function(animal){%]" +
15
+ "<li>[%= animal %]</li>" +
16
+ "[%});%]</ul>";
17
+
18
+ /*
19
+ * Create a new compiler and pass it a reference to the DOM
20
+ * node containing the source.
21
+ */
22
+ var compiler = new EjsCompiler(ejs);
23
+
24
+ /*
25
+ * Call the compile() function
26
+ */
27
+ compiler.compile();
28
+
29
+ /*
30
+ * View the compiled results
31
+ */
32
+ $('output_code').innerHTML = compiler.out.escapeHTML();
33
+
34
+ /*
35
+ * Evaluate the compiled EJS code and save the output as
36
+ * the string *compiled*. This string contains the result.
37
+ */
38
+ var compiled = eval(compiler.out);
39
+
40
+ /*
41
+ * Set the inner HTML of the output node to the result.
42
+ */
43
+ output.innerHTML = compiled;
44
+ }
45
+
46
+
47
+ function testUsingDOM() {
48
+ /*
49
+ * Some DOM Element on your web page has EJS source code
50
+ * within it. This element is assigned to *source*
51
+ *
52
+ * Some DOM Element on your web page is to be the recipient
53
+ * of the processed EJS fragment. This element is assigned
54
+ * to *output*.
55
+ *
56
+ */
57
+ var source = $('source_code');
58
+ var output = $('output_results');
59
+
60
+ /*
61
+ * Create a new compiler and pass it a reference to the DOM
62
+ * node containing the source
63
+ */
64
+ var compiler = new EjsCompiler(source);
65
+
66
+ /*
67
+ * Call the compile() function
68
+ */
69
+ compiler.compile();
70
+
71
+ /*
72
+ * View the compiled results
73
+ */
74
+ $('output_code').innerHTML = compiler.out.escapeHTML();
75
+
76
+ /*
77
+ * Evaluate the compiled EJS code and save the output as
78
+ * the string *compiled*. This string contains the result.
79
+ */
80
+ var compiled = eval(compiler.out);
81
+
82
+ /*
83
+ * Set the inner HTML of the output node to the result.
84
+ */
85
+ output.innerHTML = compiled;
86
+
87
+
88
+ }
@@ -0,0 +1,11 @@
1
+ K 25
2
+ svn:wc:ra_dav:version-url
3
+ V 26
4
+ /svn/!svn/ver/32/trunk/lib
5
+ END
6
+ ejs_fulljslint.js
7
+ K 25
8
+ svn:wc:ra_dav:version-url
9
+ V 44
10
+ /svn/!svn/ver/32/trunk/lib/ejs_fulljslint.js
11
+ END
@@ -0,0 +1,62 @@
1
+ 10
2
+
3
+ dir
4
+ 72
5
+ http://embeddedjavascript.googlecode.com/svn/trunk/lib
6
+ http://embeddedjavascript.googlecode.com/svn
7
+
8
+
9
+
10
+ 2007-12-19T06:39:56.460249Z
11
+ 32
12
+ justinbmeyer
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+ efe5f0e3-6940-0410-82d6-07539bb1838e
28
+
29
+ ejs_fulljslint.js
30
+ file
31
+
32
+
33
+
34
+
35
+ 2011-04-26T10:28:11.000000Z
36
+ 256a65120ea78ed23db397e67debb93b
37
+ 2007-12-19T06:39:56.460249Z
38
+ 32
39
+ justinbmeyer
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+ 135344
62
+
@@ -0,0 +1,3774 @@
1
+ // jslint.js
2
+ // 2007-12-10
3
+ /*
4
+ Copyright (c) 2002 Douglas Crockford (www.JSLint.com)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ this software and associated documentation files (the "Software"), to deal in
8
+ the Software without restriction, including without limitation the rights to
9
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10
+ of the Software, and to permit persons to whom the Software is furnished to do
11
+ so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ The Software shall be used for Good, not Evil.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
25
+ */
26
+
27
+ /*
28
+ JSLINT is a global function. It takes two parameters.
29
+
30
+ var myResult = JSLINT(source, option);
31
+
32
+ The first parameter is either a string or an array of strings. If it is a
33
+ string, it will be split on '\n' or '\r'. If it is an array of strings, it
34
+ is assumed that each string represents one line. The source can be a
35
+ JavaScript text, or HTML text, or a Konfabulator text.
36
+
37
+ The second parameter is an optional object of options which control the
38
+ operation of JSLINT. All of the options are booleans. All are optional and
39
+ have a default value of false.
40
+
41
+ If it checks out, JSLINT returns true. Otherwise, it returns false.
42
+
43
+ If false, you can inspect JSLINT.errors to find out the problems.
44
+ JSLINT.errors is an array of objects containing these members:
45
+
46
+ {
47
+ line : The line (relative to 0) at which the lint was found
48
+ character : The character (relative to 0) at which the lint was found
49
+ reason : The problem
50
+ evidence : The text line in which the problem occurred
51
+ raw : The raw message before the details were inserted
52
+ a : The first detail
53
+ b : The second detail
54
+ c : The third detail
55
+ d : The fourth detail
56
+ }
57
+
58
+ If a fatal error was found, a null will be the last element of the
59
+ JSLINT.errors array.
60
+
61
+ You can request a Function Report, which shows all of the functions
62
+ and the parameters and vars that they use. This can be used to find
63
+ implied global variables and other problems. The report is in HTML and
64
+ can be inserted in a <body>.
65
+
66
+ var myReport = JSLINT.report(option);
67
+
68
+ If the option is true, then the report will be limited to only errors.
69
+ */
70
+
71
+ /*jslint evil: true, nomen: false */
72
+
73
+ /*members "\b", "\t", "\n", "\f", "\r", "\"", "(begin)", "(context)",
74
+ "(end)", "(global)", "(identifier)", "(line)", "(name)", "(params)",
75
+ "(scope)", "(verb)", ")", "++", "--", "\/", ADSAFE, Array, Boolean, COM,
76
+ Canvas, CustomAnimation, Date, Debug, Error, EvalError, FadeAnimation,
77
+ Frame, Function, HotKey, Image, Math, MenuItem, MoveAnimation, Number,
78
+ Object, Point, RangeError, ReferenceError, RegExp, RotateAnimation,
79
+ ScrollBar, String, SyntaxError, Text, TextArea, TypeError, URIError,
80
+ URL, Window, XMLDOM, XMLHttpRequest, "\\", "]", a, abbr, "about-box",
81
+ "about-image", "about-text", "about-version", acronym, action, address,
82
+ adsafe, alert, alignment, anchorstyle, animator, appleScript, applet,
83
+ apply, area, author, autohide, b, background, base, bdo, beep, beget,
84
+ bgcolor, bgcolour, bgopacity, big, bitwise, block, blockquote, blur,
85
+ body, br, browser, button, bytesToUIString, c, call, callee, caller,
86
+ canvas, cap, caption, cases, center, charAt, charCodeAt, character,
87
+ checked, chooseColor, chooseFile, chooseFolder, cite, clearInterval,
88
+ clearTimeout, cliprect, clone, close, closeWidget, closed, code, col,
89
+ colgroup, color, colorize, colour, columns, combine, company, condition,
90
+ confirm, console, constructor, content, contextmenuitems,
91
+ convertPathToHFS, convertPathToPlatform, copyright, d, data, dd, debug,
92
+ decodeURI, decodeURIComponent, defaultStatus, defaulttracking,
93
+ defaultvalue, defineClass, del, description, deserialize, dfn, dir,
94
+ directory, div, dl, doAttribute, doBegin, doIt, doTagName, document, dt,
95
+ dynsrc, editable, em, embed, empty, enabled, encodeURI,
96
+ encodeURIComponent, entityify, eqeqeq, errors, escape, eval, event,
97
+ evidence, evil, exec, exps, extension, fieldset, file, filesystem,
98
+ fillmode, flags, floor, focus, focusWidget, font, fontstyle, forin,
99
+ form, fragment, frame, frames, frameset, from, fromCharCode, fud,
100
+ function, gc, getComputedStyle, group, h1, h2, h3, h4, h5, h6, halign,
101
+ handlelinks, hasOwnProperty, head, height, help, hidden, history,
102
+ hlinesize, hoffset, hotkey, hr, href, hregistrationpoint, hscrollbar,
103
+ hsladjustment, hsltinting, html, i, iTunes, icon, id, identifier,
104
+ iframe, image, img, include, indexOf, init, input, ins, interval,
105
+ isAlpha, isApplicationRunning, isDigit, isFinite, isNaN, join, kbd, key,
106
+ kind, konfabulatorVersion, label, labelled, laxbreak, lbp, led, left,
107
+ legend, length, level, li, line, lines, link, load, loadClass,
108
+ loadingsrc, location, locked, log, lowsrc, map, match, max, maxlength,
109
+ menu, menuitem, message, meta, min, minimumversion, minlength,
110
+ missingsrc, modifier, moveBy, moveTo, name, navigator, new, noframes,
111
+ nomen, noscript, notsaved, nud, object, ol, on, onblur, onclick,
112
+ oncontextmenu, ondragdrop, ondragenter, ondragexit, onerror,
113
+ onfirstdisplay, onfocus, ongainfocus, onimageloaded, onkeydown,
114
+ onkeypress, onkeyup, onload, onlosefocus, onmousedown, onmousedrag,
115
+ onmouseenter, onmouseexit, onmousemove, onmouseup, onmousewheel,
116
+ onmulticlick, onresize, onselect, ontextinput, ontimerfired, onunload,
117
+ onvaluechanged, opacity, open, openURL, opener, opera, optgroup, option,
118
+ optionvalue, order, orientation, p, pagesize, param, parent, parseFloat,
119
+ parseInt, passfail, play, plusplus, pop, popupMenu, pre, preference,
120
+ preferenceGroups, preferencegroup, preferences, print, prompt,
121
+ prototype, push, q, quit, random, raw, reach, readFile, readUrl, reason,
122
+ reloadWidget, remoteasync, replace, report, requiredplatform, reserved,
123
+ resizeBy, resizeTo, resolvePath, resumeUpdates, rhino, right, root,
124
+ rotation, runCommand, runCommandInBg, samp, saveAs, savePreferences,
125
+ screen, script, scroll, scrollBy, scrollTo, scrollbar, scrolling,
126
+ scrollx, scrolly, seal, search, secure, select, self, serialize,
127
+ setInterval, setTimeout, setting, settings, shadow, shift,
128
+ showWidgetPreferences, size, skip, sleep, slice, small, sort, source,
129
+ span, spawn, speak, special, spellcheck, split, src, srcheight,
130
+ srcwidth, status, strong, style, sub, substr, subviews, sup, superview,
131
+ supplant, suppressUpdates, sync, system, table, tag, tbody, td,
132
+ tellWidget, test, text, textarea, tfoot, th, thead, this, thumbcolor,
133
+ ticking, ticklabel, ticks, tileorigin, timer, title, toLowerCase,
134
+ toSource, toString, toint32, token, tooltip, top, tr, tracking, trigger,
135
+ truncation, tt, type, u, ul, undef, unescape, unwatch, updateNow, url,
136
+ usefileicon, valign, value, valueOf, var, version, visible, vlinesize,
137
+ voffset, vregistrationpoint, vscrollbar, watch, white, widget, width,
138
+ window, wrap, yahooCheckLogin, yahooLogin, yahooLogout, zorder
139
+ */
140
+
141
+ // We build the application inside a function so that we produce only a single
142
+ // global variable. The function will be invoked, its return value is the JSLINT
143
+ // function itself.
144
+
145
+ var JSLINT;
146
+ JSLINT = function () {
147
+
148
+ // These are words that should not be permitted in third party ads.
149
+
150
+ var adsafe = {
151
+ apply : true,
152
+ call : true,
153
+ callee : true,
154
+ caller : true,
155
+ clone : true,
156
+ constructor : true,
157
+ 'eval' : true,
158
+ 'new' : true,
159
+ prototype : true,
160
+ source : true,
161
+ 'this' : true,
162
+ toSource : true,
163
+ toString : true,
164
+ unwatch : true,
165
+ valueOf : true,
166
+ watch : true
167
+ },
168
+
169
+ // These are all of the JSLint options.
170
+
171
+ allOptions = {
172
+ adsafe : true, // if use of some browser features should be restricted
173
+ bitwise : true, // if bitwise operators should not be allowed
174
+ browser : true, // if the standard browser globals should be predefined
175
+ cap : true, // if upper case HTML should be allowed
176
+ debug : true, // if debugger statements should be allowed
177
+ eqeqeq : true, // if === should be required
178
+ evil : true, // if eval should be allowed
179
+ forin : true, // if for in statements must filter
180
+ fragment : true, // if HTML fragments should be allowed
181
+ laxbreak : true, // if line breaks should not be checked
182
+ nomen : true, // if names should be checked
183
+ on : true, // if HTML event handlers should be allowed
184
+ passfail : true, // if the scan should stop on first error
185
+ plusplus : true, // if increment/decrement should not be allowed
186
+ rhino : true, // if the Rhino environment globals should be predefined
187
+ undef : true, // if variables should be declared before used
188
+ white : true, // if strict whitespace rules apply
189
+ widget : true // if the Yahoo Widgets globals should be predefined
190
+ },
191
+
192
+ anonname, // The guessed name for anonymous functions.
193
+
194
+ // browser contains a set of global names which are commonly provided by a
195
+ // web browser environment.
196
+
197
+ browser = {
198
+ alert : true,
199
+ blur : true,
200
+ clearInterval : true,
201
+ clearTimeout : true,
202
+ close : true,
203
+ closed : true,
204
+ confirm : true,
205
+ console : true,
206
+ Debug : true,
207
+ defaultStatus : true,
208
+ document : true,
209
+ event : true,
210
+ focus : true,
211
+ frames : true,
212
+ getComputedStyle: true,
213
+ history : true,
214
+ Image : true,
215
+ length : true,
216
+ location : true,
217
+ moveBy : true,
218
+ moveTo : true,
219
+ name : true,
220
+ navigator : true,
221
+ onblur : true,
222
+ onerror : true,
223
+ onfocus : true,
224
+ onload : true,
225
+ onresize : true,
226
+ onunload : true,
227
+ open : true,
228
+ opener : true,
229
+ opera : true,
230
+ parent : true,
231
+ print : true,
232
+ prompt : true,
233
+ resizeBy : true,
234
+ resizeTo : true,
235
+ screen : true,
236
+ scroll : true,
237
+ scrollBy : true,
238
+ scrollTo : true,
239
+ self : true,
240
+ setInterval : true,
241
+ setTimeout : true,
242
+ status : true,
243
+ top : true,
244
+ window : true,
245
+ XMLHttpRequest : true
246
+ },
247
+
248
+ escapes = {
249
+ '\b': '\\b',
250
+ '\t': '\\t',
251
+ '\n': '\\n',
252
+ '\f': '\\f',
253
+ '\r': '\\r',
254
+ '"' : '\\"',
255
+ '/' : '\\/',
256
+ '\\': '\\\\'
257
+ },
258
+
259
+ funct, // The current function
260
+ functions, // All of the functions
261
+
262
+ href = {
263
+ background : true,
264
+ content : true,
265
+ data : true,
266
+ dynsrc : true,
267
+ href : true,
268
+ lowsrc : true,
269
+ value : true,
270
+ src : true,
271
+ style : true
272
+ },
273
+
274
+ global, // The global object
275
+ globals, // The current globals
276
+ implied, // Implied globals
277
+ inblock,
278
+ indent,
279
+ jsonmode,
280
+ lines,
281
+ lookahead,
282
+ member,
283
+ membersOnly,
284
+ nexttoken,
285
+ noreach,
286
+ option,
287
+ prereg,
288
+ prevtoken,
289
+
290
+ rhino = {
291
+ defineClass : true,
292
+ deserialize : true,
293
+ gc : true,
294
+ help : true,
295
+ load : true,
296
+ loadClass : true,
297
+ print : true,
298
+ quit : true,
299
+ readFile : true,
300
+ readUrl : true,
301
+ runCommand : true,
302
+ seal : true,
303
+ serialize : true,
304
+ spawn : true,
305
+ sync : true,
306
+ toint32 : true,
307
+ version : true
308
+ },
309
+
310
+ scope, // The current scope
311
+ src,
312
+ stack,
313
+
314
+ // standard contains the global names that are provided by the
315
+ // ECMAScript standard.
316
+
317
+ standard = {
318
+ Array : true,
319
+ Boolean : true,
320
+ Date : true,
321
+ decodeURI : true,
322
+ decodeURIComponent : true,
323
+ encodeURI : true,
324
+ encodeURIComponent : true,
325
+ Error : true,
326
+ escape : true,
327
+ 'eval' : true,
328
+ EvalError : true,
329
+ Function : true,
330
+ isFinite : true,
331
+ isNaN : true,
332
+ Math : true,
333
+ Number : true,
334
+ Object : true,
335
+ parseInt : true,
336
+ parseFloat : true,
337
+ RangeError : true,
338
+ ReferenceError : true,
339
+ RegExp : true,
340
+ String : true,
341
+ SyntaxError : true,
342
+ TypeError : true,
343
+ unescape : true,
344
+ URIError : true
345
+ },
346
+
347
+ syntax = {},
348
+ token,
349
+ warnings,
350
+
351
+ // widget contains the global names which are provided to a Yahoo
352
+ // (fna Konfabulator) widget.
353
+
354
+ widget = {
355
+ alert : true,
356
+ appleScript : true,
357
+ animator : true,
358
+ appleScript : true,
359
+ beep : true,
360
+ bytesToUIString : true,
361
+ Canvas : true,
362
+ chooseColor : true,
363
+ chooseFile : true,
364
+ chooseFolder : true,
365
+ convertPathToHFS : true,
366
+ convertPathToPlatform : true,
367
+ closeWidget : true,
368
+ COM : true,
369
+ CustomAnimation : true,
370
+ escape : true,
371
+ FadeAnimation : true,
372
+ filesystem : true,
373
+ focusWidget : true,
374
+ form : true,
375
+ Frame : true,
376
+ HotKey : true,
377
+ Image : true,
378
+ include : true,
379
+ isApplicationRunning : true,
380
+ iTunes : true,
381
+ konfabulatorVersion : true,
382
+ log : true,
383
+ MenuItem : true,
384
+ MoveAnimation : true,
385
+ openURL : true,
386
+ play : true,
387
+ Point : true,
388
+ popupMenu : true,
389
+ preferenceGroups : true,
390
+ preferences : true,
391
+ print : true,
392
+ prompt : true,
393
+ random : true,
394
+ reloadWidget : true,
395
+ resolvePath : true,
396
+ resumeUpdates : true,
397
+ RotateAnimation : true,
398
+ runCommand : true,
399
+ runCommandInBg : true,
400
+ saveAs : true,
401
+ savePreferences : true,
402
+ screen : true,
403
+ ScrollBar : true,
404
+ showWidgetPreferences : true,
405
+ sleep : true,
406
+ speak : true,
407
+ suppressUpdates : true,
408
+ system : true,
409
+ tellWidget : true,
410
+ Text : true,
411
+ TextArea : true,
412
+ unescape : true,
413
+ updateNow : true,
414
+ URL : true,
415
+ widget : true,
416
+ Window : true,
417
+ XMLDOM : true,
418
+ XMLHttpRequest : true,
419
+ yahooCheckLogin : true,
420
+ yahooLogin : true,
421
+ yahooLogout : true
422
+ },
423
+
424
+ // xmode is used to adapt to the exceptions in XML parsing.
425
+ // It can have these states:
426
+ // false .js script file
427
+ // " A " attribute
428
+ // ' A ' attribute
429
+ // content The content of a script tag
430
+ // CDATA A CDATA block
431
+
432
+ xmode,
433
+
434
+ // xtype identifies the type of document being analyzed.
435
+ // It can have these states:
436
+ // false .js script file
437
+ // html .html file
438
+ // widget .kon Konfabulator file
439
+
440
+ xtype,
441
+
442
+ // unsafe comment
443
+ ax = /@cc|<\/?script|\]\]|&/i,
444
+ // unsafe character
445
+ cx = /[\u0000-\u0008\u000a-\u001f\u007f-\u009f\u2028\u2029\ufff0-\uffff]/,
446
+ // token
447
+ tx = /^\s*([(){}\[.,:;'"~]|\](\]>)?|\?>?|==?=?|\/(\*(global|extern|jslint|member|members)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%[=>]?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=%\?]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
448
+ // star slash
449
+ lx = /\*\/|\/\*/,
450
+ // identifier
451
+ ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
452
+ // javascript url
453
+ jx = /(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
454
+ // url badness
455
+ ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i;
456
+
457
+ function object(o) {
458
+ function F() {}
459
+ F.prototype = o;
460
+ return new F();
461
+ }
462
+
463
+ object_combine = function (object, o) {
464
+ var n;
465
+ for (n in o) if (o.hasOwnProperty(n)) {
466
+ object[n] = o[n];
467
+ }
468
+ };
469
+
470
+ String.prototype.entityify = function () {
471
+ return this.
472
+ replace(/&/g, '&amp;').
473
+ replace(/</g, '&lt;').
474
+ replace(/>/g, '&gt;');
475
+ };
476
+
477
+ String.prototype.isAlpha = function () {
478
+ return (this >= 'a' && this <= 'z\uffff') ||
479
+ (this >= 'A' && this <= 'Z\uffff');
480
+ };
481
+
482
+
483
+ String.prototype.isDigit = function () {
484
+ return (this >= '0' && this <= '9');
485
+ };
486
+
487
+
488
+ String.prototype.supplant = function (o) {
489
+ return this.replace(/\{([^{}]*)\}/g, function (a, b) {
490
+ var r = o[b];
491
+ return typeof r === 'string' || typeof r === 'number' ? r : a;
492
+ });
493
+ };
494
+
495
+ String.prototype.name = function () {
496
+
497
+ // If the string looks like an identifier, then we can return it as is.
498
+ // If the string contains no control characters, no quote characters, and no
499
+ // backslash characters, then we can simply slap some quotes around it.
500
+ // Otherwise we must also replace the offending characters with safe
501
+ // sequences.
502
+
503
+
504
+ if (ix.test(this)) {
505
+ return this;
506
+ }
507
+ if (/[&<"\/\\\x00-\x1f]/.test(this)) {
508
+ return '"' + this.replace(/[&<"\/\\\x00-\x1f]/g, function (a) {
509
+ var c = escapes[a];
510
+ if (c) {
511
+ return c;
512
+ }
513
+ c = a.charCodeAt();
514
+ return '\\u00' +
515
+ Math.floor(c / 16).toString(16) +
516
+ (c % 16).toString(16);
517
+ }) + '"';
518
+ }
519
+ return '"' + this + '"';
520
+ };
521
+
522
+
523
+ function populateGlobals() {
524
+ if (option.adsafe) {
525
+ object_combine(globals, {ADSAFE: true});
526
+ } else {
527
+ if (option.rhino) {
528
+ object_combine(globals, rhino);
529
+ }
530
+ if (option.browser) {
531
+ object_combine(globals, browser);
532
+ }
533
+ if (option.widget) {
534
+ object_combine(globals, widget);
535
+ }
536
+ }
537
+ }
538
+
539
+
540
+ // Produce an error warning.
541
+
542
+ function quit(m, l, ch) {
543
+ throw {
544
+ name: 'JSLintError',
545
+ line: l,
546
+ character: ch,
547
+ message: m + " (" + Math.floor((l / lines.length) * 100) +
548
+ "% scanned)."
549
+ };
550
+ }
551
+
552
+ function warning(m, t, a, b, c, d) {
553
+ var ch, l, w;
554
+ t = t || nexttoken;
555
+ if (t.id === '(end)') {
556
+ t = token;
557
+ }
558
+ l = t.line || 0;
559
+ ch = t.from || 0;
560
+ w = {
561
+ id: '(error)',
562
+ raw: m,
563
+ evidence: lines[l] || '',
564
+ line: l,
565
+ character: ch,
566
+ a: a,
567
+ b: b,
568
+ c: c,
569
+ d: d
570
+ };
571
+ w.reason = m.supplant(w);
572
+ JSLINT.errors.push(w);
573
+ if (option.passfail) {
574
+ quit('Stopping. ', l, ch);
575
+ }
576
+ warnings += 1;
577
+ if (warnings === 50) {
578
+ quit("Too many errors.", l, ch);
579
+ }
580
+ return w;
581
+ }
582
+
583
+ function warningAt(m, l, ch, a, b, c, d) {
584
+ return warning(m, {
585
+ line: l,
586
+ from: ch
587
+ }, a, b, c, d);
588
+ }
589
+
590
+ function error(m, t, a, b, c, d) {
591
+ var w = warning(m, t, a, b, c, d);
592
+ quit("Stopping, unable to continue.", w.line, w.character);
593
+ }
594
+
595
+ function errorAt(m, l, ch, a, b, c, d) {
596
+ return error(m, {
597
+ line: l,
598
+ from: ch
599
+ }, a, b, c, d);
600
+ }
601
+
602
+
603
+
604
+ // lexical analysis
605
+
606
+ var lex = function () {
607
+ var character, from, line, s;
608
+
609
+ // Private lex methods
610
+
611
+ function nextLine() {
612
+ var at;
613
+ line += 1;
614
+ if (line >= lines.length) {
615
+ return false;
616
+ }
617
+ character = 0;
618
+ s = lines[line];
619
+ at = s.search(cx);
620
+ if (at >= 0) {
621
+ warningAt("Unsafe character.", line, at);
622
+ }
623
+ return true;
624
+ }
625
+
626
+ // Produce a token object. The token inherits from a syntax symbol.
627
+
628
+ function it(type, value) {
629
+ var i, t;
630
+ if (type === '(punctuator)' ||
631
+ (type === '(identifier)' && syntax.hasOwnProperty(value))) {
632
+ t = syntax[value];
633
+
634
+ // Mozilla bug workaround.
635
+
636
+ if (!t.id) {
637
+ t = syntax[type];
638
+ }
639
+ } else {
640
+ t = syntax[type];
641
+ }
642
+ t = object(t);
643
+ if (type === '(string)') {
644
+ if (jx.test(value)) {
645
+ warningAt("Script URL.", line, from);
646
+ }
647
+ } else if (type === '(identifier)') {
648
+ if (option.nomen && value.charAt(0) === '_') {
649
+ warningAt("Unexpected '_' in '{a}'.", line, from, value);
650
+ } else if (option.adsafe &&
651
+ (adsafe[value] === true || value.slice(-2) === '__')) {
652
+ warning("ADsafe restricted word '{a}'.",
653
+ {line: line, from: character}, value);
654
+ }
655
+ }
656
+ t.value = value;
657
+ t.line = line;
658
+ t.character = character;
659
+ t.from = from;
660
+ i = t.id;
661
+ if (i !== '(endline)') {
662
+ prereg = i &&
663
+ (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
664
+ i === 'return');
665
+ }
666
+ return t;
667
+ }
668
+
669
+ // Public lex methods
670
+
671
+ return {
672
+ init: function (source) {
673
+ if (typeof source === 'string') {
674
+ lines = source.
675
+ replace(/\r\n/g, '\n').
676
+ replace(/\r/g, '\n').
677
+ split('\n');
678
+ } else {
679
+ lines = source;
680
+ }
681
+ line = -1;
682
+ nextLine();
683
+ from = 0;
684
+ },
685
+
686
+ // token -- this is called by advance to get the next token.
687
+
688
+ token: function () {
689
+ var b, c, captures, d, depth, high, i, l, low, q, t;
690
+
691
+ function match(x) {
692
+ var r = x.exec(s), r1;
693
+ if (r) {
694
+ l = r[0].length;
695
+ r1 = r[1];
696
+ c = r1.charAt(0);
697
+ s = s.substr(l);
698
+ character += l;
699
+ from = character - r1.length;
700
+ return r1;
701
+ }
702
+ }
703
+
704
+ function string(x) {
705
+ var c, j, r = '';
706
+
707
+ if (jsonmode && x !== '"') {
708
+ warningAt("Strings must use doublequote.",
709
+ line, character);
710
+ }
711
+
712
+ if (xmode === x || xmode === 'string') {
713
+ return it('(punctuator)', x);
714
+ }
715
+
716
+ function esc(n) {
717
+ var i = parseInt(s.substr(j + 1, n), 16);
718
+ j += n;
719
+ if (i >= 32 && i <= 127 &&
720
+ i !== 34 && i !== 92 && i !== 39) {
721
+ warningAt("Unnecessary escapement.", line, character);
722
+ }
723
+ character += n;
724
+ c = String.fromCharCode(i);
725
+ }
726
+ j = 0;
727
+ for (;;) {
728
+ while (j >= s.length) {
729
+ j = 0;
730
+ if (xmode !== 'xml' || !nextLine()) {
731
+ errorAt("Unclosed string.", line, from);
732
+ }
733
+ }
734
+ c = s.charAt(j);
735
+ if (c === x) {
736
+ character += 1;
737
+ s = s.substr(j + 1);
738
+ return it('(string)', r, x);
739
+ }
740
+ if (c < ' ') {
741
+ if (c === '\n' || c === '\r') {
742
+ break;
743
+ }
744
+ warningAt("Control character in string: {a}.",
745
+ line, character + j, s.slice(0, j));
746
+ } else if (c === '<') {
747
+ if (option.adsafe && xmode === 'xml') {
748
+ warningAt("ADsafe string violation.",
749
+ line, character + j);
750
+ } else if (s.charAt(j + 1) === '/' && ((xmode && xmode !== 'CDATA') || option.adsafe)) {
751
+ warningAt("Expected '<\\/' and instead saw '</'.", line, character);
752
+ }
753
+ } else if (c === '\\') {
754
+ if (option.adsafe && xmode === 'xml') {
755
+ warningAt("ADsafe string violation.",
756
+ line, character + j);
757
+ }
758
+ j += 1;
759
+ character += 1;
760
+ c = s.charAt(j);
761
+ switch (c) {
762
+ case '\\':
763
+ case '\'':
764
+ case '"':
765
+ case '/':
766
+ break;
767
+ case 'b':
768
+ c = '\b';
769
+ break;
770
+ case 'f':
771
+ c = '\f';
772
+ break;
773
+ case 'n':
774
+ c = '\n';
775
+ break;
776
+ case 'r':
777
+ c = '\r';
778
+ break;
779
+ case 't':
780
+ c = '\t';
781
+ break;
782
+ case 'u':
783
+ esc(4);
784
+ break;
785
+ case 'v':
786
+ c = '\v';
787
+ break;
788
+ case 'x':
789
+ if (jsonmode) {
790
+ warningAt("Avoid \\x-.", line, character);
791
+ }
792
+ esc(2);
793
+ break;
794
+ default:
795
+ warningAt("Bad escapement.", line, character);
796
+ }
797
+ }
798
+ r += c;
799
+ character += 1;
800
+ j += 1;
801
+ }
802
+ }
803
+
804
+ for (;;) {
805
+ if (!s) {
806
+ return it(nextLine() ? '(endline)' : '(end)', '');
807
+ }
808
+ t = match(tx);
809
+ if (!t) {
810
+ t = '';
811
+ c = '';
812
+ while (s && s < '!') {
813
+ s = s.substr(1);
814
+ }
815
+ if (s) {
816
+ errorAt("Unexpected '{a}'.",
817
+ line, character, s.substr(0, 1));
818
+ }
819
+ }
820
+
821
+ // identifier
822
+
823
+ if (c.isAlpha() || c === '_' || c === '$') {
824
+ return it('(identifier)', t);
825
+ }
826
+
827
+ // number
828
+
829
+ if (c.isDigit()) {
830
+ if (!isFinite(Number(t))) {
831
+ warningAt("Bad number '{a}'.",
832
+ line, character, t);
833
+ }
834
+ if (s.substr(0, 1).isAlpha()) {
835
+ warningAt("Missing space after '{a}'.",
836
+ line, character, t);
837
+ }
838
+ if (c === '0') {
839
+ d = t.substr(1, 1);
840
+ if (d.isDigit()) {
841
+ warningAt("Don't use extra leading zeros '{a}'.",
842
+ line, character, t);
843
+ } else if (jsonmode && (d === 'x' || d === 'X')) {
844
+ warningAt("Avoid 0x-. '{a}'.",
845
+ line, character, t);
846
+ }
847
+ }
848
+ if (t.substr(t.length - 1) === '.') {
849
+ warningAt(
850
+ "A trailing decimal point can be confused with a dot '{a}'.",
851
+ line, character, t);
852
+ }
853
+ return it('(number)', t);
854
+ }
855
+
856
+ // string
857
+
858
+ switch (t) {
859
+ case '"':
860
+ case "'":
861
+ return string(t);
862
+
863
+ // // comment
864
+
865
+ case '//':
866
+ if (src || (xmode && !(xmode === 'script' || xmode === 'CDATA'))) {
867
+ warningAt("Unexpected comment.", line, character);
868
+ }
869
+ if (option.adsafe && ax.test(s)) {
870
+ warningAt("ADsafe comment violation.", line, character);
871
+ }
872
+ s = '';
873
+ break;
874
+
875
+ // /* comment
876
+
877
+ case '/*':
878
+ if (src || (xmode && !(xmode === 'script' || xmode === 'CDATA'))) {
879
+ warningAt("Unexpected comment.", line, character);
880
+ }
881
+ if (option.adsafe && ax.test(s)) {
882
+ warningAt("ADsafe comment violation.", line, character);
883
+ }
884
+ for (;;) {
885
+ i = s.search(lx);
886
+ if (i >= 0) {
887
+ break;
888
+ }
889
+ if (!nextLine()) {
890
+ errorAt("Unclosed comment.", line, character);
891
+ } else {
892
+ if (option.adsafe && ax.test(s)) {
893
+ warningAt("ADsafe comment violation.", line, character);
894
+ }
895
+ }
896
+ }
897
+ character += i + 2;
898
+ if (s.substr(i, 1) === '/') {
899
+ errorAt("Nested comment.", line, character);
900
+ }
901
+ s = s.substr(i + 2);
902
+ break;
903
+
904
+ // /*global /*extern /*members /*jslint */
905
+
906
+ case '/*global':
907
+ case '/*extern':
908
+ case '/*members':
909
+ case '/*member':
910
+ case '/*jslint':
911
+ case '*/':
912
+ return {
913
+ value: t,
914
+ type: 'special',
915
+ line: line,
916
+ character: character,
917
+ from: from
918
+ };
919
+
920
+ case '':
921
+ break;
922
+ // /
923
+ case '/':
924
+ if (prereg) {
925
+ depth = 0;
926
+ captures = 0;
927
+ l = 0;
928
+ for (;;) {
929
+ b = true;
930
+ c = s.charAt(l);
931
+ l += 1;
932
+ switch (c) {
933
+ case '':
934
+ errorAt("Unclosed regular expression.", line, from);
935
+ return;
936
+ case '/':
937
+ if (depth > 0) {
938
+ warningAt("Unescaped '{a}'.", line, from + l, '/');
939
+ }
940
+ c = s.substr(0, l - 1);
941
+ if (s.charAt(l) === 'g') {
942
+ l += 1;
943
+ }
944
+ if (s.charAt(l) === 'i') {
945
+ l += 1;
946
+ }
947
+ if (s.charAt(l) === 'm') {
948
+ l += 1;
949
+ }
950
+ character += l;
951
+ s = s.substr(l);
952
+ return it('(regex)', c);
953
+ case '\\':
954
+ l += 1;
955
+ break;
956
+ case '(':
957
+ depth += 1;
958
+ b = false;
959
+ if (s.charAt(l) === '?') {
960
+ l += 1;
961
+ switch (s.charAt(l)) {
962
+ case ':':
963
+ case '=':
964
+ case '!':
965
+ l += 1;
966
+ break;
967
+ default:
968
+ warningAt("Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
969
+ }
970
+ } else {
971
+ captures += 1;
972
+ }
973
+ break;
974
+ case ')':
975
+ if (depth === 0) {
976
+ warningAt("Unescaped '{a}'.", line, from + l, ')');
977
+ } else {
978
+ depth -= 1;
979
+ }
980
+ break;
981
+ case ' ':
982
+ q = 1;
983
+ while (s.charAt(l) === ' ') {
984
+ l += 1;
985
+ q += 1;
986
+ }
987
+ if (q > 1) {
988
+ warningAt("Spaces are hard to count. Use {{a}}.", line, from + l, q);
989
+ }
990
+ break;
991
+ case '[':
992
+ if (s.charAt(l) === '^') {
993
+ l += 1;
994
+ }
995
+ q = false;
996
+ klass: for (;;) {
997
+ c = s.charAt(l);
998
+ l += 1;
999
+ switch (c) {
1000
+ case '[':
1001
+ case '^':
1002
+ warningAt("Unescaped '{a}'.", line, from + l, c);
1003
+ q = true;
1004
+ break;
1005
+ case '-':
1006
+ if (q) {
1007
+ q = false;
1008
+ } else {
1009
+ warningAt("Unescaped '{a}'.", line, from + l, '-');
1010
+ q = true;
1011
+ }
1012
+ break;
1013
+ case ']':
1014
+ if (!q) {
1015
+ warningAt("Unescaped '{a}'.", line, from + l - 1, '-');
1016
+ }
1017
+ break klass;
1018
+ case '\\':
1019
+ l += 1;
1020
+ q = true;
1021
+ break;
1022
+ default:
1023
+ if (c < ' ') {
1024
+ errorAt(c ? "Control character in a regular expression" :
1025
+ "Unclosed regular expression.", line, from + l);
1026
+ }
1027
+ q = true;
1028
+ }
1029
+ }
1030
+ break;
1031
+ case ']':
1032
+ case '?':
1033
+ case '{':
1034
+ case '}':
1035
+ case '+':
1036
+ case '*':
1037
+ warningAt("Unescaped '{a}'.", line, from + l, c);
1038
+ break;
1039
+ default:
1040
+ if (c < ' ') {
1041
+ warningAt("Control character in a regular expression", line, from + l);
1042
+ }
1043
+ }
1044
+ if (b) {
1045
+ switch (s.charAt(l)) {
1046
+ case '?':
1047
+ case '+':
1048
+ case '*':
1049
+ l += 1;
1050
+ if (s.charAt(l) === '?') {
1051
+ l += 1;
1052
+ }
1053
+ break;
1054
+ case '{':
1055
+ l += 1;
1056
+ c = s.charAt(l);
1057
+ if (c < '0' || c > '9') {
1058
+ warningAt("Expected a number and instead saw '{a}'.", line, from + l, c);
1059
+ }
1060
+ l += 1;
1061
+ low = +c;
1062
+ for (;;) {
1063
+ c = s.charAt(l);
1064
+ if (c < '0' || c > '9') {
1065
+ break;
1066
+ }
1067
+ l += 1;
1068
+ low = +c + (low * 10);
1069
+ }
1070
+ high = low;
1071
+ if (c === ',') {
1072
+ l += 1;
1073
+ high = Infinity;
1074
+ c = s.charAt(l);
1075
+ if (c >= '0' && c <= '9') {
1076
+ l += 1;
1077
+ high = +c;
1078
+ for (;;) {
1079
+ c = s.charAt(l);
1080
+ if (c < '0' || c > '9') {
1081
+ break;
1082
+ }
1083
+ l += 1;
1084
+ high = +c + (high * 10);
1085
+ }
1086
+ }
1087
+ }
1088
+ if (s.charAt(l) !== '}') {
1089
+ warningAt("Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
1090
+ } else {
1091
+ l += 1;
1092
+ }
1093
+ if (s.charAt(l) === '?') {
1094
+ l += 1;
1095
+ }
1096
+ if (low > high) {
1097
+ warningAt("'{a}' should not be greater than '{b}'.", line, from + l, low, high);
1098
+ }
1099
+ }
1100
+ }
1101
+ }
1102
+ c = s.substr(0, l - 1);
1103
+ character += l;
1104
+ s = s.substr(l);
1105
+ return it('(regex)', c);
1106
+ }
1107
+ return it('(punctuator)', t);
1108
+
1109
+ // punctuator
1110
+
1111
+ default:
1112
+ return it('(punctuator)', t);
1113
+ }
1114
+ }
1115
+ },
1116
+
1117
+ // skip -- skip past the next occurrence of a particular string.
1118
+ // If the argument is empty, skip to just before the next '<' character.
1119
+ // This is used to ignore HTML content. Return false if it isn't found.
1120
+
1121
+ skip: function (p) {
1122
+ var i, t = p;
1123
+ if (nexttoken.id) {
1124
+ if (!t) {
1125
+ t = '';
1126
+ if (nexttoken.id.substr(0, 1) === '<') {
1127
+ lookahead.push(nexttoken);
1128
+ return true;
1129
+ }
1130
+ } else if (nexttoken.id.indexOf(t) >= 0) {
1131
+ return true;
1132
+ }
1133
+ }
1134
+ token = nexttoken;
1135
+ nexttoken = syntax['(end)'];
1136
+ for (;;) {
1137
+ i = s.indexOf(t || '<');
1138
+ if (i >= 0) {
1139
+ character += i + t.length;
1140
+ s = s.substr(i + t.length);
1141
+ return true;
1142
+ }
1143
+ if (!nextLine()) {
1144
+ break;
1145
+ }
1146
+ }
1147
+ return false;
1148
+ }
1149
+ };
1150
+ }();
1151
+
1152
+
1153
+ function addlabel(t, type) {
1154
+
1155
+ if (t === 'hasOwnProperty') {
1156
+ error("'hasOwnProperty' is a really bad name.");
1157
+ }
1158
+ if (option.adsafe && scope === global) {
1159
+ warning('ADsafe global: ' + t + '.', token);
1160
+ }
1161
+
1162
+ // Define t in the current function in the current scope.
1163
+
1164
+ if (funct.hasOwnProperty(t)) {
1165
+ warning(funct[t] === true ?
1166
+ "'{a}' was used before it was defined." :
1167
+ "'{a}' is already defined.",
1168
+ nexttoken, t);
1169
+ }
1170
+ scope[t] = funct;
1171
+ funct[t] = type;
1172
+ if (funct['(global)'] && implied.hasOwnProperty(t)) {
1173
+ warning("'{a}' was used before it was defined.",
1174
+ nexttoken, t);
1175
+ delete implied[t];
1176
+ }
1177
+ }
1178
+
1179
+
1180
+ function doOption() {
1181
+ var b, obj, filter, o = nexttoken.value, t, v;
1182
+ switch (o) {
1183
+ case '*/':
1184
+ error("Unbegun comment.");
1185
+ break;
1186
+ case '/*global':
1187
+ case '/*extern':
1188
+ if (option.adsafe) {
1189
+ warning("ADsafe restriction.");
1190
+ }
1191
+ obj = globals;
1192
+ break;
1193
+ case '/*members':
1194
+ case '/*member':
1195
+ o = '/*members';
1196
+ if (!membersOnly) {
1197
+ membersOnly = {};
1198
+ }
1199
+ obj = membersOnly;
1200
+ break;
1201
+ case '/*jslint':
1202
+ if (option.adsafe) {
1203
+ warning("ADsafe restriction.");
1204
+ }
1205
+ obj = option;
1206
+ filter = allOptions;
1207
+ }
1208
+ for (;;) {
1209
+ t = lex.token();
1210
+ if (t.id === ',') {
1211
+ t = lex.token();
1212
+ }
1213
+ while (t.id === '(endline)') {
1214
+ t = lex.token();
1215
+ }
1216
+ if (t.type === 'special' && t.value === '*/') {
1217
+ break;
1218
+ }
1219
+ if (t.type !== '(string)' && t.type !== '(identifier)' &&
1220
+ o !== '/*members') {
1221
+ error("Bad option.", t);
1222
+ }
1223
+ if (filter) {
1224
+ if (filter[t.value] !== true) {
1225
+ error("Bad option.", t);
1226
+ }
1227
+ v = lex.token();
1228
+ if (v.id !== ':') {
1229
+ error("Expected '{a}' and instead saw '{b}'.",
1230
+ t, ':', t.value);
1231
+ }
1232
+ v = lex.token();
1233
+ if (v.value === 'true') {
1234
+ b = true;
1235
+ } else if (v.value === 'false') {
1236
+ b = false;
1237
+ } else {
1238
+ error("Expected '{a}' and instead saw '{b}'.",
1239
+ t, 'true', t.value);
1240
+ }
1241
+ } else {
1242
+ b = true;
1243
+ }
1244
+ obj[t.value] = b;
1245
+ }
1246
+ if (filter) {
1247
+ populateGlobals();
1248
+ }
1249
+ }
1250
+
1251
+
1252
+ // We need a peek function. If it has an argument, it peeks that much farther
1253
+ // ahead. It is used to distinguish
1254
+ // for ( var i in ...
1255
+ // from
1256
+ // for ( var i = ...
1257
+
1258
+ function peek(p) {
1259
+ var i = p || 0, j = 0, t;
1260
+
1261
+ while (j <= i) {
1262
+ t = lookahead[j];
1263
+ if (!t) {
1264
+ t = lookahead[j] = lex.token();
1265
+ }
1266
+ j += 1;
1267
+ }
1268
+ return t;
1269
+ }
1270
+
1271
+
1272
+ var badbreak = {
1273
+ ')': true,
1274
+ ']': true,
1275
+ '++': true,
1276
+ '--': true
1277
+ };
1278
+
1279
+ // Produce the next token. It looks for programming errors.
1280
+
1281
+ function advance(id, t) {
1282
+ var l;
1283
+ switch (token.id) {
1284
+ case '(number)':
1285
+ if (nexttoken.id === '.') {
1286
+ warning(
1287
+ "A dot following a number can be confused with a decimal point.", token);
1288
+ }
1289
+ break;
1290
+ case '-':
1291
+ if (nexttoken.id === '-' || nexttoken.id === '--') {
1292
+ warning("Confusing minusses.");
1293
+ }
1294
+ break;
1295
+ case '+':
1296
+ if (nexttoken.id === '+' || nexttoken.id === '++') {
1297
+ warning("Confusing plusses.");
1298
+ }
1299
+ break;
1300
+ }
1301
+ if (token.type === '(string)' || token.identifier) {
1302
+ anonname = token.value;
1303
+ }
1304
+
1305
+ if (id && nexttoken.id !== id) {
1306
+ if (t) {
1307
+ if (nexttoken.id === '(end)') {
1308
+ warning("Unmatched '{a}'.", t, t.id);
1309
+ } else {
1310
+ warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
1311
+ nexttoken, id, t.id, t.line + 1, nexttoken.value);
1312
+ }
1313
+ } else {
1314
+ warning("Expected '{a}' and instead saw '{b}'.",
1315
+ nexttoken, id, nexttoken.value);
1316
+ }
1317
+ }
1318
+ prevtoken = token;
1319
+ token = nexttoken;
1320
+ for (;;) {
1321
+ nexttoken = lookahead.shift() || lex.token();
1322
+ if (nexttoken.type === 'special') {
1323
+ doOption();
1324
+ } else {
1325
+ if (nexttoken.id === '<![') {
1326
+ if (option.adsafe) {
1327
+ error("ADsafe violation.", nexttoken);
1328
+ }
1329
+ if (xtype === 'html') {
1330
+ error("Unexpected '{a}'.", nexttoken, '<![');
1331
+ }
1332
+ if (xmode === 'script') {
1333
+ nexttoken = lex.token();
1334
+ if (nexttoken.value !== 'CDATA') {
1335
+ error("Missing '{a}'.", nexttoken, 'CDATA');
1336
+ }
1337
+ nexttoken = lex.token();
1338
+ if (nexttoken.id !== '[') {
1339
+ error("Missing '{a}'.", nexttoken, '[');
1340
+ }
1341
+ xmode = 'CDATA';
1342
+ } else if (xmode === 'xml') {
1343
+ lex.skip(']]>');
1344
+ } else {
1345
+ error("Unexpected '{a}'.", nexttoken, '<![');
1346
+ }
1347
+ } else if (nexttoken.id === ']]>') {
1348
+ if (xmode === 'CDATA') {
1349
+ xmode = 'script';
1350
+ } else {
1351
+ error("Unexpected '{a}'.", nexttoken, ']]>');
1352
+ }
1353
+ } else if (nexttoken.id !== '(endline)') {
1354
+ break;
1355
+ }
1356
+ if (xmode === '"' || xmode === "'") {
1357
+ error("Missing '{a}'.", token, xmode);
1358
+ }
1359
+ l = !xmode && !option.laxbreak &&
1360
+ (token.type === '(string)' || token.type === '(number)' ||
1361
+ token.type === '(identifier)' || badbreak[token.id]);
1362
+ }
1363
+ }
1364
+ if (l) {
1365
+ switch (nexttoken.id) {
1366
+ case '{':
1367
+ case '}':
1368
+ case ']':
1369
+ break;
1370
+ case ')':
1371
+ switch (token.id) {
1372
+ case ')':
1373
+ case '}':
1374
+ case ']':
1375
+ break;
1376
+ default:
1377
+ warning("Line breaking error '{a}'.", token, ')');
1378
+ }
1379
+ break;
1380
+ default:
1381
+ warning("Line breaking error '{a}'.",
1382
+ token, token.value);
1383
+ }
1384
+ }
1385
+ if (xtype === 'widget' && xmode === 'script' && nexttoken.id) {
1386
+ l = nexttoken.id.charAt(0);
1387
+ if (l === '<' || l === '&') {
1388
+ nexttoken.nud = nexttoken.led = null;
1389
+ nexttoken.lbp = 0;
1390
+ nexttoken.reach = true;
1391
+ }
1392
+ }
1393
+ }
1394
+
1395
+
1396
+ // This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
1397
+ // is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is
1398
+ // like nud except that it is only used on the first token of a statement.
1399
+ // Having .fud makes it much easier to define JavaScript. I retained Pratt's
1400
+ // nomenclature.
1401
+
1402
+ // .nud Null denotation
1403
+ // .fud First null denotation
1404
+ // .led Left denotation
1405
+ // lbp Left binding power
1406
+ // rbp Right binding power
1407
+
1408
+ // They are key to the parsing method called Top Down Operator Precedence.
1409
+
1410
+ function parse(rbp, initial) {
1411
+ var left;
1412
+ var o;
1413
+ if (nexttoken.id === '(end)') {
1414
+ error("Unexpected early end of program.", token);
1415
+ }
1416
+ advance();
1417
+ if (option.adsafe && token.value === 'ADSAFE') {
1418
+ if (nexttoken.id !== '.' || !(peek(0).identifier) ||
1419
+ peek(1).id !== '(') {
1420
+ warning('ADsafe violation.', token);
1421
+ }
1422
+ }
1423
+ if (initial) {
1424
+ anonname = 'anonymous';
1425
+ funct['(verb)'] = token.value;
1426
+ }
1427
+ if (initial && token.fud) {
1428
+ left = token.fud();
1429
+ } else {
1430
+ if (token.nud) {
1431
+ o = token.exps;
1432
+ left = token.nud();
1433
+ } else {
1434
+ if (nexttoken.type === '(number)' && token.id === '.') {
1435
+ warning(
1436
+ "A leading decimal point can be confused with a dot: '.{a}'.",
1437
+ token, nexttoken.value);
1438
+ advance();
1439
+ return token;
1440
+ } else {
1441
+ error("Expected an identifier and instead saw '{a}'.",
1442
+ token, token.id);
1443
+ }
1444
+ }
1445
+ while (rbp < nexttoken.lbp) {
1446
+ o = nexttoken.exps;
1447
+ advance();
1448
+ if (token.led) {
1449
+ left = token.led(left);
1450
+ } else {
1451
+ error("Expected an operator and instead saw '{a}'.",
1452
+ token, token.id);
1453
+ }
1454
+ }
1455
+ if (initial && !o) {
1456
+ warning(
1457
+ "Expected an assignment or function call and instead saw an expression.",
1458
+ token);
1459
+ }
1460
+ }
1461
+ if (!option.evil && left && left.value === 'eval') {
1462
+ warning("eval is evil.", left);
1463
+ }
1464
+ return left;
1465
+ }
1466
+
1467
+
1468
+ // Functions for conformance of style.
1469
+
1470
+ function adjacent(left, right) {
1471
+ left = left || token;
1472
+ right = right || nexttoken;
1473
+ if (option.white) {
1474
+ if (left.character !== right.from) {
1475
+ warning("Unexpected space after '{a}'.",
1476
+ nexttoken, left.value);
1477
+ }
1478
+ }
1479
+ }
1480
+
1481
+
1482
+ function nospace(left, right) {
1483
+ left = left || token;
1484
+ right = right || nexttoken;
1485
+ if (option.white) {
1486
+ if (left.line === right.line) {
1487
+ adjacent(left, right);
1488
+ }
1489
+ }
1490
+ }
1491
+
1492
+
1493
+ function nonadjacent(left, right) {
1494
+ left = left || token;
1495
+ right = right || nexttoken;
1496
+ if (option.white) {
1497
+ if (left.character === right.from) {
1498
+ warning("Missing space after '{a}'.",
1499
+ nexttoken, left.value);
1500
+ }
1501
+ }
1502
+ }
1503
+
1504
+ function indentation(bias) {
1505
+ var i;
1506
+ if (option.white && nexttoken.id !== '(end)') {
1507
+ i = indent + (bias || 0);
1508
+ if (nexttoken.from !== i) {
1509
+ warning("Expected '{a}' to have an indentation of {b} instead of {c}.",
1510
+ nexttoken, nexttoken.value, i, nexttoken.from);
1511
+ }
1512
+ }
1513
+ }
1514
+
1515
+ function nolinebreak(t) {
1516
+ if (t.line !== nexttoken.line) {
1517
+ warning("Line breaking error '{a}'.", t, t.id);
1518
+ }
1519
+ }
1520
+
1521
+
1522
+ // Parasitic constructors for making the symbols that will be inherited by
1523
+ // tokens.
1524
+
1525
+ function symbol(s, p) {
1526
+ var x = syntax[s];
1527
+ if (!x || typeof x !== 'object') {
1528
+ syntax[s] = x = {
1529
+ id: s,
1530
+ lbp: p,
1531
+ value: s
1532
+ };
1533
+ }
1534
+ return x;
1535
+ }
1536
+
1537
+
1538
+ function delim(s) {
1539
+ return symbol(s, 0);
1540
+ }
1541
+
1542
+
1543
+ function stmt(s, f) {
1544
+ var x = delim(s);
1545
+ x.identifier = x.reserved = true;
1546
+ x.fud = f;
1547
+ return x;
1548
+ }
1549
+
1550
+
1551
+ function blockstmt(s, f) {
1552
+ var x = stmt(s, f);
1553
+ x.block = true;
1554
+ return x;
1555
+ }
1556
+
1557
+
1558
+ function reserveName(x) {
1559
+ var c = x.id.charAt(0);
1560
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
1561
+ x.identifier = x.reserved = true;
1562
+ }
1563
+ return x;
1564
+ }
1565
+
1566
+
1567
+ function prefix(s, f) {
1568
+ var x = symbol(s, 150);
1569
+ reserveName(x);
1570
+ x.nud = (typeof f === 'function') ? f : function () {
1571
+ if (option.plusplus && (this.id === '++' || this.id === '--')) {
1572
+ warning("Unexpected use of '{a}'.", this, this.id);
1573
+ }
1574
+ parse(150);
1575
+ return this;
1576
+ };
1577
+ return x;
1578
+ }
1579
+
1580
+
1581
+ function type(s, f) {
1582
+ var x = delim(s);
1583
+ x.type = s;
1584
+ x.nud = f;
1585
+ return x;
1586
+ }
1587
+
1588
+
1589
+ function reserve(s, f) {
1590
+ var x = type(s, f);
1591
+ x.identifier = x.reserved = true;
1592
+ return x;
1593
+ }
1594
+
1595
+
1596
+ function reservevar(s) {
1597
+ return reserve(s, function () {
1598
+ return this;
1599
+ });
1600
+ }
1601
+
1602
+
1603
+ function infix(s, f, p) {
1604
+ var x = symbol(s, p);
1605
+ reserveName(x);
1606
+ x.led = (typeof f === 'function') ? f : function (left) {
1607
+ nonadjacent(prevtoken, token);
1608
+ nonadjacent(token, nexttoken);
1609
+ return [this.id, left, parse(p)];
1610
+ };
1611
+ return x;
1612
+ }
1613
+
1614
+
1615
+ function relation(s, f) {
1616
+ var x = symbol(s, 100);
1617
+ x.led = function (left) {
1618
+ nonadjacent(prevtoken, token);
1619
+ nonadjacent(token, nexttoken);
1620
+ var right = parse(100);
1621
+ if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) {
1622
+ warning("Use the isNaN function to compare with NaN.", this);
1623
+ } else if (f) {
1624
+ f.apply(this, [left, right]);
1625
+ }
1626
+ return [this.id, left, right];
1627
+ };
1628
+ return x;
1629
+ }
1630
+
1631
+
1632
+ function isPoorRelation(node) {
1633
+ return (node.type === '(number)' && !+node.value) ||
1634
+ (node.type === '(string)' && !node.value) ||
1635
+ node.type === 'true' ||
1636
+ node.type === 'false' ||
1637
+ node.type === 'undefined' ||
1638
+ node.type === 'null';
1639
+ }
1640
+
1641
+
1642
+ function assignop(s, f) {
1643
+ symbol(s, 20).exps = true;
1644
+ return infix(s, function (left) {
1645
+ var l;
1646
+ nonadjacent(prevtoken, token);
1647
+ nonadjacent(token, nexttoken);
1648
+ if (adsafe) {
1649
+ l = left;
1650
+ do {
1651
+ if (l.value === 'ADSAFE') {
1652
+ warning('ADsafe violation.', l);
1653
+ }
1654
+ l = l.left;
1655
+ } while (l);
1656
+ }
1657
+ if (left) {
1658
+ if (left.id === '.' || left.id === '[' ||
1659
+ (left.identifier && !left.reserved)) {
1660
+ parse(19);
1661
+ return left;
1662
+ }
1663
+ if (left === syntax['function']) {
1664
+ warning(
1665
+ "Expected an identifier in an assignment and instead saw a function invocation.",
1666
+ token);
1667
+ }
1668
+ }
1669
+ error("Bad assignment.", this);
1670
+ }, 20);
1671
+ }
1672
+
1673
+ function bitwise(s, f, p) {
1674
+ var x = symbol(s, p);
1675
+ reserveName(x);
1676
+ x.led = (typeof f === 'function') ? f : function (left) {
1677
+ if (option.bitwise) {
1678
+ warning("Unexpected use of '{a}'.", this, this.id);
1679
+ }
1680
+ nonadjacent(prevtoken, token);
1681
+ nonadjacent(token, nexttoken);
1682
+ return [this.id, left, parse(p)];
1683
+ };
1684
+ return x;
1685
+ }
1686
+
1687
+ function bitwiseassignop(s) {
1688
+ symbol(s, 20).exps = true;
1689
+ return infix(s, function (left) {
1690
+ if (option.bitwise) {
1691
+ warning("Unexpected use of '{a}'.", this, this.id);
1692
+ }
1693
+ nonadjacent(prevtoken, token);
1694
+ nonadjacent(token, nexttoken);
1695
+ if (left) {
1696
+ if (left.id === '.' || left.id === '[' ||
1697
+ (left.identifier && !left.reserved)) {
1698
+ parse(19);
1699
+ return left;
1700
+ }
1701
+ if (left === syntax['function']) {
1702
+ warning(
1703
+ "Expected an identifier in an assignment, and instead saw a function invocation.",
1704
+ token);
1705
+ }
1706
+ }
1707
+ error("Bad assignment.", this);
1708
+ }, 20);
1709
+ }
1710
+
1711
+
1712
+ function suffix(s, f) {
1713
+ var x = symbol(s, 150);
1714
+ x.led = function (left) {
1715
+ if (option.plusplus) {
1716
+ warning("Unexpected use of '{a}'.", this, this.id);
1717
+ }
1718
+ return [f, left];
1719
+ };
1720
+ return x;
1721
+ }
1722
+
1723
+
1724
+ function optionalidentifier() {
1725
+ if (nexttoken.reserved) {
1726
+ warning("Expected an identifier and instead saw '{a}' (a reserved word).",
1727
+ nexttoken, nexttoken.id);
1728
+ }
1729
+ if (nexttoken.identifier) {
1730
+ advance();
1731
+ return token.value;
1732
+ }
1733
+ }
1734
+
1735
+
1736
+ function identifier() {
1737
+ var i = optionalidentifier();
1738
+ if (i) {
1739
+ return i;
1740
+ }
1741
+ if (token.id === 'function' && nexttoken.id === '(') {
1742
+ warning("Missing name in function statement.");
1743
+ } else {
1744
+ error("Expected an identifier and instead saw '{a}'.",
1745
+ nexttoken, nexttoken.value);
1746
+ }
1747
+ }
1748
+
1749
+ function reachable(s) {
1750
+ var i = 0, t;
1751
+ if (nexttoken.id !== ';' || noreach) {
1752
+ return;
1753
+ }
1754
+ for (;;) {
1755
+ t = peek(i);
1756
+ if (t.reach) {
1757
+ return;
1758
+ }
1759
+ if (t.id !== '(endline)') {
1760
+ if (t.id === 'function') {
1761
+ warning(
1762
+ "Inner functions should be listed at the top of the outer function.", t);
1763
+ break;
1764
+ }
1765
+ warning("Unreachable '{a}' after '{b}'.", t, t.value, s);
1766
+ break;
1767
+ }
1768
+ i += 1;
1769
+ }
1770
+ }
1771
+
1772
+
1773
+ function statement(noindent) {
1774
+ var i = indent, r, s = scope, t = nexttoken;
1775
+
1776
+ // We don't like the empty statement.
1777
+
1778
+ if (t.id === ';') {
1779
+ warning("Unnecessary semicolon.", t);
1780
+ advance(';');
1781
+ return;
1782
+ }
1783
+
1784
+ // Is this a labelled statement?
1785
+
1786
+ if (t.identifier && !t.reserved && peek().id === ':') {
1787
+ advance();
1788
+ advance(':');
1789
+ scope = object(s);
1790
+ addlabel(t.value, 'label');
1791
+ if (!nexttoken.labelled) {
1792
+ warning("Label '{a}' on {b} statement.",
1793
+ nexttoken, t.value, nexttoken.value);
1794
+ }
1795
+ if (jx.test(t.value + ':')) {
1796
+ warning("Label '{a}' looks like a javascript url.",
1797
+ t, t.value);
1798
+ }
1799
+ nexttoken.label = t.value;
1800
+ t = nexttoken;
1801
+ }
1802
+
1803
+ // Parse the statement.
1804
+
1805
+ if (!noindent) {
1806
+ indentation();
1807
+ }
1808
+ r = parse(0, true);
1809
+
1810
+ // Look for the final semicolon.
1811
+
1812
+ if (!t.block) {
1813
+ if (nexttoken.id !== ';') {
1814
+ warningAt("Missing semicolon.", token.line,
1815
+ token.from + token.value.length);
1816
+ } else {
1817
+ adjacent(token, nexttoken);
1818
+ advance(';');
1819
+ nonadjacent(token, nexttoken);
1820
+ }
1821
+ }
1822
+
1823
+ // Restore the indentation.
1824
+
1825
+ indent = i;
1826
+ scope = s;
1827
+ return r;
1828
+ }
1829
+
1830
+
1831
+ function statements() {
1832
+ var a = [];
1833
+ while (!nexttoken.reach && nexttoken.id !== '(end)') {
1834
+ if (nexttoken.id === ';') {
1835
+ warning("Unnecessary semicolon.");
1836
+ advance(';');
1837
+ } else {
1838
+ a.push(statement());
1839
+ }
1840
+ }
1841
+ return a;
1842
+ }
1843
+
1844
+
1845
+ function block(f) {
1846
+ var a, b = inblock, s = scope;
1847
+ inblock = f;
1848
+ if (f) {
1849
+ scope = object(scope);
1850
+ }
1851
+ nonadjacent(token, nexttoken);
1852
+ var t = nexttoken;
1853
+ if (nexttoken.id === '{') {
1854
+ advance('{');
1855
+ if (nexttoken.id !== '}' || token.line !== nexttoken.line) {
1856
+ indent += 4;
1857
+ if (!f && nexttoken.from === indent + 4) {
1858
+ indent += 4;
1859
+ }
1860
+ a = statements();
1861
+ indent -= 4;
1862
+ indentation();
1863
+ }
1864
+ advance('}', t);
1865
+ } else {
1866
+ warning("Expected '{a}' and instead saw '{b}'.",
1867
+ nexttoken, '{', nexttoken.value);
1868
+ noreach = true;
1869
+ a = [statement()];
1870
+ noreach = false;
1871
+ }
1872
+ funct['(verb)'] = null;
1873
+ scope = s;
1874
+ inblock = b;
1875
+ return a;
1876
+ }
1877
+
1878
+
1879
+ // An identity function, used by string and number tokens.
1880
+
1881
+ function idValue() {
1882
+ return this;
1883
+ }
1884
+
1885
+
1886
+ function countMember(m) {
1887
+ if (membersOnly && membersOnly[m] !== true) {
1888
+ warning("Unexpected /*member '{a}'.", nexttoken, m);
1889
+ }
1890
+ if (typeof member[m] === 'number') {
1891
+ member[m] += 1;
1892
+ } else {
1893
+ member[m] = 1;
1894
+ }
1895
+ }
1896
+
1897
+ function note_implied(token) {
1898
+ var name = token.value, line = token.line + 1, a = implied[name];
1899
+ if (!a) {
1900
+ a = [line];
1901
+ implied[name] = a;
1902
+ } else if (a[a.length - 1] !== line) {
1903
+ a.push(line);
1904
+ }
1905
+ }
1906
+
1907
+
1908
+ // XML types. Currently we support html and widget.
1909
+
1910
+ var xmltype = {
1911
+ html: {
1912
+ doBegin: function (n) {
1913
+ xtype = 'html';
1914
+ option.browser = true;
1915
+ populateGlobals();
1916
+ },
1917
+ doTagName: function (n, p) {
1918
+ var i, t = xmltype.html.tag[n], x;
1919
+ src = false;
1920
+ if (!t) {
1921
+ error("Unrecognized tag '<{a}>'.",
1922
+ nexttoken,
1923
+ n === n.toLowerCase() ? n :
1924
+ n + ' (capitalization error)');
1925
+ }
1926
+ x = t.parent;
1927
+ if (!option.fragment || stack.length !== 1 || !stack[0].fragment) {
1928
+ if (x) {
1929
+ if (x.indexOf(' ' + p + ' ') < 0) {
1930
+ error("A '<{a}>' must be within '<{b}>'.",
1931
+ token, n, x);
1932
+ }
1933
+ } else {
1934
+ i = stack.length;
1935
+ do {
1936
+ if (i <= 0) {
1937
+ error("A '<{a}>' must be within '<{b}>'.",
1938
+ token, n, 'body');
1939
+ }
1940
+ i -= 1;
1941
+ } while (stack[i].name !== 'body');
1942
+ }
1943
+ }
1944
+ return t.empty;
1945
+ },
1946
+ doAttribute: function (n, a) {
1947
+ if (!a) {
1948
+ warning("Missing attribute name.", token);
1949
+ }
1950
+ a = a.toLowerCase();
1951
+ if (n === 'script') {
1952
+ if (a === 'src') {
1953
+ src = true;
1954
+ return 'href';
1955
+ } else if (a === 'language') {
1956
+ warning("The 'language' attribute is deprecated.",
1957
+ token);
1958
+ return false;
1959
+ }
1960
+ } else if (n === 'style') {
1961
+ if (a === 'type' && option.adsafe) {
1962
+ warning("Don't bother with 'type'.", token);
1963
+ }
1964
+ }
1965
+ if (href[a] === true) {
1966
+ return 'href';
1967
+ }
1968
+ if (a.slice(0, 2) === 'on') {
1969
+ if (!option.on) {
1970
+ warning("Avoid HTML event handlers.");
1971
+ }
1972
+ return 'script';
1973
+ } else {
1974
+ return 'value';
1975
+ }
1976
+ },
1977
+ doIt: function (n) {
1978
+ return n === 'script' ? 'script' : n !== 'html' &&
1979
+ xmltype.html.tag[n].special && 'special';
1980
+ },
1981
+ tag: {
1982
+ a: {},
1983
+ abbr: {},
1984
+ acronym: {},
1985
+ address: {},
1986
+ applet: {},
1987
+ area: {empty: true, parent: ' map '},
1988
+ b: {},
1989
+ base: {empty: true, parent: ' head '},
1990
+ bdo: {},
1991
+ big: {},
1992
+ blockquote: {},
1993
+ body: {parent: ' html noframes '},
1994
+ br: {empty: true},
1995
+ button: {},
1996
+ canvas: {parent: ' body p div th td '},
1997
+ caption: {parent: ' table '},
1998
+ center: {},
1999
+ cite: {},
2000
+ code: {},
2001
+ col: {empty: true, parent: ' table colgroup '},
2002
+ colgroup: {parent: ' table '},
2003
+ dd: {parent: ' dl '},
2004
+ del: {},
2005
+ dfn: {},
2006
+ dir: {},
2007
+ div: {},
2008
+ dl: {},
2009
+ dt: {parent: ' dl '},
2010
+ em: {},
2011
+ embed: {},
2012
+ fieldset: {},
2013
+ font: {},
2014
+ form: {},
2015
+ frame: {empty: true, parent: ' frameset '},
2016
+ frameset: {parent: ' html frameset '},
2017
+ h1: {},
2018
+ h2: {},
2019
+ h3: {},
2020
+ h4: {},
2021
+ h5: {},
2022
+ h6: {},
2023
+ head: {parent: ' html '},
2024
+ html: {},
2025
+ hr: {empty: true},
2026
+ i: {},
2027
+ iframe: {},
2028
+ img: {empty: true},
2029
+ input: {empty: true},
2030
+ ins: {},
2031
+ kbd: {},
2032
+ label: {},
2033
+ legend: {parent: ' fieldset '},
2034
+ li: {parent: ' dir menu ol ul '},
2035
+ link: {empty: true, parent: ' head '},
2036
+ map: {},
2037
+ menu: {},
2038
+ meta: {empty: true, parent: ' head noframes noscript '},
2039
+ noframes: {parent: ' html body '},
2040
+ noscript: {parent: ' head html noframes '},
2041
+ object: {},
2042
+ ol: {},
2043
+ optgroup: {parent: ' select '},
2044
+ option: {parent: ' optgroup select '},
2045
+ p: {},
2046
+ param: {empty: true, parent: ' applet object '},
2047
+ pre: {},
2048
+ q: {},
2049
+ samp: {},
2050
+ script: {parent: ' body div frame head iframe p pre span '},
2051
+ select: {},
2052
+ small: {},
2053
+ span: {},
2054
+ strong: {},
2055
+ style: {parent: ' head ', special: true},
2056
+ sub: {},
2057
+ sup: {},
2058
+ table: {},
2059
+ tbody: {parent: ' table '},
2060
+ td: {parent: ' tr '},
2061
+ textarea: {},
2062
+ tfoot: {parent: ' table '},
2063
+ th: {parent: ' tr '},
2064
+ thead: {parent: ' table '},
2065
+ title: {parent: ' head '},
2066
+ tr: {parent: ' table tbody thead tfoot '},
2067
+ tt: {},
2068
+ u: {},
2069
+ ul: {},
2070
+ 'var': {}
2071
+ }
2072
+ },
2073
+ widget: {
2074
+ doBegin: function (n) {
2075
+ xtype = 'widget';
2076
+ option.widget = true;
2077
+ option.cap = true;
2078
+ populateGlobals();
2079
+ },
2080
+ doTagName: function (n, p) {
2081
+ var t = xmltype.widget.tag[n];
2082
+ if (!t) {
2083
+ error("Unrecognized tag '<{a}>'.", nexttoken, n);
2084
+ }
2085
+ var x = t.parent;
2086
+ if (x.indexOf(' ' + p + ' ') < 0) {
2087
+ error("A '<{a}>' must be within '<{b}>'.",
2088
+ token, n, x);
2089
+ }
2090
+ },
2091
+ doAttribute: function (n, a) {
2092
+ var t = xmltype.widget.tag[a];
2093
+ if (!t) {
2094
+ error("Unrecognized attribute '<{a} {b}>'.", nexttoken, n, a);
2095
+ }
2096
+ var x = t.parent;
2097
+ if (x.indexOf(' ' + n + ' ') < 0) {
2098
+ error("Attribute '{a}' does not belong in '<{b}>'.", nexttoken, a, n);
2099
+ }
2100
+ return t.script ?
2101
+ 'script' :
2102
+ a === 'name' && n !== 'setting' ?
2103
+ 'define' : 'string';
2104
+ },
2105
+ doIt: function (n) {
2106
+ var x = xmltype.widget.tag[n];
2107
+ return x && x.script && 'script';
2108
+ },
2109
+ tag: {
2110
+ "about-box": {parent: ' widget '},
2111
+ "about-image": {parent: ' about-box '},
2112
+ "about-text": {parent: ' about-box '},
2113
+ "about-version": {parent: ' about-box '},
2114
+ action: {parent: ' widget ', script: true},
2115
+ alignment: {parent: ' canvas frame image scrollbar text textarea window '},
2116
+ anchorstyle: {parent: ' text '},
2117
+ author: {parent: ' widget '},
2118
+ autohide: {parent: ' scrollbar '},
2119
+ beget: {parent: ' canvas frame image scrollbar text window '},
2120
+ bgcolor: {parent: ' text textarea '},
2121
+ bgcolour: {parent: ' text textarea '},
2122
+ bgopacity: {parent: ' text textarea '},
2123
+ canvas: {parent: ' frame window '},
2124
+ charset: {parent: ' script '},
2125
+ checked: {parent: ' image menuitem '},
2126
+ cliprect: {parent: ' image '},
2127
+ color: {parent: ' about-text about-version shadow text textarea '},
2128
+ colorize: {parent: ' image '},
2129
+ colour: {parent: ' about-text about-version shadow text textarea '},
2130
+ columns: {parent: ' textarea '},
2131
+ company: {parent: ' widget '},
2132
+ contextmenuitems: {parent: ' canvas frame image scrollbar text textarea window '},
2133
+ copyright: {parent: ' widget '},
2134
+ data: {parent: ' about-text about-version text textarea '},
2135
+ debug: {parent: ' widget '},
2136
+ defaultvalue: {parent: ' preference '},
2137
+ defaulttracking: {parent: ' widget '},
2138
+ description: {parent: ' preference '},
2139
+ directory: {parent: ' preference '},
2140
+ editable: {parent: ' textarea '},
2141
+ enabled: {parent: ' menuitem '},
2142
+ extension: {parent: ' preference '},
2143
+ file: {parent: ' action preference '},
2144
+ fillmode: {parent: ' image '},
2145
+ font: {parent: ' about-text about-version text textarea '},
2146
+ fontstyle: {parent: ' textarea '},
2147
+ frame: {parent: ' frame window '},
2148
+ group: {parent: ' preference '},
2149
+ halign: {parent: ' canvas frame image scrollbar text textarea '},
2150
+ handlelinks: {parent: ' textarea '},
2151
+ height: {parent: ' canvas frame image scrollbar text textarea window '},
2152
+ hidden: {parent: ' preference '},
2153
+ hlinesize: {parent: ' frame '},
2154
+ hoffset: {parent: ' about-text about-version canvas frame image scrollbar shadow text textarea window '},
2155
+ hotkey: {parent: ' widget '},
2156
+ hregistrationpoint: {parent: ' canvas frame image scrollbar text '},
2157
+ hscrollbar: {parent: ' frame '},
2158
+ hsladjustment: {parent: ' image '},
2159
+ hsltinting: {parent: ' image '},
2160
+ icon: {parent: ' preferencegroup '},
2161
+ id: {parent: ' canvas frame hotkey image preference text textarea timer scrollbar widget window '},
2162
+ image: {parent: ' about-box frame window widget '},
2163
+ interval: {parent: ' action timer '},
2164
+ key: {parent: ' hotkey '},
2165
+ kind: {parent: ' preference '},
2166
+ level: {parent: ' window '},
2167
+ lines: {parent: ' textarea '},
2168
+ loadingsrc: {parent: ' image '},
2169
+ locked: {parent: ' window '},
2170
+ max: {parent: ' scrollbar '},
2171
+ maxlength: {parent: ' preference '},
2172
+ menuitem: {parent: ' contextmenuitems '},
2173
+ min: {parent: ' scrollbar '},
2174
+ minimumversion: {parent: ' widget '},
2175
+ minlength: {parent: ' preference '},
2176
+ missingsrc: {parent: ' image '},
2177
+ modifier: {parent: ' hotkey '},
2178
+ name: {parent: ' canvas frame hotkey image preference preferencegroup scrollbar setting text textarea timer widget window '},
2179
+ notsaved: {parent: ' preference '},
2180
+ onclick: {parent: ' canvas frame image scrollbar text textarea ', script: true},
2181
+ oncontextmenu: {parent: ' canvas frame image scrollbar text textarea window ', script: true},
2182
+ ondragdrop: {parent: ' canvas frame image scrollbar text textarea ', script: true},
2183
+ ondragenter: {parent: ' canvas frame image scrollbar text textarea ', script: true},
2184
+ ondragexit: {parent: ' canvas frame image scrollbar text textarea ', script: true},
2185
+ onfirstdisplay: {parent: ' window ', script: true},
2186
+ ongainfocus: {parent: ' textarea window ', script: true},
2187
+ onkeydown: {parent: ' hotkey text textarea window ', script: true},
2188
+ onkeypress: {parent: ' textarea window ', script: true},
2189
+ onkeyup: {parent: ' hotkey text textarea window ', script: true},
2190
+ onimageloaded: {parent: ' image ', script: true},
2191
+ onlosefocus: {parent: ' textarea window ', script: true},
2192
+ onmousedown: {parent: ' canvas frame image scrollbar text textarea window ', script: true},
2193
+ onmousedrag: {parent: ' canvas frame image scrollbar text textarea window ', script: true},
2194
+ onmouseenter: {parent: ' canvas frame image scrollbar text textarea window ', script: true},
2195
+ onmouseexit: {parent: ' canvas frame image scrollbar text textarea window ', script: true},
2196
+ onmousemove: {parent: ' canvas frame image scrollbar text textarea window ', script: true},
2197
+ onmouseup: {parent: ' canvas frame image scrollbar text textarea window ', script: true},
2198
+ onmousewheel: {parent: ' frame ', script: true},
2199
+ onmulticlick: {parent: ' canvas frame image scrollbar text textarea window ', script: true},
2200
+ onselect: {parent: ' menuitem ', script: true},
2201
+ ontextinput: {parent: ' window ', script: true},
2202
+ ontimerfired: {parent: ' timer ', script: true},
2203
+ onvaluechanged: {parent: ' scrollbar ', script: true},
2204
+ opacity: {parent: ' canvas frame image scrollbar shadow text textarea window '},
2205
+ option: {parent: ' preference widget '},
2206
+ optionvalue: {parent: ' preference '},
2207
+ order: {parent: ' preferencegroup '},
2208
+ orientation: {parent: ' scrollbar '},
2209
+ pagesize: {parent: ' scrollbar '},
2210
+ preference: {parent: ' widget '},
2211
+ preferencegroup: {parent: ' widget '},
2212
+ remoteasync: {parent: ' image '},
2213
+ requiredplatform: {parent: ' widget '},
2214
+ root: {parent: ' window '},
2215
+ rotation: {parent: ' canvas frame image scrollbar text '},
2216
+ script: {parent: ' widget ', script: true},
2217
+ scrollbar: {parent: ' frame text textarea window '},
2218
+ scrolling: {parent: ' text '},
2219
+ scrollx: {parent: ' frame '},
2220
+ scrolly: {parent: ' frame '},
2221
+ secure: {parent: ' preference textarea '},
2222
+ setting: {parent: ' settings '},
2223
+ settings: {parent: ' widget '},
2224
+ shadow: {parent: ' about-text about-version text window '},
2225
+ size: {parent: ' about-text about-version text textarea '},
2226
+ spellcheck: {parent: ' textarea '},
2227
+ src: {parent: ' image script '},
2228
+ srcheight: {parent: ' image '},
2229
+ srcwidth: {parent: ' image '},
2230
+ style: {parent: ' about-text about-version canvas frame image preference scrollbar text textarea window '},
2231
+ subviews: {parent: ' frame '},
2232
+ superview: {parent: ' canvas frame image scrollbar text textarea '},
2233
+ text: {parent: ' frame text textarea window '},
2234
+ textarea: {parent: ' frame window '},
2235
+ timer: {parent: ' widget '},
2236
+ thumbcolor: {parent: ' scrollbar textarea '},
2237
+ ticking: {parent: ' timer '},
2238
+ ticks: {parent: ' preference '},
2239
+ ticklabel: {parent: ' preference '},
2240
+ tileorigin: {parent: ' image '},
2241
+ title: {parent: ' menuitem preference preferencegroup window '},
2242
+ tooltip: {parent: ' frame image text textarea '},
2243
+ tracking: {parent: ' canvas image '},
2244
+ trigger: {parent: ' action '},
2245
+ truncation: {parent: ' text '},
2246
+ type: {parent: ' preference '},
2247
+ url: {parent: ' about-box about-text about-version '},
2248
+ usefileicon: {parent: ' image '},
2249
+ valign: {parent: ' canvas frame image scrollbar text textarea '},
2250
+ value: {parent: ' preference scrollbar setting '},
2251
+ version: {parent: ' widget '},
2252
+ visible: {parent: ' canvas frame image scrollbar text textarea window '},
2253
+ vlinesize: {parent: ' frame '},
2254
+ voffset: {parent: ' about-text about-version canvas frame image scrollbar shadow text textarea window '},
2255
+ vregistrationpoint: {parent: ' canvas frame image scrollbar text '},
2256
+ vscrollbar: {parent: ' frame '},
2257
+ width: {parent: ' canvas frame image scrollbar text textarea window '},
2258
+ window: {parent: ' canvas frame image scrollbar text textarea widget '},
2259
+ wrap: {parent: ' text '},
2260
+ zorder: {parent: ' canvas frame image scrollbar text textarea window '}
2261
+ }
2262
+ }
2263
+ };
2264
+
2265
+ function xmlword(tag) {
2266
+ var w = nexttoken.value;
2267
+ if (!nexttoken.identifier) {
2268
+ if (nexttoken.id === '<') {
2269
+ if (tag) {
2270
+ error("Expected '{a}' and instead saw '{b}'.",
2271
+ token, '&lt;', '<');
2272
+ } else {
2273
+ error("Missing '{a}'.", token, '>');
2274
+ }
2275
+ } else if (nexttoken.id === '(end)') {
2276
+ error("Bad structure.");
2277
+ } else {
2278
+ warning("Missing quote.", token);
2279
+ }
2280
+ }
2281
+ advance();
2282
+ while (nexttoken.id === '-' || nexttoken.id === ':') {
2283
+ w += nexttoken.id;
2284
+ advance();
2285
+ if (!nexttoken.identifier) {
2286
+ error("Bad name '{a}'.", nexttoken, w + nexttoken.value);
2287
+ }
2288
+ w += nexttoken.value;
2289
+ advance();
2290
+ }
2291
+ if (option.cap) {
2292
+ w = w.toLowerCase();
2293
+ }
2294
+ return w;
2295
+ }
2296
+
2297
+ function closetag(n) {
2298
+ return '</' + n + '>';
2299
+ }
2300
+
2301
+ function xml() {
2302
+ var a, e, n, q, t, wmode;
2303
+ xmode = 'xml';
2304
+ stack = null;
2305
+ for (;;) {
2306
+ switch (nexttoken.value) {
2307
+ case '<':
2308
+ if (!stack) {
2309
+ stack = [];
2310
+ }
2311
+ advance('<');
2312
+ t = nexttoken;
2313
+ n = xmlword(true);
2314
+ t.name = n;
2315
+ if (!xtype) {
2316
+ if (option.fragment && option.adsafe &&
2317
+ n !== 'div' && n !== 'iframe') {
2318
+ error("ADsafe HTML fragment violation.", token);
2319
+ }
2320
+ if (xmltype[n]) {
2321
+ xmltype[n].doBegin();
2322
+ n = xtype;
2323
+ e = false;
2324
+ } else {
2325
+ if (option.fragment) {
2326
+ xmltype.html.doBegin();
2327
+ } else {
2328
+ error("Unrecognized tag '<{a}>'.", nexttoken, n);
2329
+ }
2330
+ }
2331
+ } else {
2332
+ if (stack.length === 0) {
2333
+ error("What the hell is this?");
2334
+ }
2335
+ e = xmltype[xtype].doTagName(n,
2336
+ stack[stack.length - 1].name);
2337
+ }
2338
+ t.type = n;
2339
+ for (;;) {
2340
+ if (nexttoken.id === '/') {
2341
+ advance('/');
2342
+ if (nexttoken.id !== '>') {
2343
+ warning("Expected '{a}' and instead saw '{b}'.",
2344
+ nexttoken, '>', nexttoken.value);
2345
+ }
2346
+ e = true;
2347
+ break;
2348
+ }
2349
+ if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') {
2350
+ break;
2351
+ }
2352
+ a = xmlword();
2353
+ switch (xmltype[xtype].doAttribute(n, a)) {
2354
+ case 'script':
2355
+ xmode = 'string';
2356
+ advance('=');
2357
+ q = nexttoken.id;
2358
+ if (q !== '"' && q !== "'") {
2359
+ error("Missing quote.");
2360
+ }
2361
+ xmode = q;
2362
+ wmode = option.white;
2363
+ option.white = false;
2364
+ advance(q);
2365
+ statements();
2366
+ option.white = wmode;
2367
+ if (nexttoken.id !== q) {
2368
+ error("Missing close quote on script attribute.");
2369
+ }
2370
+ xmode = 'xml';
2371
+ advance(q);
2372
+ break;
2373
+ case 'value':
2374
+ advance('=');
2375
+ if (!nexttoken.identifier &&
2376
+ nexttoken.type !== '(string)' &&
2377
+ nexttoken.type !== '(number)') {
2378
+ error("Bad value '{a}'.",
2379
+ nexttoken, nexttoken.value);
2380
+ }
2381
+ advance();
2382
+ break;
2383
+ case 'string':
2384
+ advance('=');
2385
+ if (nexttoken.type !== '(string)') {
2386
+ error("Bad value '{a}'.",
2387
+ nexttoken, nexttoken.value);
2388
+ }
2389
+ advance();
2390
+ break;
2391
+ case 'href':
2392
+ advance('=');
2393
+ if (nexttoken.type !== '(string)') {
2394
+ error("Bad value '{a}'.",
2395
+ nexttoken, nexttoken.value);
2396
+ }
2397
+ if (option.adsafe && ux.test(nexttoken.value)) {
2398
+ error("ADsafe URL violation.");
2399
+ }
2400
+ advance();
2401
+ break;
2402
+ case 'define':
2403
+ advance('=');
2404
+ if (nexttoken.type !== '(string)') {
2405
+ error("Bad value '{a}'.",
2406
+ nexttoken, nexttoken.value);
2407
+ }
2408
+ addlabel(nexttoken.value, 'var');
2409
+ advance();
2410
+ break;
2411
+ default:
2412
+ if (nexttoken.id === '=') {
2413
+ advance('=');
2414
+ if (!nexttoken.identifier &&
2415
+ nexttoken.type !== '(string)' &&
2416
+ nexttoken.type !== '(number)') {
2417
+ error("Bad value '{a}'.",
2418
+ nexttoken, nexttoken.value);
2419
+ }
2420
+ advance();
2421
+ }
2422
+ }
2423
+ }
2424
+ switch (xmltype[xtype].doIt(n)) {
2425
+ case 'script':
2426
+ xmode = 'script';
2427
+ advance('>');
2428
+ indent = nexttoken.from;
2429
+ if (src) {
2430
+ if (option.fragment && option.adsafe) {
2431
+ warning("ADsafe script violation.", token);
2432
+ }
2433
+ } else {
2434
+ statements();
2435
+ }
2436
+ if (nexttoken.id !== '</' && nexttoken.id !== '(end)') {
2437
+ warning("Expected '{a}' and instead saw '{b}'.",
2438
+ nexttoken, '<\/script>', nexttoken.value);
2439
+ }
2440
+ xmode = 'xml';
2441
+ break;
2442
+ case 'special':
2443
+ e = true;
2444
+ n = closetag(t.name);
2445
+ if (!lex.skip(n)) {
2446
+ error("Missing '{a}'.", t, n);
2447
+ }
2448
+ break;
2449
+ default:
2450
+ lex.skip('>');
2451
+ }
2452
+ if (!e) {
2453
+ stack.push(t);
2454
+ }
2455
+ break;
2456
+ case '</':
2457
+ advance('</');
2458
+ n = xmlword(true);
2459
+ t = stack.pop();
2460
+ if (!t) {
2461
+ error("Unexpected '{a}'.", nexttoken, closetag(n));
2462
+ }
2463
+ if (t.name !== n) {
2464
+ error("Expected '{a}' and instead saw '{b}'.",
2465
+ nexttoken, closetag(t.name), closetag(n));
2466
+ }
2467
+ if (nexttoken.id !== '>') {
2468
+ error("Missing '{a}'.", nexttoken, '>');
2469
+ }
2470
+ if (stack.length > 0) {
2471
+ lex.skip('>');
2472
+ } else {
2473
+ advance('>');
2474
+ }
2475
+ break;
2476
+ case '<!':
2477
+ if (option.adsafe) {
2478
+ error("ADsafe HTML violation.");
2479
+ }
2480
+ for (;;) {
2481
+ advance();
2482
+ if (nexttoken.id === '>') {
2483
+ break;
2484
+ }
2485
+ if (nexttoken.id === '<' || nexttoken.id === '(end)') {
2486
+ error("Missing '{a}'.", token, '>');
2487
+ }
2488
+ }
2489
+ lex.skip('>');
2490
+ break;
2491
+ case '<!--':
2492
+ if (option.adsafe) {
2493
+ error("ADsafe comment violation.");
2494
+ }
2495
+ lex.skip('-->');
2496
+ break;
2497
+ case '<%':
2498
+ if (option.adsafe) {
2499
+ error("ADsafe HTML violation.");
2500
+ }
2501
+ lex.skip('%>');
2502
+ break;
2503
+ case '<?':
2504
+ if (option.adsafe) {
2505
+ error("ADsafe HTML violation.");
2506
+ }
2507
+ for (;;) {
2508
+ advance();
2509
+ if (nexttoken.id === '?>') {
2510
+ break;
2511
+ }
2512
+ if (nexttoken.id === '<?' || nexttoken.id === '<' ||
2513
+ nexttoken.id === '>' || nexttoken.id === '(end)') {
2514
+ error("Missing '{a}'.", token, '?>');
2515
+ }
2516
+ }
2517
+ lex.skip('?>');
2518
+ break;
2519
+ case '<=':
2520
+ case '<<':
2521
+ case '<<=':
2522
+ error("Missing '{a}'.", nexttoken, '&lt;');
2523
+ break;
2524
+ case '(end)':
2525
+ return;
2526
+ }
2527
+ if (stack && stack.length === 0) {
2528
+ return;
2529
+ }
2530
+ if (!lex.skip('')) {
2531
+ if (!stack) {
2532
+ error("Bad XML.");
2533
+ }
2534
+ t = stack.pop();
2535
+ if (t.value) {
2536
+ error("Missing '{a}'.", t, closetag(t.name));
2537
+ } else {
2538
+ return;
2539
+ }
2540
+ }
2541
+ advance();
2542
+ }
2543
+ }
2544
+
2545
+
2546
+ // Build the syntax table by declaring the syntactic elements of the language.
2547
+
2548
+ type('(number)', idValue);
2549
+ type('(string)', idValue);
2550
+
2551
+ syntax['(identifier)'] = {
2552
+ type: '(identifier)',
2553
+ lbp: 0,
2554
+ identifier: true,
2555
+ nud: function () {
2556
+ var v = this.value,
2557
+ s = scope[v];
2558
+
2559
+ // The name is in scope and defined in the current function.
2560
+
2561
+ if (s && (s === funct || s === funct['(global)'])) {
2562
+
2563
+ // If we are not also in the global scope, change 'unused' to 'var',
2564
+ // and reject labels.
2565
+
2566
+ if (!funct['(global)']) {
2567
+ switch (funct[v]) {
2568
+ case 'unused':
2569
+ funct[v] = 'var';
2570
+ break;
2571
+ case 'label':
2572
+ warning("'{a}' is a statement label.", token, v);
2573
+ break;
2574
+ }
2575
+ }
2576
+
2577
+ // The name is not defined in the function. If we are in the global scope,
2578
+ // then we have an undefined variable.
2579
+
2580
+ } else if (funct['(global)']) {
2581
+ if (option.undef) {
2582
+ warning("'{a}' is undefined.", token, v);
2583
+ }
2584
+ note_implied(token);
2585
+
2586
+ // If the name is already defined in the current
2587
+ // function, but not as outer, then there is a scope error.
2588
+
2589
+ } else {
2590
+ switch (funct[v]) {
2591
+ case 'closure':
2592
+ case 'function':
2593
+ case 'var':
2594
+ case 'unused':
2595
+ warning("'{a}' used out of scope.", token, v);
2596
+ break;
2597
+ case 'label':
2598
+ warning("'{a}' is a statement label.", token, v);
2599
+ break;
2600
+ case 'outer':
2601
+ case true:
2602
+ break;
2603
+ default:
2604
+
2605
+ // If the name is defined in an outer function, make an outer entry, and if
2606
+ // it was unused, make it var.
2607
+
2608
+ if (s === true) {
2609
+ funct[v] = true;
2610
+ } else if (typeof s !== 'object') {
2611
+ if (option.undef) {
2612
+ warning("'{a}' is undefined.", token, v);
2613
+ } else {
2614
+ funct[v] = true;
2615
+ }
2616
+ note_implied(token);
2617
+ } else {
2618
+ switch (s[v]) {
2619
+ case 'function':
2620
+ case 'var':
2621
+ case 'unused':
2622
+ s[v] = 'closure';
2623
+ funct[v] = 'outer';
2624
+ break;
2625
+ case 'closure':
2626
+ case 'parameter':
2627
+ funct[v] = 'outer';
2628
+ break;
2629
+ case 'label':
2630
+ warning("'{a}' is a statement label.", token, v);
2631
+ }
2632
+ }
2633
+ }
2634
+ }
2635
+ return this;
2636
+ },
2637
+ led: function () {
2638
+ error("Expected an operator and instead saw '{a}'.",
2639
+ nexttoken, nexttoken.value);
2640
+ }
2641
+ };
2642
+
2643
+ type('(regex)', function () {
2644
+ return [this.id, this.value, this.flags];
2645
+ });
2646
+
2647
+ delim('(endline)');
2648
+ delim('(begin)');
2649
+ delim('(end)').reach = true;
2650
+ delim('</').reach = true;
2651
+ delim('<![').reach = true;
2652
+ delim('<%');
2653
+ delim('<?');
2654
+ delim('<!');
2655
+ delim('<!--');
2656
+ delim('%>');
2657
+ delim('?>');
2658
+ delim('(error)').reach = true;
2659
+ delim('}').reach = true;
2660
+ delim(')');
2661
+ delim(']');
2662
+ delim(']]>').reach = true;
2663
+ delim('"').reach = true;
2664
+ delim("'").reach = true;
2665
+ delim(';');
2666
+ delim(':').reach = true;
2667
+ delim(',');
2668
+ reserve('else');
2669
+ reserve('case').reach = true;
2670
+ reserve('catch');
2671
+ reserve('default').reach = true;
2672
+ reserve('finally');
2673
+ reservevar('arguments');
2674
+ reservevar('eval');
2675
+ reservevar('false');
2676
+ reservevar('Infinity');
2677
+ reservevar('NaN');
2678
+ reservevar('null');
2679
+ reservevar('this');
2680
+ reservevar('true');
2681
+ reservevar('undefined');
2682
+ assignop('=', 'assign', 20);
2683
+ assignop('+=', 'assignadd', 20);
2684
+ assignop('-=', 'assignsub', 20);
2685
+ assignop('*=', 'assignmult', 20);
2686
+ assignop('/=', 'assigndiv', 20).nud = function () {
2687
+ error("A regular expression literal can be confused with '/='.");
2688
+ };
2689
+ assignop('%=', 'assignmod', 20);
2690
+ bitwiseassignop('&=', 'assignbitand', 20);
2691
+ bitwiseassignop('|=', 'assignbitor', 20);
2692
+ bitwiseassignop('^=', 'assignbitxor', 20);
2693
+ bitwiseassignop('<<=', 'assignshiftleft', 20);
2694
+ bitwiseassignop('>>=', 'assignshiftright', 20);
2695
+ bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20);
2696
+ infix('?', function (left) {
2697
+ parse(10);
2698
+ advance(':');
2699
+ parse(10);
2700
+ }, 30);
2701
+
2702
+ infix('||', 'or', 40);
2703
+ infix('&&', 'and', 50);
2704
+ bitwise('|', 'bitor', 70);
2705
+ bitwise('^', 'bitxor', 80);
2706
+ bitwise('&', 'bitand', 90);
2707
+ relation('==', function (left, right) {
2708
+ if (option.eqeqeq) {
2709
+ warning("Expected '{a}' and instead saw '{b}'.",
2710
+ this, '===', '==');
2711
+ } else if (isPoorRelation(left)) {
2712
+ warning("Use '{a}' to compare with '{b}'.",
2713
+ this, '===', left.value);
2714
+ } else if (isPoorRelation(right)) {
2715
+ warning("Use '{a}' to compare with '{b}'.",
2716
+ this, '===', right.value);
2717
+ }
2718
+ return ['==', left, right];
2719
+ });
2720
+ relation('===');
2721
+ relation('!=', function (left, right) {
2722
+ if (option.eqeqeq) {
2723
+ warning("Expected '{a}' and instead saw '{b}'.",
2724
+ this, '!==', '!=');
2725
+ } else if (isPoorRelation(left)) {
2726
+ warning("Use '{a}' to compare with '{b}'.",
2727
+ this, '!==', left.value);
2728
+ } else if (isPoorRelation(right)) {
2729
+ warning("Use '{a}' to compare with '{b}'.",
2730
+ this, '!==', right.value);
2731
+ }
2732
+ return ['!=', left, right];
2733
+ });
2734
+ relation('!==');
2735
+ relation('<');
2736
+ relation('>');
2737
+ relation('<=');
2738
+ relation('>=');
2739
+ bitwise('<<', 'shiftleft', 120);
2740
+ bitwise('>>', 'shiftright', 120);
2741
+ bitwise('>>>', 'shiftrightunsigned', 120);
2742
+ infix('in', 'in', 120);
2743
+ infix('instanceof', 'instanceof', 120);
2744
+ infix('+', function (left) {
2745
+ nonadjacent(prevtoken, token);
2746
+ nonadjacent(token, nexttoken);
2747
+ var right = parse(130);
2748
+ if (left && right && left.id === '(string)' && right.id === '(string)') {
2749
+ left.value += right.value;
2750
+ left.character = right.character;
2751
+ if (jx.test(left.value)) {
2752
+ warning("JavaScript URL.", left);
2753
+ }
2754
+ return left;
2755
+ }
2756
+ return [this.id, left, right];
2757
+ }, 130);
2758
+ prefix('+', 'num');
2759
+ infix('-', 'sub', 130);
2760
+ prefix('-', 'neg');
2761
+ infix('*', 'mult', 140);
2762
+ infix('/', 'div', 140);
2763
+ infix('%', 'mod', 140);
2764
+
2765
+ suffix('++', 'postinc');
2766
+ prefix('++', 'preinc');
2767
+ syntax['++'].exps = true;
2768
+
2769
+ suffix('--', 'postdec');
2770
+ prefix('--', 'predec');
2771
+ syntax['--'].exps = true;
2772
+ prefix('delete', function () {
2773
+ var p = parse(0);
2774
+ if (p.id !== '.' && p.id !== '[') {
2775
+ warning("Expected '{a}' and instead saw '{b}'.",
2776
+ nexttoken, '.', nexttoken.value);
2777
+ }
2778
+ }).exps = true;
2779
+
2780
+
2781
+ prefix('~', function () {
2782
+ if (option.bitwise) {
2783
+ warning("Unexpected '{a}'.", this, '~');
2784
+ }
2785
+ parse(150);
2786
+ return this;
2787
+ });
2788
+ prefix('!', 'not');
2789
+ prefix('typeof', 'typeof');
2790
+ prefix('new', function () {
2791
+ var c = parse(155), i;
2792
+ if (c) {
2793
+ if (c.identifier) {
2794
+ c['new'] = true;
2795
+ switch (c.value) {
2796
+ case 'Object':
2797
+ warning("Use the object literal notation {}.", token);
2798
+ break;
2799
+ case 'Array':
2800
+ warning("Use the array literal notation [].", token);
2801
+ break;
2802
+ case 'Number':
2803
+ case 'String':
2804
+ case 'Boolean':
2805
+ warning("Do not use the {a} function as a constructor.",
2806
+ token, c.value);
2807
+ break;
2808
+ case 'Function':
2809
+ if (!option.evil) {
2810
+ warning("The Function constructor is eval.");
2811
+ }
2812
+ break;
2813
+ default:
2814
+ if (c.id !== 'function') {
2815
+ i = c.value.substr(0, 1);
2816
+ if (i < 'A' || i > 'Z') {
2817
+ warning(
2818
+ "A constructor name should start with an uppercase letter.",
2819
+ token);
2820
+ }
2821
+ }
2822
+ }
2823
+ } else {
2824
+ if (c.id !== '.' && c.id !== '[' && c.id !== '(') {
2825
+ warning("Bad constructor.", token);
2826
+ }
2827
+ }
2828
+ } else {
2829
+ warning("Weird construction. Delete 'new'.", this);
2830
+ }
2831
+ adjacent(token, nexttoken);
2832
+ if (nexttoken.id === '(') {
2833
+ advance('(');
2834
+ nospace();
2835
+ if (nexttoken.id !== ')') {
2836
+ for (;;) {
2837
+ parse(10);
2838
+ if (nexttoken.id !== ',') {
2839
+ break;
2840
+ }
2841
+ advance(',');
2842
+ }
2843
+ }
2844
+ advance(')');
2845
+ nospace(prevtoken, token);
2846
+ } else {
2847
+ warning("Missing '()' invoking a constructor.");
2848
+ }
2849
+ return syntax['function'];
2850
+ });
2851
+ syntax['new'].exps = true;
2852
+
2853
+ infix('.', function (left) {
2854
+ adjacent(prevtoken, token);
2855
+ var m = identifier();
2856
+ if (typeof m === 'string') {
2857
+ countMember(m);
2858
+ }
2859
+ if (!option.evil && left && left.value === 'document' &&
2860
+ (m === 'write' || m === 'writeln')) {
2861
+ warning("document.write can be a form of eval.", left);
2862
+ }
2863
+ this.left = left;
2864
+ this.right = m;
2865
+ return this;
2866
+ }, 160);
2867
+
2868
+ infix('(', function (left) {
2869
+ adjacent(prevtoken, token);
2870
+ nospace();
2871
+ var n = 0;
2872
+ var p = [];
2873
+ if (left && left.type === '(identifier)') {
2874
+ if (left.value.match(/^[A-Z](.*[a-z].*)?$/)) {
2875
+ if (left.value !== 'Number' && left.value !== 'String' &&
2876
+ left.value !== 'Boolean' && left.value !== 'Date') {
2877
+ warning("Missing 'new' prefix when invoking a constructor.",
2878
+ left);
2879
+ }
2880
+ }
2881
+ }
2882
+ if (nexttoken.id !== ')') {
2883
+ for (;;) {
2884
+ p[p.length] = parse(10);
2885
+ n += 1;
2886
+ if (nexttoken.id !== ',') {
2887
+ break;
2888
+ }
2889
+ advance(',');
2890
+ nonadjacent(token, nexttoken);
2891
+ }
2892
+ }
2893
+ advance(')');
2894
+ nospace(prevtoken, token);
2895
+ if (typeof left === 'object') {
2896
+ if (left.value === 'parseInt' && n === 1) {
2897
+ warning("Missing radix parameter.", left);
2898
+ }
2899
+ if (!option.evil) {
2900
+ if (left.value === 'eval' || left.value === 'Function') {
2901
+ warning("eval is evil.", left);
2902
+ } else if (p[0] && p[0].id === '(string)' &&
2903
+ (left.value === 'setTimeout' ||
2904
+ left.value === 'setInterval')) {
2905
+ warning(
2906
+ "Implied eval is evil. Pass a function instead of a string.", left);
2907
+ }
2908
+ }
2909
+ if (!left.identifier && left.id !== '.' &&
2910
+ left.id !== '[' && left.id !== '(') {
2911
+ warning("Bad invocation.", left);
2912
+ }
2913
+
2914
+ }
2915
+ return syntax['function'];
2916
+ }, 155).exps = true;
2917
+
2918
+ prefix('(', function () {
2919
+ nospace();
2920
+ var v = parse(0);
2921
+ advance(')', this);
2922
+ nospace(prevtoken, token);
2923
+ return v;
2924
+ });
2925
+
2926
+ infix('[', function (left) {
2927
+ if (option.adsafe) {
2928
+ warning('ADsafe subscripting.');
2929
+ }
2930
+ nospace();
2931
+ var e = parse(0), s;
2932
+ if (e && e.type === '(string)') {
2933
+ countMember(e.value);
2934
+ if (ix.test(e.value)) {
2935
+ s = syntax[e.value];
2936
+ if (!s || !s.reserved) {
2937
+ warning("['{a}'] is better written in dot notation.",
2938
+ e, e.value);
2939
+ }
2940
+ }
2941
+ }
2942
+ advance(']', this);
2943
+ nospace(prevtoken, token);
2944
+ this.left = left;
2945
+ this.right = e;
2946
+ return this;
2947
+ }, 160);
2948
+
2949
+ prefix('[', function () {
2950
+ if (nexttoken.id === ']') {
2951
+ advance(']');
2952
+ return;
2953
+ }
2954
+ var b = token.line !== nexttoken.line;
2955
+ if (b) {
2956
+ indent += 4;
2957
+ if (nexttoken.from === indent + 4) {
2958
+ indent += 4;
2959
+ }
2960
+ }
2961
+ for (;;) {
2962
+ if (b && token.line !== nexttoken.line) {
2963
+ indentation();
2964
+ }
2965
+ parse(10);
2966
+ if (nexttoken.id === ',') {
2967
+ adjacent(token, nexttoken);
2968
+ advance(',');
2969
+ if (nexttoken.id === ',' || nexttoken.id === ']') {
2970
+ warning("Extra comma.", token);
2971
+ }
2972
+ nonadjacent(token, nexttoken);
2973
+ } else {
2974
+ if (b) {
2975
+ indent -= 4;
2976
+ indentation();
2977
+ }
2978
+ advance(']', this);
2979
+ return;
2980
+ }
2981
+ }
2982
+ }, 160);
2983
+
2984
+ (function (x) {
2985
+ x.nud = function () {
2986
+ var i, s;
2987
+ if (nexttoken.id === '}') {
2988
+ advance('}');
2989
+ return;
2990
+ }
2991
+ var b = token.line !== nexttoken.line;
2992
+ if (b) {
2993
+ indent += 4;
2994
+ if (nexttoken.from === indent + 4) {
2995
+ indent += 4;
2996
+ }
2997
+ }
2998
+ for (;;) {
2999
+ if (b) {
3000
+ indentation();
3001
+ }
3002
+ i = optionalidentifier(true);
3003
+ if (!i) {
3004
+ if (nexttoken.id === '(string)') {
3005
+ i = nexttoken.value;
3006
+ if (ix.test(i)) {
3007
+ s = syntax[i];
3008
+ }
3009
+ advance();
3010
+ } else if (nexttoken.id === '(number)') {
3011
+ i = nexttoken.value.toString();
3012
+ advance();
3013
+ } else {
3014
+ error("Expected '{a}' and instead saw '{b}'.",
3015
+ nexttoken, '}', nexttoken.value);
3016
+ }
3017
+ }
3018
+ countMember(i);
3019
+ advance(':');
3020
+ nonadjacent(token, nexttoken);
3021
+ parse(10);
3022
+ if (nexttoken.id === ',') {
3023
+ adjacent(token, nexttoken);
3024
+ advance(',');
3025
+ if (nexttoken.id === ',' || nexttoken.id === '}') {
3026
+ warning("Extra comma.", token);
3027
+ }
3028
+ nonadjacent(token, nexttoken);
3029
+ } else {
3030
+ if (b) {
3031
+ indent -= 4;
3032
+ indentation();
3033
+ }
3034
+ advance('}', this);
3035
+ return;
3036
+ }
3037
+ }
3038
+ };
3039
+ x.fud = function () {
3040
+ error("Expected to see a statement and instead saw a block.", token);
3041
+ };
3042
+ })(delim('{'));
3043
+
3044
+
3045
+ function varstatement() {
3046
+
3047
+ // JavaScript does not have block scope. It only has function scope. So,
3048
+ // declaring a variable in a block can have unexpected consequences.
3049
+
3050
+ for (;;) {
3051
+ nonadjacent(token, nexttoken);
3052
+ addlabel(identifier(), 'unused');
3053
+ if (nexttoken.id === '=') {
3054
+ nonadjacent(token, nexttoken);
3055
+ advance('=');
3056
+ nonadjacent(token, nexttoken);
3057
+ if (peek(0).id === '=') {
3058
+ error("Variable {a} was not declared correctly.",
3059
+ nexttoken, nexttoken.value);
3060
+ }
3061
+ parse(20);
3062
+ }
3063
+ if (nexttoken.id !== ',') {
3064
+ return;
3065
+ }
3066
+ adjacent(token, nexttoken);
3067
+ advance(',');
3068
+ nonadjacent(token, nexttoken);
3069
+ }
3070
+ }
3071
+
3072
+
3073
+ stmt('var', varstatement);
3074
+
3075
+ stmt('new', function () {
3076
+ error("'new' should not be used as a statement.");
3077
+ });
3078
+
3079
+
3080
+ function functionparams() {
3081
+ var i, t = nexttoken, p = [];
3082
+ advance('(');
3083
+ nospace();
3084
+ if (nexttoken.id === ')') {
3085
+ advance(')');
3086
+ nospace(prevtoken, token);
3087
+ return;
3088
+ }
3089
+ for (;;) {
3090
+ i = identifier();
3091
+ p.push(i);
3092
+ addlabel(i, 'parameter');
3093
+ if (nexttoken.id === ',') {
3094
+ advance(',');
3095
+ nonadjacent(token, nexttoken);
3096
+ } else {
3097
+ advance(')', t);
3098
+ nospace(prevtoken, token);
3099
+ return p.join(', ');
3100
+ }
3101
+ }
3102
+ }
3103
+
3104
+ function doFunction(i) {
3105
+ var s = scope;
3106
+ scope = object(s);
3107
+ funct = {
3108
+ '(name)' : i || '"' + anonname + '"',
3109
+ '(line)' : nexttoken.line + 1,
3110
+ '(context)' : funct,
3111
+ '(scope)' : scope
3112
+ };
3113
+ functions.push(funct);
3114
+ if (i) {
3115
+ addlabel(i, 'function');
3116
+ }
3117
+ funct['(params)'] = functionparams();
3118
+
3119
+ block(false);
3120
+ scope = s;
3121
+ funct = funct['(context)'];
3122
+ }
3123
+
3124
+
3125
+ blockstmt('function', function () {
3126
+ if (inblock) {
3127
+ warning(
3128
+ "Function statements cannot be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token);
3129
+
3130
+ }
3131
+ var i = identifier();
3132
+ adjacent(token, nexttoken);
3133
+ addlabel(i, 'unused');
3134
+ doFunction(i);
3135
+ if (nexttoken.id === '(' && nexttoken.line === token.line) {
3136
+ error(
3137
+ "Function statements are not invocable. Wrap the function expression in parens.");
3138
+ }
3139
+ });
3140
+
3141
+ prefix('function', function () {
3142
+ var i = optionalidentifier();
3143
+ if (i) {
3144
+ adjacent(token, nexttoken);
3145
+ } else {
3146
+ nonadjacent(token, nexttoken);
3147
+ }
3148
+ doFunction(i);
3149
+ });
3150
+
3151
+ blockstmt('if', function () {
3152
+ var t = nexttoken;
3153
+ advance('(');
3154
+ nonadjacent(this, t);
3155
+ nospace();
3156
+ parse(20);
3157
+ if (nexttoken.id === '=') {
3158
+ warning("Assignment in control part.");
3159
+ advance('=');
3160
+ parse(20);
3161
+ }
3162
+ advance(')', t);
3163
+ nospace(prevtoken, token);
3164
+ block(true);
3165
+ if (nexttoken.id === 'else') {
3166
+ nonadjacent(token, nexttoken);
3167
+ advance('else');
3168
+ if (nexttoken.id === 'if' || nexttoken.id === 'switch') {
3169
+ statement(true);
3170
+ } else {
3171
+ block(true);
3172
+ }
3173
+ }
3174
+ return this;
3175
+ });
3176
+
3177
+ blockstmt('try', function () {
3178
+ var b, e, s;
3179
+ block(false);
3180
+ if (nexttoken.id === 'catch') {
3181
+ advance('catch');
3182
+ nonadjacent(token, nexttoken);
3183
+ advance('(');
3184
+ s = scope;
3185
+ scope = object(s);
3186
+ e = nexttoken.value;
3187
+ if (nexttoken.type !== '(identifier)') {
3188
+ warning("Expected an identifier and instead saw '{a}'.",
3189
+ nexttoken, e);
3190
+ } else {
3191
+ addlabel(e, 'unused');
3192
+ }
3193
+ advance();
3194
+ advance(')');
3195
+ block(false);
3196
+ b = true;
3197
+ scope = s;
3198
+ }
3199
+ if (nexttoken.id === 'finally') {
3200
+ advance('finally');
3201
+ block(false);
3202
+ return;
3203
+ } else if (!b) {
3204
+ error("Expected '{a}' and instead saw '{b}'.",
3205
+ nexttoken, 'catch', nexttoken.value);
3206
+ }
3207
+ });
3208
+
3209
+ blockstmt('while', function () {
3210
+ var t = nexttoken;
3211
+ advance('(');
3212
+ nonadjacent(this, t);
3213
+ nospace();
3214
+ parse(20);
3215
+ if (nexttoken.id === '=') {
3216
+ warning("Assignment in control part.");
3217
+ advance('=');
3218
+ parse(20);
3219
+ }
3220
+ advance(')', t);
3221
+ nospace(prevtoken, token);
3222
+ block(true);
3223
+ }).labelled = true;
3224
+
3225
+ reserve('with');
3226
+
3227
+ blockstmt('switch', function () {
3228
+ var t = nexttoken;
3229
+ var g = false;
3230
+ advance('(');
3231
+ nonadjacent(this, t);
3232
+ nospace();
3233
+ this.condition = parse(20);
3234
+ advance(')', t);
3235
+ nospace(prevtoken, token);
3236
+ nonadjacent(token, nexttoken);
3237
+ t = nexttoken;
3238
+ advance('{');
3239
+ nonadjacent(token, nexttoken);
3240
+ indent += 4;
3241
+ this.cases = [];
3242
+ for (;;) {
3243
+ switch (nexttoken.id) {
3244
+ case 'case':
3245
+ switch (funct['(verb)']) {
3246
+ case 'break':
3247
+ case 'case':
3248
+ case 'continue':
3249
+ case 'return':
3250
+ case 'switch':
3251
+ case 'throw':
3252
+ break;
3253
+ default:
3254
+ warning(
3255
+ "Expected a 'break' statement before 'case'.",
3256
+ token);
3257
+ }
3258
+ indentation(-4);
3259
+ advance('case');
3260
+ this.cases.push(parse(20));
3261
+ g = true;
3262
+ advance(':');
3263
+ funct['(verb)'] = 'case';
3264
+ break;
3265
+ case 'default':
3266
+ switch (funct['(verb)']) {
3267
+ case 'break':
3268
+ case 'continue':
3269
+ case 'return':
3270
+ case 'throw':
3271
+ break;
3272
+ default:
3273
+ warning(
3274
+ "Expected a 'break' statement before 'default'.",
3275
+ token);
3276
+ }
3277
+ indentation(-4);
3278
+ advance('default');
3279
+ g = true;
3280
+ advance(':');
3281
+ break;
3282
+ case '}':
3283
+ indent -= 4;
3284
+ indentation();
3285
+ advance('}', t);
3286
+ if (this.cases.length === 1 || this.condition.id === 'true' ||
3287
+ this.condition.id === 'false') {
3288
+ warning("This 'switch' should be an 'if'.", this);
3289
+ }
3290
+ return;
3291
+ case '(end)':
3292
+ error("Missing '{a}'.", nexttoken, '}');
3293
+ return;
3294
+ default:
3295
+ if (g) {
3296
+ switch (token.id) {
3297
+ case ',':
3298
+ error("Each value should have its own case label.");
3299
+ return;
3300
+ case ':':
3301
+ statements();
3302
+ break;
3303
+ default:
3304
+ error("Missing ':' on a case clause.", token);
3305
+ }
3306
+ } else {
3307
+ error("Expected '{a}' and instead saw '{b}'.",
3308
+ nexttoken, 'case', nexttoken.value);
3309
+ }
3310
+ }
3311
+ }
3312
+ }).labelled = true;
3313
+
3314
+ stmt('debugger', function () {
3315
+ if (!option.debug) {
3316
+ warning("All 'debugger' statements should be removed.");
3317
+ }
3318
+ });
3319
+
3320
+ stmt('do', function () {
3321
+ block(true);
3322
+ advance('while');
3323
+ var t = nexttoken;
3324
+ nonadjacent(token, t);
3325
+ advance('(');
3326
+ nospace();
3327
+ parse(20);
3328
+ advance(')', t);
3329
+ nospace(prevtoken, token);
3330
+ }).labelled = true;
3331
+
3332
+ blockstmt('for', function () {
3333
+ var s, t = nexttoken;
3334
+ advance('(');
3335
+ nonadjacent(this, t);
3336
+ nospace();
3337
+ if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {
3338
+ if (nexttoken.id === 'var') {
3339
+ advance('var');
3340
+ addlabel(identifier(), 'var');
3341
+ } else {
3342
+ advance();
3343
+ }
3344
+ advance('in');
3345
+ parse(20);
3346
+ advance(')', t);
3347
+ if (nexttoken.id === 'if') {
3348
+ nolinebreak(token);
3349
+ statement(true);
3350
+ } else {
3351
+ s = block(true);
3352
+ if (!option.forin && (s.length > 1 || typeof s[0] !== 'object' ||
3353
+ s[0].value !== 'if')) {
3354
+ warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this);
3355
+ }
3356
+ }
3357
+ return this;
3358
+ } else {
3359
+ if (nexttoken.id !== ';') {
3360
+ if (nexttoken.id === 'var') {
3361
+ advance('var');
3362
+ varstatement();
3363
+ } else {
3364
+ for (;;) {
3365
+ parse(0);
3366
+ if (nexttoken.id !== ',') {
3367
+ break;
3368
+ }
3369
+ advance(',');
3370
+ }
3371
+ }
3372
+ }
3373
+ advance(';');
3374
+ if (nexttoken.id !== ';') {
3375
+ parse(20);
3376
+ }
3377
+ advance(';');
3378
+ if (nexttoken.id === ';') {
3379
+ error("Expected '{a}' and instead saw '{b}'.",
3380
+ nexttoken, ')', ';');
3381
+ }
3382
+ if (nexttoken.id !== ')') {
3383
+ for (;;) {
3384
+ parse(0);
3385
+ if (nexttoken.id !== ',') {
3386
+ break;
3387
+ }
3388
+ advance(',');
3389
+ }
3390
+ }
3391
+ advance(')', t);
3392
+ nospace(prevtoken, token);
3393
+ block(true);
3394
+ }
3395
+ }).labelled = true;
3396
+
3397
+
3398
+ stmt('break', function () {
3399
+ var v = nexttoken.value;
3400
+ nolinebreak(this);
3401
+ if (nexttoken.id !== ';') {
3402
+ if (funct[v] !== 'label') {
3403
+ warning("'{a}' is not a statement label.", nexttoken, v);
3404
+ } else if (scope[v] !== funct) {
3405
+ warning("'{a}' is out of scope.", nexttoken, v);
3406
+ }
3407
+ advance();
3408
+ }
3409
+ reachable('break');
3410
+ });
3411
+
3412
+
3413
+ stmt('continue', function () {
3414
+ var v = nexttoken.value;
3415
+ nolinebreak(this);
3416
+ if (nexttoken.id !== ';') {
3417
+ if (funct[v] !== 'label') {
3418
+ warning("'{a}' is not a statement label.", nexttoken, v);
3419
+ } else if (scope[v] !== funct) {
3420
+ warning("'{a}' is out of scope.", nexttoken, v);
3421
+ }
3422
+ advance();
3423
+ }
3424
+ reachable('continue');
3425
+ });
3426
+
3427
+
3428
+ stmt('return', function () {
3429
+ nolinebreak(this);
3430
+ if (nexttoken.id !== ';' && !nexttoken.reach) {
3431
+ nonadjacent(token, nexttoken);
3432
+ parse(20);
3433
+ }
3434
+ reachable('return');
3435
+ });
3436
+
3437
+
3438
+ stmt('throw', function () {
3439
+ nolinebreak(this);
3440
+ nonadjacent(token, nexttoken);
3441
+ parse(20);
3442
+ reachable('throw');
3443
+ });
3444
+
3445
+
3446
+ // Superfluous reserved words
3447
+
3448
+ reserve('abstract');
3449
+ reserve('boolean');
3450
+ reserve('byte');
3451
+ reserve('char');
3452
+ reserve('class');
3453
+ reserve('const');
3454
+ reserve('double');
3455
+ reserve('enum');
3456
+ reserve('export');
3457
+ reserve('extends');
3458
+ reserve('final');
3459
+ reserve('float');
3460
+ reserve('goto');
3461
+ reserve('implements');
3462
+ reserve('import');
3463
+ reserve('int');
3464
+ reserve('interface');
3465
+ reserve('long');
3466
+ reserve('native');
3467
+ reserve('package');
3468
+ reserve('private');
3469
+ reserve('protected');
3470
+ reserve('public');
3471
+ reserve('short');
3472
+ reserve('static');
3473
+ reserve('super');
3474
+ reserve('synchronized');
3475
+ reserve('throws');
3476
+ reserve('transient');
3477
+ reserve('void');
3478
+ reserve('volatile');
3479
+
3480
+
3481
+ function jsonValue() {
3482
+
3483
+ function jsonObject() {
3484
+ var t = nexttoken;
3485
+ advance('{');
3486
+ if (nexttoken.id !== '}') {
3487
+ for (;;) {
3488
+ if (nexttoken.id === '(end)') {
3489
+ error("Missing '}' to match '{' from line {a}.",
3490
+ nexttoken, t.line + 1);
3491
+ } else if (nexttoken.id === '}') {
3492
+ warning("Unexpected comma.", token);
3493
+ break;
3494
+ } else if (nexttoken.id === ',') {
3495
+ error("Unexpected comma.", nexttoken);
3496
+ } else if (nexttoken.id !== '(string)') {
3497
+ warning("Expected a string and instead saw {a}.",
3498
+ nexttoken, nexttoken.value);
3499
+ }
3500
+ advance();
3501
+ advance(':');
3502
+ jsonValue();
3503
+ if (nexttoken.id !== ',') {
3504
+ break;
3505
+ }
3506
+ advance(',');
3507
+ }
3508
+ }
3509
+ advance('}');
3510
+ }
3511
+
3512
+ function jsonArray() {
3513
+ var t = nexttoken;
3514
+ advance('[');
3515
+ if (nexttoken.id !== ']') {
3516
+ for (;;) {
3517
+ if (nexttoken.id === '(end)') {
3518
+ error("Missing ']' to match '[' from line {a}.",
3519
+ nexttoken, t.line + 1);
3520
+ } else if (nexttoken.id === ']') {
3521
+ warning("Unexpected comma.", token);
3522
+ break;
3523
+ } else if (nexttoken.id === ',') {
3524
+ error("Unexpected comma.", nexttoken);
3525
+ }
3526
+ jsonValue();
3527
+ if (nexttoken.id !== ',') {
3528
+ break;
3529
+ }
3530
+ advance(',');
3531
+ }
3532
+ }
3533
+ advance(']');
3534
+ }
3535
+
3536
+ switch (nexttoken.id) {
3537
+ case '{':
3538
+ jsonObject();
3539
+ break;
3540
+ case '[':
3541
+ jsonArray();
3542
+ break;
3543
+ case 'true':
3544
+ case 'false':
3545
+ case 'null':
3546
+ case '(number)':
3547
+ case '(string)':
3548
+ advance();
3549
+ break;
3550
+ case '-':
3551
+ advance('-');
3552
+ if (token.character !== nexttoken.from) {
3553
+ warning("Unexpected space after '-'.", token);
3554
+ }
3555
+ adjacent(token, nexttoken);
3556
+ advance('(number)');
3557
+ break;
3558
+ default:
3559
+ error("Expected a JSON value.", nexttoken);
3560
+ }
3561
+ }
3562
+
3563
+
3564
+ // The actual JSLINT function itself.
3565
+
3566
+ var itself = function (s, o) {
3567
+ if (o) {
3568
+ if (o.adsafe) {
3569
+ o.browser = false;
3570
+ o.debug = false;
3571
+ o.eqeqeq = true;
3572
+ o.evil = false;
3573
+ o.forin = false;
3574
+ o.on = false;
3575
+ o.rhino = false;
3576
+ o.undef = true;
3577
+ o.widget = false;
3578
+ }
3579
+ option = o;
3580
+ } else {
3581
+ option = {};
3582
+ }
3583
+ globals = option.adsafe ? {} : object(standard);
3584
+ JSLINT.errors = [];
3585
+ global = object(globals);
3586
+ scope = global;
3587
+ funct = {'(global)': true, '(name)': '(global)', '(scope)': scope};
3588
+ functions = [];
3589
+ src = false;
3590
+ xmode = false;
3591
+ xtype = '';
3592
+ stack = null;
3593
+ member = {};
3594
+ membersOnly = null;
3595
+ implied = {};
3596
+ inblock = false;
3597
+ lookahead = [];
3598
+ indent = 0;
3599
+ jsonmode = false;
3600
+ warnings = 0;
3601
+ lex.init(s);
3602
+ prereg = true;
3603
+
3604
+ prevtoken = token = nexttoken = syntax['(begin)'];
3605
+ populateGlobals();
3606
+
3607
+ try {
3608
+ advance();
3609
+ if (nexttoken.value.charAt(0) === '<') {
3610
+ xml();
3611
+ } else if (nexttoken.id === '{' || nexttoken.id === '[') {
3612
+ option.laxbreak = true;
3613
+ jsonmode = true;
3614
+ jsonValue();
3615
+ } else {
3616
+ statements();
3617
+ }
3618
+ advance('(end)');
3619
+ } catch (e) {
3620
+ if (e) {
3621
+ JSLINT.errors.push({
3622
+ reason : e.message,
3623
+ line : e.line || nexttoken.line,
3624
+ character : e.character || nexttoken.from
3625
+ }, null);
3626
+ }
3627
+ }
3628
+ return JSLINT.errors.length === 0;
3629
+ };
3630
+
3631
+ function to_array(o) {
3632
+ var a = [], k;
3633
+ for (k in o) if (o.hasOwnProperty(k)) {
3634
+ a.push(k);
3635
+ }
3636
+ return a;
3637
+ }
3638
+
3639
+ // Report generator.
3640
+
3641
+ itself.report = function (option) {
3642
+ var a = [], c, e, f, i, k, l, m = '', n, o = [], s, v, cl, va, un, ou, gl, la;
3643
+
3644
+ function detail(h, s) {
3645
+ if (s.length) {
3646
+ o.push('<div><i>' + h + '</i> ' +
3647
+ s.sort().join(', ') + '</div>');
3648
+ }
3649
+ }
3650
+
3651
+ s = to_array(implied);
3652
+
3653
+ k = JSLINT.errors.length;
3654
+ if (k || s.length > 0) {
3655
+ o.push('<div id=errors><i>Error:</i>');
3656
+ if (s.length > 0) {
3657
+ s.sort();
3658
+ for (i = 0; i < s.length; i += 1) {
3659
+ s[i] = '<code>' + s[i] + '</code>&nbsp;<i>' +
3660
+ implied[s[i]].join(' ') +
3661
+ '</i>';
3662
+ }
3663
+ o.push('<p><i>Implied global:</i> ' + s.join(', ') + '</p>');
3664
+ c = true;
3665
+ }
3666
+ for (i = 0; i < k; i += 1) {
3667
+ c = JSLINT.errors[i];
3668
+ if (c) {
3669
+ e = c.evidence || '';
3670
+ o.push('<p>Problem' + (isFinite(c.line) ? ' at line ' + (c.line + 1) +
3671
+ ' character ' + (c.character + 1) : '') +
3672
+ ': ' + c.reason.entityify() +
3673
+ '</p><p class=evidence>' +
3674
+ (e && (e.length > 80 ? e.slice(0, 77) + '...' :
3675
+ e).entityify()) + '</p>');
3676
+ }
3677
+ }
3678
+ o.push('</div>');
3679
+ if (!c) {
3680
+ return o.join('');
3681
+ }
3682
+ }
3683
+
3684
+ if (!option) {
3685
+
3686
+ o.push('<div id=functions>');
3687
+
3688
+ s = to_array(scope);
3689
+ if (s.length === 0) {
3690
+ o.push('<div><i>No new global variables introduced.</i></div>');
3691
+ } else {
3692
+ o.push('<div><i>Global</i> ' + s.sort().join(', ') + '</div>');
3693
+ }
3694
+
3695
+ for (i = 0; i < functions.length; i += 1) {
3696
+ f = functions[i];
3697
+ cl = [];
3698
+ va = [];
3699
+ un = [];
3700
+ ou = [];
3701
+ gl = [];
3702
+ la = [];
3703
+ for (k in f) if (f.hasOwnProperty(k)) {
3704
+ v = f[k];
3705
+ switch (v) {
3706
+ case 'closure':
3707
+ cl.push(k);
3708
+ break;
3709
+ case 'var':
3710
+ va.push(k);
3711
+ break;
3712
+ case 'unused':
3713
+ un.push(k);
3714
+ break;
3715
+ case 'label':
3716
+ la.push(k);
3717
+ break;
3718
+ case 'outer':
3719
+ ou.push(k);
3720
+ break;
3721
+ case true:
3722
+ if (k !== '(context)') {
3723
+ gl.push(k);
3724
+ }
3725
+ break;
3726
+ }
3727
+ }
3728
+ o.push('<br><div class=function><i>' + f['(line)'] + '</i> ' +
3729
+ (f['(name)'] || '') + '(' +
3730
+ (f['(params)'] || '') + ')</div>');
3731
+ detail('Closure', cl);
3732
+ detail('Variable', va);
3733
+ detail('Unused', un);
3734
+ detail('Label', la);
3735
+ detail('Outer', ou);
3736
+ detail('Global', gl);
3737
+ }
3738
+ a = [];
3739
+ for (k in member) {
3740
+ if (typeof member[k] === 'number') {
3741
+ a.push(k);
3742
+ }
3743
+ }
3744
+ if (a.length) {
3745
+ a = a.sort();
3746
+ m = '<br><pre>/*members ';
3747
+ l = 10;
3748
+ for (i = 0; i < a.length; i += 1) {
3749
+ k = a[i];
3750
+ n = k.name();
3751
+ if (l + n.length > 72) {
3752
+ o.push(m + '<br>');
3753
+ m = ' ';
3754
+ l = 1;
3755
+ }
3756
+ l += n.length + 2;
3757
+ if (member[k] === 1) {
3758
+ n = '<i>' + n + '</i>';
3759
+ }
3760
+ if (i < a.length - 1) {
3761
+ n += ', ';
3762
+ }
3763
+ m += n;
3764
+ }
3765
+ o.push(m + '<br>*/</pre>');
3766
+ }
3767
+ o.push('</div>');
3768
+ }
3769
+ return o.join('');
3770
+ };
3771
+
3772
+ return itself;
3773
+
3774
+ }();