Reusable Accessible Mapping Platform

API Docs for: 5.3.1
Show:

File: src/js/RAMP/bootstrapper.js

  1. /*global require, window, dojoConfig, i18n, document, $, console, RAMP */
  2.  
  3. /**
  4. * Ramp module
  5. *
  6. * @module RAMP
  7. * @main RAMP
  8. */
  9.  
  10. /**
  11. * Bootstrapper class.
  12. * Starting point of RAMP, RAMP modules are loaded here and mapped to a function parameter
  13. * Phase X?: For mobile support, there can be a different mobileBootstrapper with only the mobile modules loaded
  14. *
  15. * ####Imports RAMP Modules:
  16. * {{#crossLink "Map"}}{{/crossLink}}
  17. * {{#crossLink "BaseMapSelector"}}{{/crossLink}}
  18. * {{#crossLink "Maptips"}}{{/crossLink}}
  19. * {{#crossLink "Datagrid"}}{{/crossLink}}
  20. * {{#crossLink "Navigation"}}{{/crossLink}}
  21. * {{#crossLink "FilterManager"}}{{/crossLink}}
  22. * {{#crossLink "BookmarkLink"}}{{/crossLink}}
  23. * {{#crossLink "Url"}}{{/crossLink}}
  24. * {{#crossLink "FeatureHighlighter"}}{{/crossLink}}
  25. * {{#crossLink "RAMP"}}{{/crossLink}}
  26. * {{#crossLink "GlobalStorage"}}{{/crossLink}}
  27. * {{#crossLink "GUI"}}{{/crossLink}}
  28. * {{#crossLink "EventManager"}}{{/crossLink}}
  29. * {{#crossLink "AdvancedToolbar"}}{{/crossLink}}
  30. * {{#crossLink "Util"}}{{/crossLink}}
  31. * {{#crossLink "Prototype"}}{{/crossLink}}
  32. * {{#crossLink "FunctionMangler"}}{{/crossLink}}
  33. * {{#crossLink "LayerLoader"}}{{/crossLink}}
  34. *
  35. * @class Bootstrapper
  36. * @static
  37. *
  38. * @uses dojo/parser
  39. * @uses dojo/on
  40. * @uses dojo/topic
  41. * @uses dojo/request/script
  42. * @uses dojo/request/xhr
  43. */
  44.  
  45. require([
  46. /* Dojo */
  47. "dojo/parser", "dojo/on", "dojo/topic", "dojo/request/script", "dojo/request/xhr",
  48. "esri/config", "esri/urlUtils",
  49.  
  50. /* RAMP */
  51. "ramp/map", "ramp/basemapSelector", "ramp/maptips", "ramp/datagrid",
  52. "ramp/navigation", "ramp/filterManager", "ramp/imageExport", "ramp/bookmarkLink",
  53. "utils/url", "ramp/featureHighlighter",
  54. "ramp/ramp", "ramp/globalStorage", "ramp/gui", "ramp/eventManager",
  55. "ramp/advancedToolbar", "ramp/geoSearch",
  56. "ramp/theme", "ramp/layerLoader", "ramp/dataLoaderGui", "ramp/dataLoader", "ramp/stepItem",
  57. /* Utils */
  58. "utils/util",
  59.  
  60. /* Plugins */
  61. "utils/prototype!", "utils/functionMangler!", "dojo/domReady!"],
  62.  
  63. function (
  64. /* Dojo */
  65. parser, dojoOn, topic, requestScript, xhr,
  66. esriConfig, esriUrlUtils,
  67.  
  68. /* RAMP */
  69. RampMap, BasemapSelector, Maptips, Datagrid, NavWidget, FilterManager, ImageExport,
  70. BookmarkLink, Url, FeatureHighlighter,
  71. Ramp, GlobalStorage, gui, EventManager, AdvancedToolbar, GeoSearch,
  72. theme, LayerLoader, DataLoadedGui, DataLoader, StepItem,
  73.  
  74. /* Utils */
  75. UtilMisc
  76. ) {
  77. "use strict";
  78.  
  79. /**
  80. * loadPlugin takes a plugin file and loads it into the DOM.
  81. * Creates a dynamic script tag to load the script at runtime.
  82. *
  83. * @method loadPlugin
  84. * @private
  85. * @param {String} pluginName, the file name of the plugin to be loaded (should be in the plugins folder)
  86. */
  87. function loadPlugin(pluginName) {
  88. var head = document.getElementsByTagName('head')[0],
  89. script = document.createElement('script');
  90. script.type = 'text/javascript';
  91. script.src = dojoConfig.fullPluginPath + pluginName;
  92. console.log('loading plugin: ' + script.src);
  93. head.appendChild(script);
  94. }
  95.  
  96. function initializeMap() {
  97. /* Start - RAMP Events, after map is loaded */
  98.  
  99. // this split exists solely to separate out the parts that IE9 is
  100. // bad at handling there is a DOM race condition somewhere in here,
  101. // we've given up on trying to find it
  102. function guiInits() {
  103. //initialize the filter
  104. FilterManager.init();
  105.  
  106. // Initialize the advanced toolbar and tools.
  107. if (RAMP.config.advancedToolbar.enabled) {
  108. AdvancedToolbar.init();
  109. }
  110.  
  111. Datagrid.init();
  112. theme.tooltipster();
  113.  
  114. //start loading the layers
  115. RAMP.startupLayers.forEach(function (layer) {
  116. LayerLoader.loadLayer(layer);
  117. });
  118. }
  119.  
  120. topic.subscribe(EventManager.Map.INITIAL_BASEMAP_LOADED, function () {
  121. console.log("map - >> first update-end; init the rest");
  122.  
  123. // Only initialize the bookmark link after all the UI events of all other modules have
  124. // finished loading
  125. // IMPORTANT: for now, only basemapselector and filtermanager have a UI complete event
  126. // but in the future, if other modules start publishing their own UI complete events, it needs
  127. // to be subscribe to here so BookmarkLink will not attempt to call the module before its GUI
  128. // has finished rendering
  129. UtilMisc.subscribeAll(
  130. [
  131. EventManager.BasemapSelector.UI_COMPLETE,
  132. EventManager.FilterManager.UI_COMPLETE
  133. ], function () {
  134. BookmarkLink.subscribeAndUpdate();
  135.  
  136. //initialize the map export after everything is done
  137. ImageExport.init();
  138.  
  139. DataLoadedGui.init();
  140. //RampMap.zoomToLayerScale();
  141. });
  142. // Added current level so slider will know how to adjust the position
  143. var currentLevel = (RampMap.getMap().__LOD.level) ? RampMap.getMap().__LOD.level : 0;
  144.  
  145. NavWidget.init(currentLevel);
  146. FeatureHighlighter.init();
  147.  
  148. Maptips.init();
  149.  
  150. //Apply listeners for basemap gallery
  151. BasemapSelector.init();
  152.  
  153. if (RAMP.flags.brokenWebBrowser || RAMP.flags.ie10client) {
  154. console.log('delaying for IE9 and IE10 to catch up with the group');
  155. window.setTimeout(guiInits, 2000);
  156. } else {
  157. guiInits();
  158. }
  159.  
  160. });
  161.  
  162. RampMap.init();
  163. NavWidget.construct();
  164.  
  165. // a workaround for bug#3460; ideally each module's ui component would call tooltipster on its own; probably a good idea would to implement this when working on mobile view
  166. theme.tooltipster();
  167.  
  168. /* End - RAMP Events */
  169. }
  170. /* End - Bootstrapper functions */
  171.  
  172. // Check to make sure the console exists, redefines it to the no-op function
  173. // if it does not (e.g. in IE when the debugger is not on)
  174. UtilMisc.checkConsole();
  175.  
  176. // Once all of our modules are loaded and the DOM is ready:
  177.  
  178. // call the parser to create the dijit layout dijits
  179. parser.parse();
  180.  
  181. //To hold values from RAMP service
  182.  
  183. var lang = $("html").attr("lang"),
  184. configFile,
  185. defJson;
  186.  
  187. if (lang !== "en" && lang !== "fr") {
  188. lang = "en";
  189. }
  190.  
  191. RAMP.locale = lang;
  192.  
  193. i18n.init(
  194. {
  195. lng: lang + "-CA",
  196. load: "current",
  197. fallbackLng: false
  198. });
  199.  
  200. //loading config object from JSON file
  201. configFile = (lang === "fr") ? "config.fr.json" : "config.en.json";
  202.  
  203. // Request the JSON config file
  204. defJson = xhr(configFile, {
  205. handleAs: "json"
  206. });
  207.  
  208. defJson.then(
  209. function (fileConfig) {
  210. //there is no need to convert the result to an object. it comes through pre-parsed
  211. if (!RAMP.configServiceURL) {
  212. //no config service. we just use the file provided
  213. configReady(fileConfig);
  214. } else {
  215. //get additional config stuff from the config service. mash it into our primary object
  216.  
  217. // pull smallkeys from URL
  218. var siteURL = new Url(require.toUrl(document.location)),
  219. smallkeys = siteURL.queryObject.keys;
  220.  
  221. if (!smallkeys || smallkeys === "") {
  222. //no keys. no point hitting the service. jump to next step
  223. configReady(fileConfig);
  224. } else {
  225. //TODO verify endpoint is correct
  226. var serviceUrl = RAMP.configServiceURL + "docs/" + $("html").attr("lang") + "/" + smallkeys,
  227. defService = requestScript.get(serviceUrl, { jsonp: 'callback', timeout: 5000 });
  228.  
  229. //Request the JSON snippets from the RAMP Config Service
  230.  
  231. //NOTE: XHR cannot be used here for cross domain purposes (primarily when running thru visual studio).
  232. // we use request/script instead to get the config as jsonp
  233. // we may consider looking into ways to mitiate the cross domain issue (Aly had some ideas)
  234.  
  235. defService.then(
  236. function (serviceContent) {
  237. console.log(serviceContent);
  238.  
  239. //we are expecting an array of JSON config fragments
  240. //merge each fragment into the file config
  241.  
  242. serviceContent.forEach(function (configFragment) {
  243. UtilMisc.mergeRecursive(fileConfig, configFragment);
  244. });
  245.  
  246. //fragments are now in fileConfig. carry on.
  247. configReady(fileConfig);
  248. },
  249. function (error) {
  250. console.log("An error occurred: " + error);
  251. }
  252. );
  253. }
  254. }
  255. },
  256. function (error) {
  257. console.log("An error occurred when retrieving the JSON Config: " + error);
  258. }
  259. );
  260.  
  261. /**
  262. * once the config file has been retrieved, proceed with the loading of the site
  263. *
  264. * @method configReady
  265. * @private
  266. * @param {Object} configObject the configuration object
  267. */
  268. function configReady(configObject) {
  269. var pluginConfig,
  270. advancedToolbarToggle = $("li.map-toolbar-item #advanced-toggle").parent(),
  271. brokenWebBrowser = document.getElementsByTagName('html')[0].className.indexOf('dj_ie9') > -1,
  272. annoyingWebBrowser = document.getElementsByTagName('html')[0].className.indexOf('dj_ie10') > -1;
  273.  
  274. console.log("Bootstrapper: config loaded");
  275.  
  276. GlobalStorage.init(configObject);
  277. GlobalStorage.defineProjections(window.proj4);
  278. GeoSearch.init();
  279.  
  280. esriConfig.defaults.io.proxyUrl = RAMP.config.proxyUrl;
  281. // try to avoid the proxy if possible, but this will cause network errors if CORS is not allowed by the target server
  282. esriConfig.defaults.io.corsDetection = !brokenWebBrowser;
  283. // really IE9??? (╯°□°)╯︵ ┻━┻
  284. if (brokenWebBrowser && RAMP.config.exportProxyUrl !== undefined) {
  285. esriUrlUtils.addProxyRule({ proxyUrl: RAMP.config.exportProxyUrl, urlPrefix: RAMP.config.exportMapUrl });
  286. }
  287. RAMP.flags.brokenWebBrowser = brokenWebBrowser;
  288. RAMP.flags.ie10client = annoyingWebBrowser;
  289.  
  290. // Show or remove advanced toolbar toggle based on the config value
  291. if (RAMP.config.advancedToolbar.enabled) {
  292. advancedToolbarToggle.removeClass("wb-invisible");
  293. } else {
  294. advancedToolbarToggle.remove();
  295. }
  296.  
  297. pluginConfig = RAMP.config.plugins;
  298. if (pluginConfig) {
  299. pluginConfig.map(function (pName) { loadPlugin(pName); });
  300. }
  301.  
  302. // apply defaulting of extents (must be done prior to bookmark link updates)
  303. RampMap.applyExtentDefaulting();
  304.  
  305. // Modify the config based on the url
  306. // needs to do this before the gui loads because the gui module
  307. // also reads from the config
  308. BookmarkLink.updateConfig(window.location.pathname.split("/").last());
  309.  
  310. //other initilizations must wait until our extents have been projected to our active basemap
  311. topic.subscribe(EventManager.Map.EXTENTS_REPROJECTED, function () {
  312. // Initialize the map only after the gui loads
  313. // if we do it beforehand, the map extent may get messed up since
  314. // the available screen size may still be changing (e.g. due to fullscreen
  315. // or subpanel closing)
  316. topic.subscribe(EventManager.GUI.UPDATE_COMPLETE, function () {
  317. // Create the panel that the bookmark link sits in
  318. // can only do this after the gui loads
  319. BookmarkLink.createUI();
  320.  
  321. LayerLoader.init();
  322. initializeMap();
  323. });
  324.  
  325. gui.load(null, null, function () { });
  326. Ramp.loadStrings();
  327. });
  328.  
  329. //project extents to basemap
  330. RampMap.projectConfigExtents();
  331. }
  332. });
  333.