Browser app (当前是 System 的一部分) 提供了浏览器相关的功能 — 包括页面导航,搜索和书签。本文介绍了 Browser app 的基本工作以及它是如何融合进更大的 System中的。
由于 Gaia 运行 Gecko 的上层, 在基于 Gekco 实例之上,启动一个 Browser app/ System 浏览器进行常规的页面是非常容易做到的。它是由 mozBrowser API 实现的。
注意: Firefox OS 2.1 之后, Browser app 就是 System app 的一部分了。这意味着可以同时通过点击浏览器图标启动 Browser app 或通过全局搜索以及导航的能力来进行 web 浏览。 app 和 浏览器 tab 页此后会有共同的公共体验, 它们会作为 Haida 用户体验 的一部分,存在于任务管理器和表视图中(用于边缘手势)。
System 浏览器 (浏览器框架)
当 Firefox OS 用户将一个 web 页面添加为标签时, 它就会显示在 homescreen 上, 这个 web 页面后续就会打开 System 浏览器而不是 Browser app。在页面底部会有一个工具栏, 包括 向前/向后/刷新的功能。在 Gaia 中,它被称之为浏览器框架或包装器( wrapper)。您可以在下面图片的右手侧看到。
如果想要使您的 web 页面仍具有 后退/前进/刷新 的功能, 您可以在 app 表单文件中包含下面声明来使能浏览器框架。
declare { chrome: { navigation: true } }
注意: 浏览器框架工具栏会影响到内容的高度,因此当在设计 web 页面布局时将其考虑进去。
代码流程
当在 Firefox OS 中打开一个新的 web 页面时,调用流程如下
Gecko > WrapperFactory > Window Manager > AppWindow > BrowserFrame
Wrappers inheriting from system/js/wrapper_factory will receive the mozbrowseropenwindow
event for a bookmarked web page.
In the handleEvent section, the handler will check the event to decide whether the web page should be opened as an app or in browser chrome.
Finally, launchWrapper is called to launch the corresponding window.
全局搜索 & 导航
With the new search and navigation bar, users can get to their favorites, type in a URL, or discover a new app, from anywhere in Firefox OS. The search bar lives at the top of the screen, and users can just tap or swipe to open it.
Think of it as a combination of the Awesome Bar from the browser and the adaptive app search from the homescreen. Because Firefox OS uses web apps, when you find what you want, even if it’s a new app, it opens right away. You don’t need to install anything, because everything is instant and web—like.
Browser App
The Browser app is a certified webapp that provides a general web browser experience. The main function is located in apps/browser/js/browser.js:
var Browser = { init: function browser_init() { this.getAllElements(); ... BrowserDB.init((function() { ... } } }; window.addEventListener('load', function browserOnLoad(evt) { window.removeEventListener('load', browserOnLoad); Browser.init(); });
The Browser will call its init()
function while the DOM is loaded.
getAllElements: function browser_getAllElements() { var elementIDs = [ 'toolbar—start', ... 'danger—dialog']; // Loop and add element with camel style name to Modal Dialog attribute. elementIDs.forEach(function createElementRef(name) { this[this.toCamelCase(name)] = document.getElementById(name); }, this); },
The getAllElements
function is used to get all camelCase element handlers, after which the apps/browser/js/browser_db.js is called, to prepare for adding the default search engine and bookmarks.
书签
From Firefox OS 2.0 apps/bookmark is used to handle bookmark save/remove activities.
The most interesting parts apps/bookmark/webapp.manifest looks like so:
"activities": { "save—bookmark": { "filters": { "type": "url", "url": { "required":true, "pattern":"https?:.{1,16384}" } }, "disposition": "inline", "href": "/save.html", "returnValue": true }, "remove—bookmark": { "filters": { "type": "url", "url": { "required":true, "pattern":"https?:.{1,16384}" } }, "disposition": "inline", "href": "/remove.html", "returnValue": true } },
As seen above, the activity is handled by save.html and remove.html. Both operations are delegated to apps/bookmark/js/activity_handler.js:
var ActivityHandler = { 'save—bookmark': function ah_save(activity) { }, 'remove—bookmark': function ah_remove(activity) { } }; navigator.mozSetMessageHandler('activity', function onActivity(activity) { var name = activity.source.name; switch (name) { case 'save—bookmark': case 'remove—bookmark': if (activity.source.data.type === 'url') { ActivityHandler[name](activity); } ... } }
When the message handler listener navigator.mozSetMessageHandler('activity')
receives the save-bookmark or remove-bookmark activities, the ActivityHandler
function is triggered to handle correspondent operations.