瀏覽代碼

Added wip browser

Toby Chui 3 年之前
父節點
當前提交
9e7a289159

+ 46 - 0
web/Browser/blank.html

@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="UTF-8">
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
+		<meta name="theme-color" content="#4b75ff">
+		<link rel="stylesheet" href="../script/semantic/semantic.min.css">
+		<script src="../script/jquery.min.js"></script>
+		<script src="../script/ao_module.js"></script>
+		<script src="../script/semantic/semantic.min.js"></script>
+		
+		<link rel="manifest" crossorigin="use-credentials" href="manifest.json">
+		<title>about:blank</title>
+		<style>
+
+        </style>
+    </head>
+    <body>
+        <br>
+        <div class="ui container">
+            <div class="main">
+                <h1 class="ui header">
+                    <img class="ui image" src="img/desktop_icon.png">
+                    <div class="content">
+                        about:blank
+                    </div>
+                </h1>
+                <div class="ui divider"></div>
+                <h3>ArozOS Browser</h3>
+                <p>Technically this is not a browser but an iframe. Not all websites work inside an iframe due to CORS policy. <br>
+                    <b>Use with your own risk</b></p>
+                <p>Here are some partially working websites for getting started: </p>
+                <div class="ui bulleted list" style="max-width: 200px;">
+                    <a class="item" onclick="parent.loadWebsite('www.google.com/search?igu=1');">google.com</a>
+                    <a class="item" onclick="parent.loadWebsite('bing.com');">bing.com</a>
+                    <a class="item" onclick="parent.loadWebsite('wikipedia.org');">wikipedia.org</a>
+                </div>
+
+                <img class="ui tiny image" style="cursor: pointer;" onclick="parent.loadWebsite('arozos.com');" src="img/logo.png">
+            </div>
+        </div>
+       
+
+    </body>
+</html>

+ 0 - 0
web/Browser/canvas.html


+ 11 - 0
web/Browser/functions/getHeader.js

@@ -0,0 +1,11 @@
+/*
+    getHeader.js
+    Get Header of the target website and return it as JSON
+*/
+requirelib("http");
+if (url == "" || typeof(url) == "undefined"){
+    sendResp(JSON.stringify(""));
+}else{
+    var header = http.head(url, "x-frame-options"); 
+    sendResp(header);
+}

+ 13 - 0
web/Browser/functions/proxy.js

@@ -0,0 +1,13 @@
+/*
+    proxy.js
+    This script help proxy text content of the requested page and render them locally
+*/
+
+//Get the target webpage body
+requirelib("http");
+var websiteContent = http.get(url);
+
+//replace the relative path files with absolutes
+websiteContent = websiteContent.split('src="/').join('src="' + url + '/');
+websiteContent = websiteContent.split('href="/').join('href="' + url + '/');
+sendResp(websiteContent);

二進制
web/Browser/img/desktop_icon.png


二進制
web/Browser/img/desktop_icon.psd


二進制
web/Browser/img/logo.png


二進制
web/Browser/img/module_icon.png


二進制
web/Browser/img/module_icon.psd


二進制
web/Browser/img/small_icon.png


二進制
web/Browser/img/small_icon.psd


+ 272 - 0
web/Browser/index.html

