WebView.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. "atomic component";
  2. // TODO: expose to inspector
  3. var WIDTH = Atomic.graphics.width - 100;
  4. var HEIGHT = Atomic.graphics.height - 100;
  5. var home = "http://www.atomicgameengine.com";
  6. var bookmarks = {
  7. "Atomic": "http://www.atomicgameengine.com",
  8. "Google": "http://www.google.com",
  9. "YouTube": "https://www.youtube.com",
  10. "Steam": "https://store.steampowered.com",
  11. "Reddit": "https://www.reddit.com/r/gamedev",
  12. "Penny Arcade": "https://www.penny-arcade.com/",
  13. "Local Example": "atomic://Resources/WebClient/LocalPage.html"
  14. };
  15. // Create the UI view
  16. var view = new Atomic.UIView();
  17. // enable to get debug window
  18. // Atomic.UI.debugShowSettingsWindow(view);
  19. var newTabButton;
  20. var newTabContent;
  21. // WebBrowser example component
  22. exports.component = function(self) {
  23. var window = new Atomic.UIWindow();
  24. window.text = "UIWebView Browser Example";
  25. window.setSize(WIDTH, HEIGHT);
  26. var mainLayout = new Atomic.UILayout();
  27. mainLayout.axis = Atomic.UI_AXIS.UI_AXIS_Y;
  28. mainLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION.UI_LAYOUT_DISTRIBUTION_GRAVITY;
  29. mainLayout.gravity = Atomic.UI_GRAVITY.UI_GRAVITY_ALL;
  30. var tabContainer = new Atomic.UITabContainer();
  31. tabContainer.gravity = Atomic.UI_GRAVITY.UI_GRAVITY_ALL;
  32. newTabButton = new Atomic.UIButton();
  33. newTabButton.text = " ";
  34. newTabButton.onClick = function() {
  35. createBrowserTab(tabContainer, home);
  36. // set the current page to the created page (ignoring the new tab dummy page)
  37. tabContainer.currentPage = tabContainer.numPages - 2;
  38. return true;
  39. };
  40. newTabContent = new Atomic.UIWidget();
  41. tabContainer.tabLayout.addChild(newTabButton);
  42. tabContainer.contentRoot.addChild(newTabContent);
  43. // change id, so we don't initiate a page change when clicked
  44. newTabButton.id = "NewTabButton";
  45. // create a startup with our home address
  46. createBrowserTab(tabContainer, home);
  47. tabContainer.currentPage = 0;
  48. // Add to main UI view and center
  49. mainLayout.addChild(tabContainer);
  50. window.addChild(mainLayout);
  51. view.addChild(window);
  52. window.center();
  53. };
  54. function createBookmarks(webView, layout, bookmarks) {
  55. for (var text in bookmarks) {
  56. var button = new Atomic.UIButton();
  57. button.text = text;
  58. button.skinBg = "TBButton.flat";
  59. // button layout and font desc
  60. var buttonLP = new Atomic.UILayoutParams();
  61. buttonLP.width = 120,
  62. buttonLP.height = 18;
  63. button.layoutParams = buttonLP;
  64. var fontDesc = new Atomic.UIFontDescription();
  65. fontDesc.size = 11;
  66. fontDesc.id = "Vera";
  67. button.fontDescription = fontDesc;
  68. layout.addChild(button);
  69. var webClient = webView.webClient;
  70. (function() {
  71. var url = bookmarks[text];
  72. button.onClick = function() { webClient.loadURL(url); };
  73. })();
  74. }
  75. }
  76. function createBrowserTab(tabContainer, url) {
  77. var contentRoot = tabContainer.contentRoot;
  78. var tabLayout = tabContainer.tabLayout;
  79. var layout = new Atomic.UILayout();
  80. layout.axis = Atomic.UI_AXIS_Y;
  81. layout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION.UI_LAYOUT_DISTRIBUTION_GRAVITY;
  82. layout.gravity = Atomic.UI_GRAVITY.UI_GRAVITY_ALL;
  83. layout.spacing = 8;
  84. var tabButton = new Atomic.UIButton();
  85. tabButton.text = "Loading...";
  86. // button layout and font desc
  87. var buttonLP = new Atomic.UILayoutParams();
  88. buttonLP.width = 160,
  89. buttonLP.height = 32;
  90. tabButton.layoutParams = buttonLP;
  91. var fontDesc = new Atomic.UIFontDescription();
  92. fontDesc.size = 11;
  93. fontDesc.id = "Vera";
  94. tabButton.fontDescription = fontDesc;
  95. // tabButtons with URL text by default open the URL upon clicking them
  96. // we don't want this behaviour
  97. tabButton.urlEnabled = false;
  98. tabLayout.addChildBefore(tabButton, newTabButton);
  99. // address bar
  100. var addressLayout = new Atomic.UILayout();
  101. addressLayout.gravity = Atomic.UI_GRAVITY.UI_GRAVITY_ALL;
  102. addressLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION.UI_LAYOUT_DISTRIBUTION_GRAVITY;
  103. // navigation buttons
  104. var backButton = new Atomic.UIButton();
  105. backButton.text = "Back";
  106. addressLayout.addChild(backButton);
  107. var fwdButton = new Atomic.UIButton();
  108. fwdButton.text = "Forward";
  109. addressLayout.addChild(fwdButton);
  110. var reloadButton = new Atomic.UIButton();
  111. reloadButton.text = "Reload";
  112. addressLayout.addChild(reloadButton);
  113. var homeButton = new Atomic.UIButton();
  114. homeButton.text = "Home";
  115. addressLayout.addChild(homeButton);
  116. var addressEdit = new Atomic.UIEditField();
  117. addressEdit.gravity = Atomic.UI_GRAVITY.UI_GRAVITY_ALL;
  118. addressLayout.addChild(addressEdit);
  119. layout.addChild(addressLayout);
  120. var webView = new WebView.UIWebView(url);
  121. webView.gravity = Atomic.UI_GRAVITY.UI_GRAVITY_ALL;
  122. var webClient = webView.webClient;
  123. // bookmark bar
  124. var bookmarkLayout = new Atomic.UILayout();
  125. bookmarkLayout.gravity = Atomic.UI_GRAVITY.UI_GRAVITY_ALL;
  126. createBookmarks( webView, bookmarkLayout, bookmarks);
  127. layout.addChild(bookmarkLayout);
  128. layout.addChild(webView);
  129. contentRoot.addChildBefore(layout, newTabContent);
  130. // initial state
  131. reloadButton.disable();
  132. backButton.disable();
  133. fwdButton.disable();
  134. // go home
  135. homeButton.onClick = function() { webClient.loadURL(home);};
  136. // reload
  137. reloadButton.onClick = function() { webClient.reload(); };
  138. // Forward/Back
  139. fwdButton.onClick = function() { webClient.goForward(); };
  140. backButton.onClick = function() { webClient.goBack(); };
  141. // events
  142. // update the addressEdit at start and stop of url load
  143. webView.subscribeToEvent(webClient, WebView.WebViewLoadStateChangeEvent(function(ev) {
  144. ev.canGoBack ? backButton.enable() : backButton.disable();
  145. ev.canGoForward ? fwdButton.enable() : fwdButton.disable();
  146. }));
  147. // update the addressEdit at start and stop of url load
  148. webView.subscribeToEvent(webClient, WebView.WebViewAddressChangeEvent(function(ev) {
  149. // we can now reload
  150. reloadButton.enable();
  151. addressEdit.text = ev.url;
  152. }));
  153. webView.subscribeToEvent(webClient, WebView.WebViewTitleChangeEvent(function(ev) {
  154. tabButton.text = ev.title;
  155. }));
  156. webView.subscribeToEvent(webClient, WebView.WebViewPopupRequestEvent(function(ev) {
  157. webClient.loadURL(ev.url);
  158. }));
  159. //this.subscribeToEvent(this.countEditField, "UIWidgetEditComplete", (ev) => this.handleUIWidgetEditCompleteEvent(ev));
  160. webView.subscribeToEvent(addressEdit, Atomic.UIWidgetEditCompleteEvent(function(ev) {
  161. var url = addressEdit.text;
  162. url = url.replace(" ", "%20");
  163. if (url.indexOf(".") == -1) {
  164. url = "http://www.google.com/search?q=" + url;
  165. }
  166. if (url.indexOf("://") == -1) {
  167. url = "https://" + url;
  168. }
  169. if (!url.length)
  170. return;
  171. webClient.loadURL(url);
  172. }));
  173. /////////////////////////////////////////////////////
  174. // HANDLE CUSTOM MESSAGES COMING IN FROM LOCAL PAGE
  175. var messageHandler = new WebView.WebMessageHandler();
  176. webClient.addMessageHandler(messageHandler);
  177. webView.subscribeToEvent(messageHandler, WebView.WebMessageEvent(function (webMessage) {
  178. var messageType;
  179. var messageObject;
  180. try {
  181. messageObject = JSON.parse(webMessage.request);
  182. messageType = messageObject.message;
  183. } catch (e) {
  184. // not JSON, we are just getting a notification message of some sort
  185. messageType = webMessage.request;
  186. }
  187. switch (messageType) {
  188. // notification sent up from the web view client
  189. case "CUSTOM_NOTIFICATION":
  190. new Atomic.UIMessageWindow(view, "modal_error").show("Message from WebView", "Click Count: " + messageObject.clickCount, Atomic.UI_MESSAGEWINDOW_SETTINGS.UI_MESSAGEWINDOW_SETTINGS_OK, true, 480, 240);
  191. webMessage.handler.success();
  192. break;
  193. // web view client is asking for something
  194. case "GET_FROM_HOST":
  195. // Got a prefix from the client, let's respond
  196. webMessage.handler.success(JSON.stringify({
  197. displayMessage: messageObject.prefix + "-ro-dah"
  198. }));
  199. break;
  200. // web view client wants us to do some processing and call back to a specific function
  201. case "CALLBACK_FUNCTION":
  202. // mimic some kind of event loop and process on the next update event inside a closure
  203. var msgloop = new Atomic.ScriptObject();
  204. // cache the web client that called us since it will get GC'd
  205. var webClient = webMessage.handler.webClient;
  206. msgloop.subscribeToEvent(Atomic.UpdateEvent(function () {
  207. msgloop.unsubscribeFromAllEvents();
  208. webClient.executeJavaScript(messageObject.callbackFunction + "('Called from host');");
  209. }));
  210. webMessage.handler.success();
  211. break;
  212. }
  213. }));
  214. }