Firefox OS 是一个基于 Firefox 网页浏览器引擎构建的操作系统,该引擎称为 Gecko。Firefox OS 上的浏览器应用程序提供了一个使用 HTML5 技术编写的用户界面,并使用 浏览器 API 管理网页浏览。它还根据实现管理选项卡、浏览历史记录、书签等。
虽然 Firefox OS 已经包含一个浏览器,但您可以使用浏览器 API 来创建自己的浏览器或将浏览器功能添加到您的应用程序。本文介绍了如何为 Firefox OS 设备构建浏览器应用程序。按照这些步骤,您将获得一个基本的 Firefox OS 浏览器应用程序,其中包含一个地址栏和后退/前进按钮以浏览网页。
源代码可以在 https://github.com/begeeben/firefox-os-browser-sample 下载。
先决条件:WebIDE
您可以通过 Firefox 34 或更高版本使用 WebIDE。开发、构建或测试浏览器应用程序不需要 Firefox OS 设备。通过使用 WebIDE,我们可以轻松地引导一个 Web 应用程序,进行 HTML/CSS/JS 修改,并在 Firefox OS 模拟器之一上运行应用程序。要在 Firefox 中打开 WebIDE,请从顶部菜单中选择**工具 > Web 开发者 > WebIDE**
从模板创建应用程序
首先,使用 WebIDE 空模板引导一个 Web 应用程序。应用程序类型需要是特权的,以便可以设置browser权限。为了使用 浏览器 API,需要此权限。 浏览器 API 提供了管理 iframe 的附加方法和事件。
以下是应用程序的外观截图。接下来我们将开始添加代码以制作一个简单的浏览器应用程序。
编辑 manifest.webapp
让我们开始进行一些代码更改。模板已经在 manifest.webapp 中将应用程序类型设置为privileged。
"type": "privileged",
要允许我们的应用程序使用浏览器 API,我们需要指定“browser”权限。
"permissions": {
"browser": {}
},
HTML 结构
我们正在构建的浏览器应用程序将在顶部有一个工具栏,以及一个作为 iframe 容器的 div,默认情况下它显示“Hello myBrowser!”。浏览器 iframe 将稍后使用 JavaScript 创建。我们可以在 HTML 中添加 iframe,但在本示例中,将动态创建新的浏览器 iframe。
Hello myBrowser!
以下是简单浏览器应用程序的截图
管理浏览器 iframe
浏览器应用程序必须处理mozbrowser事件,这些事件在应用程序具有browser权限时可用。为了分离 UI 和mozbrowser事件处理,并保留将来支持多个选项卡的灵活性,我们添加了一个 tab.js 文件。以下是 tab.js 中的代码,该代码使用“mozbrowser”属性创建了一个 iframe 以启用 浏览器 API 的使用。
/**
* Returns an iframe which runs in a child process with Browser API enabled
* and fullscreen is allowed
*
* @param {String} [url] Optional URL
* @return {iframe} An OOP mozbrowser iframe
*/
function createIFrame (url) {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', true);
iframe.setAttribute('mozallowfullscreen', true);
iframe.setAttribute('remote', true);
if (url) {
iframe.src = url;
}
return iframe;
}
mozallowfullscreen属性使 iframe 的嵌入网页能够使用全屏模式。网页可以通过调用Element.mozRequestFullscreen()来请求全屏模式。
“remote”属性将嵌入的 iframe 分隔到另一个子进程中。出于安全原因,需要这样做,以防止恶意网站破坏浏览器应用程序。目前,此属性在此示例浏览器应用程序中没有任何作用,因为嵌套 OOP 尚未实现。请参阅 错误 1020135 – (nested-oop) [meta] 允许嵌套 oop <iframe mozbrowser>.
接下来,将“Tab”对象构造函数添加到 tab.js。此构造函数处理浏览器 iframe 创建和浏览器事件处理。当构造一个 Tab 时,它会创建一个浏览器 iframe 并将mozbrowser事件侦听器附加到它。
/**
* The browser tab constructor.
*
* Creates an iframe and attaches mozbrowser events for web browsing.
*
* Implements EventListener Interface.
*
* @param {String} url An optional plaintext URL
*/
function Tab (url) {
this.iframe = createIFrame(url);
this.title = null;
this.url = url;
this.iframe.addEventListener('mozbrowserloadstart', this);
this.iframe.addEventListener('mozbrowserlocationchange', this);
this.iframe.addEventListener('mozbrowsertitlechange', this);
this.iframe.addEventListener('mozbrowserloadend', this);
this.iframe.addEventListener('mozbrowsererror', this);
};
还有其他未在此简单浏览器应用程序中使用的mozbrowser事件。在此示例中使用的事件可以访问有关 iframe 的有用信息,而我们的浏览器应用程序使用它们来提供网页详细信息,例如标题、URL、加载进度、上下文菜单等。
例如,要在工具栏上显示页面标题,我们使用mozbrowsertitlechange事件来检索网页的标题。更新标题后,会分发一个带有 Tab 本身的详细信息的CustomEvent 'tab:titlechange',以通知其他组件更新标题。
Tab.prototype.mozbrowsertitlechange = function _mozbrowsertitlechange (e) {
if (e.detail) {
this.title = e.detail;
}
var event = new CustomEvent('tab:titlechange', { detail: this });
window.dispatchEvent(event);
};
现在可以在主 app.js 中添加代码来处理此自定义事件,该事件将更新标题。
/**
* Display the title of the currentTab on titlechange event.
*/
window.addEventListener('tab:titlechange', function (e) {
if (currentTab === e.detail) {
urlInput.value = currentTab.title;
}
});
在提交事件中浏览网页
在浏览器中使用地址栏作为搜索栏是一种常见的实用做法。当用户提交输入时,首先我们会检查它是否是有效的 URL。如果不是,则输入被视为搜索词,并将其附加到搜索引擎 URI。请注意,可以以多种方式处理 URL 的验证。示例应用程序使用了一个类型属性设置为 URL 的输入元素。还可以使用一个 URL 对象,并将 URL 字符串作为第一个参数传递给构造函数。如果 URL 无效,则会抛出 DOM 异常。然后可以捕获此异常,并假定 URL 字符串是搜索词。
/**
* The default search engine URI
*
* @type {String}
*/
var searchEngineUri = 'https://search.yahoo.com/search?p={searchTerms}';
/**
* Using an input element to check the validity of the input URL. If the input
* is not valid, returns a search URL.
*
* @param {String} input A plaintext URL or search terms
* @param {String} searchEngineUri The search engine to be used
* @return {String} A valid URL
*/
function getUrlFromInput(input, searchEngineUri) {
var urlValidate = document.createElement('input');
urlValidate.setAttribute('type', 'url');
urlValidate.setAttribute('value', input);
if (!urlValidate.validity.valid) {
var uri = searchEngineUri.replace('{searchTerms}', input);
return uri;
}
return input;
}
然后可以在主 app.js 中添加代码来处理提交按钮。此代码检查是否存在当前活动的Tab对象,如果存在,则加载 URL 或如果 URL 未更改则重新加载 URL。如果不存在,则创建该对象并加载 URL。
/**
* Check the input and browse the address with a Tab object on url submit.
*/
window.addEventListener('submit', function (e) {
e.preventDefault();
if (!currentUrlInput.trim()) {
return;
}
if (frameContainer.classList.contains('empty')) {
frameContainer.classList.remove('empty');
}
var url = getUrlFromInput(currentUrlInput.trim(), searchEngineUri);
if (!currentTab) {
currentTab = new Tab(url);
frameContainer.appendChild(currentTab.iframe);
} else if (currentUrlInput === currentTab.title) {
currentTab.reload();
} else {
currentTab.goToUrl(url);
}
});
currentTab.reload函数使用Browser API提供的iframe.reload函数来重新加载页面。以下代码添加到 tab.js 文件中以处理重新加载。
/**
* Reload the current page.
*/
Tab.prototype.reload = function _reload () {
this.iframe.reload();
};
启用/禁用后退和前进按钮
最后,可以使用 浏览器 API 来检查页面是否可以在导航历史记录中后退或前进。iframe.getCanGoBack方法返回一个DOMRequest对象,该对象在其onsuccess回调中指示页面是否可以后退。我们使用Promise来包装此函数,以便更轻松地访问。此代码添加到 tab.js 文件中。
/**
* Check if the iframe can go backward in the navigation history.
*
* @return {Promise} Resolve with true if it can go backward.
*/
Tab.prototype.getCanGoBack = function _getCanGoBack () {
var self = this;
return new Promise(function (resolve, reject) {
var request = self.iframe.getCanGoBack();
request.onsuccess = function () {
if (this.result) {
resolve(true);
} else {
resolve(false);
}
};
});
};
当页面加载时,将在 app.js 文件中执行检查。当 iframe 接收mozbrowserloadend事件时,就会发生这种情况。
/**
* Enable/disable goback and goforward buttons accordingly when the
* currentTab is loaded.
*/
window.addEventListener('tab:loadend', function (e) {
if (currentTab === e.detail) {
currentTab.getCanGoBack().then(function(canGoBack) {
gobackButton.disabled = !canGoBack;
});
currentTab.getCanGoForward().then(function(canGoForward) {
goforwardButton.disabled = !canGoForward;
});
}
});
运行应用程序
现在可以使用 Firefox OS 模拟器之一来测试示例浏览器应用程序。
在 WebIDE 的右上角,单击**选择运行时**以选择一个 Firefox OS 手机或模拟器
选择并启动 Firefox OS 运行时后,您可以通过单击 WebIDE 中的播放按钮来安装并运行该应用程序。有关构建、调试和部署 Firefox OS 应用程序的更多信息,请参阅 WebIDE 文档。
最后的想法
您可以向这个简单的浏览器添加更多功能以使其真正有用,包括书签、设置、搜索建议和共享。随意扩展此代码并享受使用乐趣。让我们知道您的想法,并务必传播 Firefox OS 的信息!
其他信息
https://hacks.mozilla.ac.cn/2014/08/building-the-firefox-browser-for-firefox-os/
https://mdn.org.cn/en-US/docs/Web/API/Using_the_Browser_API







2 评论