@@ -0,0 +1,272 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="UTF-8">
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
+		<meta name="theme-color" content="#4b75ff">
+		<link rel="stylesheet" href="../script/semantic/semantic.min.css">
+		<script src="../script/jquery.min.js"></script>
+		<script src="../script/ao_module.js"></script>
+		<script src="../script/semantic/semantic.min.js"></script>
+		
+		<link rel="manifest" crossorigin="use-credentials" href="manifest.json">
+		<title>Browser</title>
+		<style>
+			body{
+				overflow: hidden;
+			}
+			#urlbar{
+				padding-top: 0.2em;
+				padding-bottom: 0.2em;
+				padding-left: 1.2em;
+				padding-right: 0.3em;
+				line-height: 1em;
+			}
+
+			.menuitem{
+				margin-top: 0.2em;
+				padding:0.2em !important;
+				border: 0px !important;
+			}
+
+			.menuitem button{
+				background-color: white !important;
+			}
+
+			.rightMenuItem{
+				margin-top: 0.3em;
+				padding:0.1em !important;
+				border: 0px !important;
+			}
+
+			.rightMenuItem button{
+				background-color: white !important;
+			}
+
+			#starBtn{
+				padding-right: 0.9em;
+				cursor: pointer !important;
+				background-color: white !important;
+			}
+
+			#starBtn:hover{
+				opacity: 0.7;
+			}
+
+			#xframe{
+				width: 100%;
+				height: calc(100% - 43px);
+				border: 0px solid transparent;
+			}
+
+			#notvdiWarning{
+				position: fixed;
+				bottom: 0px;
+				left: 0px;
+				width: 100%;
+				padding: 0.4em;
+				display: none;
+			}
+		</style>
+	</head>
+	<body>
+		<div class="ui top small attached menu" style="background-color: #eceef2; padding-left: 12px; padding-right: 12px;">
+			<div class="ui menuitem">
+				<button class="ui circular tiny icon button" onclick="undoPage();">
+					<i class="arrow left icon"></i>
+				</button>
+			</div>
+			<div class="ui menuitem">
+				<button class="ui circular tiny icon button" onclick="redoPage();">
+					<i class="arrow right icon"></i>
+				</button>
+			</div>
+			<div class="ui menuitem">
+				<button class="ui circular tiny icon button" onclick="refreshPage();">
+					<i class="green refresh icon"></i>
+				</button>
+			</div>
+			<div id="urlbar" class="ui tiny action fluid input">
+				<input id="urlText" type="text" value="about:blank" onkeydown="handleURLKeydown(event);">
+				<button id="starBtn" class="ui icon basic circular tiny button">
+					<i class="star icon"></i>
+				</button>
+			</div>
+			<div class="right menu">
+				<div class="ui rightMenuItem">
+					<button class="ui tiny icon button">
+						<i class="blue bookmark icon"></i>
+					</button>
+				</div>
+				<div class="ui rightMenuItem">
+					<button class="ui tiny icon button" onclick="loadWebsite('about:blank');">
+						<i class="home icon"></i>
+					</button>
+				</div>
+				<div class="ui rightMenuItem">
+					<button class="ui tiny icon button">
+						<i class="grey download icon"></i>
+					</button>
+				</div>
+			</div>
+		  </div>
+		  <iframe id="xframe" src="./blank.html" allow="fullscreen" referrerpolicy="no-referrer">
+
+		  </iframe>
+		  <div id="notvdiWarning">
+			<div class="ui yellow message">
+				<i class="close icon"></i>
+				<div class="header">
+					<i class="remove icon"></i>Not Recommended Way of Usage
+				</div>
+				<p>Please use your native browser windows instead of this iframe browser for maximum website compatibility.</p>
+			</div>
+		  </div>
+		<script>
+			let historyStack = [];
+			let historyPopStack = [];
+			let currentURL = "about:blank";
+
+			//Check if currently under vdi mode
+			if (ao_module_virtualDesktop == false){
+				$("#notvdiWarning").show();
+			}
+
+			$('.message .close').on('click', function() {
+				$(this).closest('.message').transition('fade');
+			});
+
+
+			//Perform window resize element size calculation
+			$(window).on("resize", function(){
+				updateResizeElements();
+			});
+			function updateResizeElements(){
+				let buttonWidths = 0;
+				$(".menuitem").each(function(){
+					buttonWidths+= $(this).width();
+				});
+
+				let urlbarWidth = window.innerWidth - buttonWidths - 20;
+				$("#urlbar").css("width", urlbarWidth + "px");
+			}
+			updateResizeElements();
+
+
+			function handleURLKeydown(e){
+				if (e.keyCode == 13){
+					let url = $("#urlText").val();
+					loadWebsite(url);
+				}
+			}
+
+			function refreshPage(){
+				loadWebsite(currentURL);
+			}
+
+			function undoPage(){
+				//Push current page into the history pop stack
+				if (historyStack.length == 0){
+					return;
+				}
+				let currentBackupURL = currentURL;
+				historyPopStack.push(currentBackupURL);
+				let targetReturnURL = historyStack.pop();
+				loadWebsite(targetReturnURL, false);
+			}
+
+			function redoPage(){
+				if (historyPopStack.length == 0){
+					return;
+				}
+				restorePage = historyPopStack.pop();
+				historyStack.push(currentURL);
+				loadWebsite(restorePage, false);
+			}
+
+			function loadWebsite(targetURL, writeRestoreRecord = true){
+				if (writeRestoreRecord && currentURL != targetURL){
+					historyPopStack = [];
+				}
+				
+				//Handle special case
+				if (targetURL == "about:blank"){
+					$("#xframe").attr("src", "blank.html");
+					$("#urlText").val(targetURL);
+					if (writeRestoreRecord && currentURL != targetURL){
+						historyStack.push(JSON.parse(JSON.stringify(currentURL)));
+					}
+					currentURL = targetURL;
+					return;
+				}
+
+				//Filter the URL if required
+				if (targetURL.substr(0,4) != "http"){
+					if (location.protocol !== "https:"){
+						//This page is currently loaded in http mode. Add http:// to it
+						targetURL = "http://" + targetURL;
+					}else{
+						targetURL = "https://" + targetURL;
+					}
+				}
+
+				$("#urlText").val(targetURL);
+				if (writeRestoreRecord && currentURL != targetURL){
+					historyStack.push(JSON.parse(JSON.stringify(currentURL)));
+				}
+				currentURL = targetURL;
+				
+
+				//Check if the website allow iframe
+				checkIfAllowIframing(targetURL, function(allowIframe){
+					if (allowIframe == null){
+						$("#xframe").attr("src", "notfound.html#" + targetURL);
+					}else{
+						if (allowIframe == true){
+							$("#xframe").attr("src", targetURL);
+						}else{
+							proxyWebContent(targetURL, function(content){
+								$("#xframe").attr("src", "");
+								$("#xframe").attr("srcdoc", content)
+							
+							});
+							//alert("Target website do not allow embedding");
+						}
+					}
+				
+				});
+			}
+
+
+			function proxyWebContent(url, callback){
+				ao_module_agirun("Browser/functions/proxy.js", {
+					url: url,
+				}, function(data){
+					callback(data);
+				});
+			}
+
+			//Check if a website can be directly embedded as iframe, can return true / false /null (site not exists)
+			function checkIfAllowIframing(url, callback){
+				ao_module_agirun("Browser/functions/getHeader.js", {
+					url: url
+				}, function(data){
+					if (data == "null"){
+						//Site not exists
+						callback(null);
+					}
+					let xFrameOptions = JSON.parse(data).toLowerCase().trim();
+					
+					if (xFrameOptions == "sameorigin" || xFrameOptions == "deny"){
+						//This webpage do not allow iframeing
+						callback(false);
+					}else{
+						//This webpage allow iframing. Show it
+						callback(true);
+					}
+				}, undefined, 5000)
+			}
+		</script>
+	</body>
+</html>

