index.html 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="apple-mobile-web-app-capable" content="yes" />
  6. <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
  7. <meta name="theme-color" content="#4b75ff">
  8. <link rel="stylesheet" href="../script/semantic/semantic.min.css">
  9. <script src="../script/jquery.min.js"></script>
  10. <script src="../script/ao_module.js"></script>
  11. <script src="../script/semantic/semantic.min.js"></script>
  12. <link rel="manifest" crossorigin="use-credentials" href="manifest.json">
  13. <title>Browser</title>
  14. <style>
  15. body{
  16. overflow: hidden;
  17. }
  18. #urlbar{
  19. padding-top: 0.2em;
  20. padding-bottom: 0.2em;
  21. padding-left: 1.2em;
  22. padding-right: 0.3em;
  23. line-height: 1em;
  24. }
  25. .menuitem{
  26. margin-top: 0.2em;
  27. padding:0.2em !important;
  28. border: 0px !important;
  29. }
  30. .menuitem button{
  31. background-color: white !important;
  32. }
  33. .rightMenuItem{
  34. margin-top: 0.3em;
  35. padding:0.1em !important;
  36. border: 0px !important;
  37. }
  38. .rightMenuItem button{
  39. background-color: white !important;
  40. }
  41. #starBtn{
  42. padding-right: 0.9em;
  43. cursor: pointer !important;
  44. background-color: white !important;
  45. }
  46. #starBtn:hover{
  47. opacity: 0.7;
  48. }
  49. #xframe{
  50. width: 100%;
  51. height: calc(100% - 43px);
  52. border: 0px solid transparent;
  53. }
  54. #notvdiWarning{
  55. position: fixed;
  56. bottom: 0px;
  57. left: 0px;
  58. width: 100%;
  59. padding: 0.4em;
  60. display: none;
  61. }
  62. </style>
  63. </head>
  64. <body>
  65. <div class="ui top small attached menu" style="background-color: #eceef2; padding-left: 12px; padding-right: 12px;">
  66. <div class="ui menuitem">
  67. <button class="ui circular tiny icon button" onclick="undoPage();">
  68. <i class="arrow left icon"></i>
  69. </button>
  70. </div>
  71. <div class="ui menuitem">
  72. <button class="ui circular tiny icon button" onclick="redoPage();">
  73. <i class="arrow right icon"></i>
  74. </button>
  75. </div>
  76. <div class="ui menuitem">
  77. <button class="ui circular tiny icon button" onclick="refreshPage();">
  78. <i class="green refresh icon"></i>
  79. </button>
  80. </div>
  81. <div id="urlbar" class="ui tiny action fluid input">
  82. <input id="urlText" type="text" value="about:blank" onkeydown="handleURLKeydown(event);">
  83. <button id="starBtn" class="ui icon basic circular tiny button">
  84. <i class="star icon"></i>
  85. </button>
  86. </div>
  87. <div class="right menu">
  88. <div class="ui rightMenuItem">
  89. <button class="ui tiny icon button">
  90. <i class="blue bookmark icon"></i>
  91. </button>
  92. </div>
  93. <div class="ui rightMenuItem">
  94. <button class="ui tiny icon button" onclick="loadWebsite('about:blank');">
  95. <i class="home icon"></i>
  96. </button>
  97. </div>
  98. <div class="ui rightMenuItem">
  99. <button class="ui tiny icon button">
  100. <i class="grey download icon"></i>
  101. </button>
  102. </div>
  103. </div>
  104. </div>
  105. <iframe id="xframe" src="./blank.html" allow="fullscreen" referrerpolicy="no-referrer">
  106. </iframe>
  107. <div id="notvdiWarning">
  108. <div class="ui yellow message">
  109. <i class="close icon"></i>
  110. <div class="header">
  111. <i class="remove icon"></i>Not Recommended Way of Usage
  112. </div>
  113. <p>Please use your native browser windows instead of this iframe browser for maximum website compatibility.</p>
  114. </div>
  115. </div>
  116. <script>
  117. let historyStack = [];
  118. let historyPopStack = [];
  119. let currentURL = "about:blank";
  120. //Check if currently under vdi mode
  121. if (ao_module_virtualDesktop == false){
  122. $("#notvdiWarning").show();
  123. }
  124. $('.message .close').on('click', function() {
  125. $(this).closest('.message').transition('fade');
  126. });
  127. //Perform window resize element size calculation
  128. $(window).on("resize", function(){
  129. updateResizeElements();
  130. });
  131. function updateResizeElements(){
  132. let buttonWidths = 0;
  133. $(".menuitem").each(function(){
  134. buttonWidths+= $(this).width();
  135. });
  136. let urlbarWidth = window.innerWidth - buttonWidths - 20;
  137. $("#urlbar").css("width", urlbarWidth + "px");
  138. }
  139. updateResizeElements();
  140. function handleURLKeydown(e){
  141. if (e.keyCode == 13){
  142. let url = $("#urlText").val();
  143. loadWebsite(url);
  144. }
  145. }
  146. function refreshPage(){
  147. loadWebsite(currentURL);
  148. }
  149. function undoPage(){
  150. //Push current page into the history pop stack
  151. if (historyStack.length == 0){
  152. return;
  153. }
  154. let currentBackupURL = currentURL;
  155. historyPopStack.push(currentBackupURL);
  156. let targetReturnURL = historyStack.pop();
  157. loadWebsite(targetReturnURL, false);
  158. }
  159. function redoPage(){
  160. if (historyPopStack.length == 0){
  161. return;
  162. }
  163. restorePage = historyPopStack.pop();
  164. historyStack.push(currentURL);
  165. loadWebsite(restorePage, false);
  166. }
  167. function loadWebsite(targetURL, writeRestoreRecord = true){
  168. if (writeRestoreRecord && currentURL != targetURL){
  169. historyPopStack = [];
  170. }
  171. //Handle special case
  172. if (targetURL == "about:blank"){
  173. $("#xframe").attr("src", "blank.html");
  174. $("#urlText").val(targetURL);
  175. if (writeRestoreRecord && currentURL != targetURL){
  176. historyStack.push(JSON.parse(JSON.stringify(currentURL)));
  177. }
  178. currentURL = targetURL;
  179. return;
  180. }
  181. //Filter the URL if required
  182. if (targetURL.substr(0,4) != "http"){
  183. if (location.protocol !== "https:"){
  184. //This page is currently loaded in http mode. Add http:// to it
  185. targetURL = "http://" + targetURL;
  186. }else{
  187. targetURL = "https://" + targetURL;
  188. }
  189. }
  190. $("#urlText").val(targetURL);
  191. if (writeRestoreRecord && currentURL != targetURL){
  192. historyStack.push(JSON.parse(JSON.stringify(currentURL)));
  193. }
  194. currentURL = targetURL;
  195. //Check if the website allow iframe
  196. checkIfAllowIframing(targetURL, function(allowIframe, redirectTarget){
  197. if (allowIframe == null){
  198. $("#xframe").attr("src", "notfound.html#" + targetURL);
  199. }else{
  200. if (allowIframe == true){
  201. $("#xframe").removeAttr("srcdoc");
  202. $("#xframe").attr("src", targetURL);
  203. }else{
  204. proxyWebContent(targetURL, function(content){
  205. $("#xframe").attr("src", "");
  206. $("#xframe").attr("srcdoc", content);
  207. });
  208. //alert("Target website do not allow embedding");
  209. }
  210. if (redirectTarget != undefined && redirectTarget != ""){
  211. $("#urlText").val(redirectTarget);
  212. }
  213. }
  214. });
  215. }
  216. function proxyWebContent(url, callback){
  217. ao_module_agirun("Browser/functions/proxy.js", {
  218. url: url,
  219. }, function(data){
  220. callback(data);
  221. });
  222. }
  223. //Check if a website can be directly embedded as iframe, can return true / false /null (site not exists)
  224. function checkIfAllowIframing(url, callback){
  225. ao_module_agirun("Browser/functions/getHeader.js", {
  226. url: url
  227. }, function(data){
  228. let xFrameOptions = JSON.parse(data);
  229. let header = xFrameOptions.header.toLowerCase().trim();
  230. let location = xFrameOptions.location;
  231. if (header == "null"){
  232. //Site not exists
  233. callback(null);
  234. }
  235. if (xFrameOptions.header == "sameorigin" || xFrameOptions.header == "deny"){
  236. //This webpage do not allow iframeing
  237. callback(false, location);
  238. }else{
  239. //This webpage allow iframing. Show it
  240. callback(true, location);
  241. }
  242. }, undefined, 5000)
  243. }
  244. </script>
  245. </body>
  246. </html>