+ 19 - 0
web/Browser/init.agi

@@ -0,0 +1,19 @@
+/*
+	Browser Bookmarking Module Register Script
+*/
+
+//Setup the module information
+var moduleLaunchInfo = {
+    Name: "Browser",
+	Desc: "A simple web browser like bookmarking app",
+	Group: "Office",
+	IconPath: "Browser/img/module_icon.png",
+	Version: "1.0",
+	StartDir: "Browser/index.html",
+	InitFWSize: [720, 480],
+	SupportedExt: []
+}
+
+
+//Register the module
+registerModule(JSON.stringify(moduleLaunchInfo));

+ 38 - 0
web/Browser/notfound.html

@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="UTF-8">
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
+		<meta name="theme-color" content="#4b75ff">
+		<link rel="stylesheet" href="../script/semantic/semantic.min.css">
+		<script src="../script/jquery.min.js"></script>
+		<script src="../script/ao_module.js"></script>
+		<script src="../script/semantic/semantic.min.js"></script>
+		
+		<link rel="manifest" crossorigin="use-credentials" href="manifest.json">
+		<title>Not Found</title>
+		<style>
+
+        </style>
+    </head>
+    <body>
+        <br>
+        <div class="ui container">
+            <div class="main">
+                <h1><i class="remove icon"></i>Website Not Found</h1>
+                <p>Unable to connect to <span id="targeturl"></span> </p>
+                <div class="ui divider"></div>
+                <h3>The URL you are requesting does not exists or not responding</h3>
+                <p>We cannot request any header from the URL endpoint given. Please try again later or return to <a style="cursor: pointer;" onclick="parent.loadWebsite('about:blank');">home page</a>.</p>
+
+                <img class="ui tiny image" style="cursor: pointer;" onclick="parent.loadWebsite('arozos.com');" src="img/logo.png">
+            </div>
+        </div>
+       <script>
+        if (window.location.hash.length > 1){
+            $("#targeturl").text(window.location.hash.substr(1));
+        }
+       </script>
+    </body>
+</html>