buildable mobile browser mobile
authormfinkle@mozilla.com
Fri, 18 Apr 2008 13:41:49 +0000
branchmobile
changeset 1 05a4a50c728fa0c3981987e34d41e2d3f4ebb73b
parent 0 7821bba627c16abc1d25aae0a7c140c79e904d08
child 2 5b90e73b5adc49dbc8fb2bc8c32d14970869b88b
push id1
push uservladimir@mozilla.com
push dateFri, 09 May 2008 21:34:35 +0000
buildable mobile browser
Makefile.in
app/Makefile.in
app/application.ini
app/mobile.js
build.mk
chrome/Makefile.in
chrome/content/browser.js
chrome/content/browser.xul
chrome/content/commandUtil.js
chrome/content/content.css
chrome/content/deckbrowser.css
chrome/content/deckbrowser.xml
chrome/content/scrollbars.css
chrome/jar.mn
chrome/locale/en-US/brand/brand.dtd
chrome/locale/en-US/brand/brand.properties
chrome/locale/en-US/browser.dtd
chrome/skin/browser.css
chrome/skin/images/bookmarks.png
chrome/skin/images/close.png
chrome/skin/images/default-favicon.png
chrome/skin/images/go-arrow.png
chrome/skin/images/page-starred.png
chrome/skin/images/search-glass.png
chrome/skin/images/star-page.png
chrome/skin/images/starred48.png
chrome/skin/images/tap-n-hold.png
chrome/skin/images/throbber.gif
chrome/skin/images/throbber.png
chrome/skin/images/toolbar.png
confvars.sh
installer/Makefile.in
makefiles.sh
new file mode 100644
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,47 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Mark Finkle <mfinkle@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH      = ..
+topsrcdir  = @top_srcdir@
+srcdir     = @srcdir@
+VPATH      = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS       = chrome app
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/app/Makefile.in
@@ -0,0 +1,98 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Mark Finkle <mfinkle@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH     = ../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+PREF_JS_EXPORTS = $(srcdir)/mobile.js
+DIST_FILES  = application.ini
+
+include $(topsrcdir)/config/rules.mk
+
+GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
+GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build BuildID)
+APP_UA_NAME = $(shell echo $(MOZ_APP_DISPLAYNAME) | sed -e's/[^A-Za-z]//g')
+
+DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID) -DAPP_NAME=$(MOZ_APP_DISPLAYNAME) -DAPP_VERSION=$(MOZ_APP_VERSION) -DAPP_UA_NAME=$(APP_UA_NAME)
+
+APP_BINARY = $(MOZ_APP_NAME)$(BIN_SUFFIX)
+
+ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
+
+APP_NAME = $(MOZ_APP_DISPLAYNAME)
+APP_VERSION = $(MOZ_APP_VERSION)
+
+ifdef MOZ_DEBUG
+APP_NAME := $(APP_NAME)Debug
+endif
+
+AB_CD = $(MOZ_UI_LOCALE)
+
+AB := $(firstword $(subst -, ,$(AB_CD)))
+
+clean clobber repackage::
+	rm -rf $(DIST)/$(APP_NAME).app
+
+APPFILES = Resources
+
+libs repackage:: application.ini
+	mkdir -p $(DIST)/$(APP_NAME).app/Contents/MacOS
+	rsync -a --exclude CVS --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/$(APP_NAME).app --exclude English.lproj
+	mkdir -p $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
+	rsync -a --exclude CVS --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
+	sed -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" -e "s/%APP_BINARY%/$(APP_BINARY)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/$(APP_NAME).app/Contents/Info.plist
+	sed -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj/InfoPlist.strings
+	rsync -a $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
+	$(RM) $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/mangle $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/shlibsign
+	cp $(LIBXUL_DIST)/bin/xulrunner$(BIN_SUFFIX) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(APP_BINARY)
+	rsync -a --exclude nsinstall --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(DIST)/$(APP_NAME).app/Contents/Frameworks
+	echo -n APPLMOZB > $(DIST)/$(APP_NAME).app/Contents/PkgInfo
+#	remove CVS dirs from packaged app
+	find $(DIST)/$(APP_NAME).app -type d -name "CVS" -prune -exec rm -rf {} \;
+
+else
+
+libs::
+	cp $(LIBXUL_DIST)/bin/xulrunner-stub$(BIN_SUFFIX) $(DIST)/bin/$(APP_BINARY)
+	$(NSINSTALL) -D $(DIST)/bin/xulrunner
+	(cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
+
+endif
new file mode 100644
--- /dev/null
+++ b/app/application.ini
@@ -0,0 +1,15 @@
+#filter substitution
+[App]
+Vendor=Mozilla
+Name=@APP_NAME@
+Version=@APP_VERSION@
+BuildID=@GRE_BUILDID@
+Copyright=Copyright (c) 2008 Mozilla.org
+ID={a23983c0-fd0e-11dc-95ff-0800200c9a66}
+
+[Gecko]
+MinVersion=@GRE_MILESTONE@
+MaxVersion=@GRE_MILESTONE@
+
+[XRE]
+EnableExtensionManager=1
new file mode 100644
--- /dev/null
+++ b/app/mobile.js
@@ -0,0 +1,121 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#filter substitution
+
+pref("toolkit.defaultChromeURI", "chrome://browser/content/browser.xul");
+pref("general.useragent.extra.mobile", "@APP_UA_NAME@/@APP_VERSION@");
+
+pref("browser.startup.homepage", "http://www.mozilla.org/");
+pref("browser.ui.cursor", false);
+pref("general.smoothScroll", false);
+
+/* cache prefs */
+pref("browser.cache.disk.enable", false);
+pref("browser.cache.disk.capacity", 0);
+pref("browser.cache.memory.enable", true);
+pref("browser.cache.memory.capacity", 1024);
+
+/* http prefs */
+pref("network.http.pipelining", true);
+pref("network.http.pipelining.ssl", true);
+pref("network.http.proxy.pipelining", true);
+pref("network.http.pipelining.maxrequests" , 2);
+pref("network.http.keep-alive.timeout", 600);
+pref("network.http.max-connections", 4);
+pref("network.http.max-connections-per-server", 1);
+pref("network.http.max-persistent-connections-per-server", 1);
+pref("network.http.max-persistent-connections-per-proxy", 1);
+
+/* session history */
+pref("browser.sessionhistory.max_total_viewers", 0);
+pref("browser.sessionhistory.max_entries", 3);
+
+/* debugging prefs */
+pref("browser.dom.window.dump.enabled", true);
+pref("javascript.options.showInConsole", true);
+pref("javascript.options.strict", true);
+pref("nglayout.debug.disable_xul_cache", false);
+pref("nglayout.debug.disable_xul_fastload", false);
+
+/* download manager */
+pref("browser.download.useDownloadDir", true);
+pref("browser.download.folderList", 0);
+pref("browser.download.manager.showAlertOnComplete", true);
+pref("browser.download.manager.showAlertInterval", 2000);
+pref("browser.download.manager.retention", 2);
+pref("browser.download.manager.showWhenStarting", true);
+pref("browser.download.manager.useWindow", true);
+pref("browser.download.manager.closeWhenDone", true);
+pref("browser.download.manager.openDelay", 0);
+pref("browser.download.manager.focusWhenStarting", false);
+pref("browser.download.manager.flashCount", 2);
+pref("browser.download.manager.displayedHistoryDays", 7);
+
+/* download alerts */
+pref("alerts.slideIncrement", 1);
+pref("alerts.slideIncrementTime", 10);
+pref("alerts.totalOpenTime", 6000);
+pref("alerts.height", 50);
+
+/* password manager */
+pref("signon.rememberSignons", true);
+pref("signon.expireMasterPassword", false);
+pref("signon.SignonFileName", "signons.txt");
+
+/* autocomplete */
+pref("browser.formfill.enable", true);
+
+/* spellcheck */
+pref("layout.spellcheckDefault", 1);
+
+/* extension manager and xpinstall */
+pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
+pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul?type=themes");
+pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul?type=extensions");
+pref("xpinstall.dialog.progress.type.skin", "Extension:Manager-themes");
+pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager-extensions");
+pref("extensions.update.enabled", true);
+pref("extensions.update.interval", 86400);
+pref("extensions.dss.enabled", false);
+pref("extensions.dss.switchPending", false);
+pref("extensions.ignoreMTimeChanges", false);
+pref("extensions.logging.enabled", false);
+
+/* these point at AMO */
+pref("extensions.update.url", "chrome://mozapps/locale/extensions/extensions.properties");
+pref("extensions.getMoreExtensionsURL", "chrome://mozapps/locale/extensions/extensions.properties");
+pref("extensions.getMoreThemesURL", "chrome://mozapps/locale/extensions/extensions.properties");
new file mode 100644
--- /dev/null
+++ b/build.mk
@@ -0,0 +1,57 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Mark Finkle <mfinkle@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+TIERS += app
+
+ifdef MOZ_EXTENSIONS
+tier_app_dirs += extensions
+endif
+
+tier_app_dirs += \
+  mobile \
+  $(NULL)
+
+installer:
+	@echo "Mobile doesn't have an installer yet."
+	@exit 1
+
+package:
+	@$(MAKE) -C mobile/installer
+
+install::
+	@echo "Mobile can't be installed directly."
+	@exit 1
new file mode 100644
--- /dev/null
+++ b/chrome/Makefile.in
@@ -0,0 +1,47 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Mark Finkle <mfinkle@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH     = ../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DEFINES   += -DAB_CD=$(MOZ_UI_LOCALE) -DPACKAGE=browser
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/chrome/content/browser.js
@@ -0,0 +1,1034 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brad Lassey <blassey@mozilla.com>
+ *   Mark Finkle <mfinkle@mozilla.com>
+ *   Aleks Totic <a@totic.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const TOOLBARSTATE_LOADING        = 1;
+const TOOLBARSTATE_LOADED         = 2;
+const TOOLBARSTATE_TYPING         = 3;
+const TOOLBARSTATE_INDETERMINATE  = 4;
+
+var LocationBar = {
+  _urlbar : null,
+  _throbber : null,
+  _favicon : null,
+  _faviconAdded : false,
+
+  _linkAdded : function(aEvent) {
+    var link = aEvent.originalTarget;
+    var rel = link.rel && link.rel.toLowerCase();
+    if (!link || !link.ownerDocument || !rel || !link.href)
+      return;
+
+    var rels = rel.split(/\s+/);
+    if (rels.indexOf("icon") != -1) {
+      this._favicon.setAttribute("src", link.href);
+      this._throbber.setAttribute("src", "");
+      this._faviconAdded = true;
+    }
+  },
+
+  init : function() {
+    this._urlbar = document.getElementById("urlbar");
+    this._urlbar.addEventListener("focus", this, false);
+    this._urlbar.addEventListener("input", this, false);
+
+    this._throbber = document.getElementById("urlbar-throbber");
+    this._favicon = document.getElementById("urlbar-favicon");
+    this._favicon.addEventListener("error", this, false);
+
+    Browser.content.addEventListener("DOMLinkAdded", this, true);
+  },
+
+  update : function(aState) {
+    var go = document.getElementById("cmd_go");
+    var search = document.getElementById("cmd_search");
+    var reload = document.getElementById("cmd_reload");
+    var stop = document.getElementById("cmd_stop");
+
+    if (aState == TOOLBARSTATE_INDETERMINATE) {
+      this._faviconAdded = false;
+      aState = TOOLBARSTATE_LOADED;
+      this.setURI();
+    }
+
+    if (aState == TOOLBARSTATE_LOADING) {
+      go.collapsed = true;
+      search.collapsed = true;
+      reload.collapsed = true;
+      stop.collapsed = false;
+
+      this._throbber.setAttribute("src", "chrome://browser/skin/images/throbber.gif");
+      this._favicon.setAttribute("src", "");
+      this._faviconAdded = false;
+    }
+    else if (aState == TOOLBARSTATE_LOADED) {
+      go.collapsed = true;
+      search.collapsed = true;
+      reload.collapsed = false;
+      stop.collapsed = true;
+
+      this._throbber.setAttribute("src", "");
+      if (this._faviconAdded == false) {
+        var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+        var faviconURI = ios.newURI(Browser.content.browser.currentURI.prePath + "/favicon.ico", null, null);
+
+        var fis = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
+        if (fis.isFailedFavicon(faviconURI))
+          faviconURI = ios.newURI("chrome://browser/skin/images/default-favicon.png", null, null);
+
+        this._favicon.setAttribute("src", faviconURI.spec);
+        this._faviconAdded = true;
+      }
+    }
+    else if (aState == TOOLBARSTATE_TYPING) {
+      reload.collapsed = true;
+      stop.collapsed = true;
+      go.collapsed = false;
+      search.collapsed = false;
+
+      this._throbber.setAttribute("src", "chrome://browser/skin/images/throbber.png");
+      this._favicon.setAttribute("src", "");
+    }
+  },
+
+  /* Set the location to the current content */
+  setURI : function() {
+    // Update UI for history
+    var browser = Browser.content.browser;
+    var back = document.getElementById("cmd_back");
+    var forward = document.getElementById("cmd_forward");
+
+    back.setAttribute("disabled", !browser.canGoBack);
+    forward.setAttribute("disabled", !browser.canGoForward);
+
+    // Check for a bookmarked page
+    var star = document.getElementById("tool_star");
+    star.removeAttribute("starred");
+    var bms = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
+    var bookmarks = bms.getBookmarkIdsForURI(browser.currentURI, {});
+    if (bookmarks.length > 0) {
+      star.setAttribute("starred", "true");
+    }
+
+    var uri = browser.currentURI.spec;
+    if (uri == "about:blank") {
+      uri = "";
+      this._urlbar.focus();
+    }
+
+    this._urlbar.value = uri;
+  },
+
+  revertURI : function() {
+    // Reset the current URI from the browser if the histroy list is not open
+    if (this._urlbar.popupOpen == false)
+      this.setURI();
+
+    // If the value isn't empty and the urlbar has focus, select the value.
+    if (this._urlbar.value && this._urlbar.hasAttribute("focused"))
+      this._urlbar.select();
+
+    return (this._urlbar.popupOpen == false);
+  },
+
+  goToURI : function() {
+    Browser.content.loadURI(this._urlbar.value, null, null, false);
+  },
+
+  search : function() {
+    var queryURI = "http://www.google.com/search?q=" + this._urlbar.value + "&hl=en&lr=&btnG=Search";
+    Browser.content.loadURI(queryURI, null, null, false);
+  },
+
+  getURLBar : function() {
+    return this._urlbar;
+  },
+
+  handleEvent: function (aEvent) {
+    switch (aEvent.type) {
+      case "DOMLinkAdded":
+        this._linkAdded(aEvent);
+        break;
+      case "focus":
+        setTimeout(function() { aEvent.target.select(); }, 0);
+        break;
+      case "input":
+        this.update(TOOLBARSTATE_TYPING);
+        break;
+      case "error":
+        this._favicon.setAttribute("src", "chrome://browser/skin/images/default-favicon.png");
+        break;
+    }
+  }
+};
+
+
+var Bookmarks = {
+  bookmarks : null,
+  panel : null,
+  item : null,
+
+  edit : function(aURI) {
+    this.bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
+    this.panel = document.getElementById("bookmark_edit");
+    this.panel.hidden = false; // was initially hidden to reduce Ts
+
+    var bookmarkIDs = this.bookmarks.getBookmarkIdsForURI(aURI, {});
+    if (bookmarkIDs.length > 0) {
+      this.item = bookmarkIDs[0];
+      document.getElementById("bookmark_url").value = aURI.spec;
+      document.getElementById("bookmark_name").value = this.bookmarks.getItemTitle(this.item);
+
+      this.panel.openPopup(document.getElementById("tool_star"), "after_end", 0, 0, false, false);
+    }
+  },
+
+  remove : function() {
+    if (this.item) {
+      this.bookmarks.removeItem(this.item);
+      document.getElementById("tool_star").removeAttribute("starred");
+    }
+    this.close();
+  },
+
+  save : function() {
+    if (this.panel && this.item) {
+      var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+      var bookmarkURI = ios.newURI(document.getElementById("bookmark_url").value, null, null);
+      if (bookmarkURI) {
+        this.bookmarks.setItemTitle(this.item, document.getElementById("bookmark_name").value);
+        this.bookmarks.changeBookmarkURI(this.item, bookmarkURI);
+      }
+    }
+    this.close();
+  },
+
+  close : function() {
+    if (this.panel) {
+      this.item = null;
+      this.panel.hidePopup();
+      this.panel = null;
+    }
+  },
+
+  list : function() {
+    this.bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
+    this.panel = document.getElementById("bookmark_picker");
+    this.panel.hidden = false; // was initially hidden to reduce Ts
+
+    var list = document.getElementById("bookmark_list");
+    while (list.childNodes.length > 0) {
+      list.removeChild(list.childNodes[0]);
+    }
+
+    var fis = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
+
+    var items = this.getBookmarks();
+    if (items.length > 0) {
+      for (var i=0; i<items.length; i++) {
+        var itemId = items[i];
+        var listItem = document.createElement("richlistitem");
+        listItem.setAttribute("class", "bookmarklist-item");
+
+        var box = document.createElement("vbox");
+        box.setAttribute("pack", "center");
+        var image = document.createElement("image");
+        image.setAttribute("class", "bookmarklist-image");
+        image.setAttribute("src", fis.getFaviconImageForPage(this.bookmarks.getBookmarkURI(itemId)).spec);
+        box.appendChild(image);
+        listItem.appendChild(box);
+
+        var label = document.createElement("label");
+        label.setAttribute("class", "bookmarklist-text");
+        label.setAttribute("value", this.bookmarks.getItemTitle(itemId));
+        label.setAttribute("flex", "1");
+        label.setAttribute("crop", "end");
+        label.setAttribute("onclick", "Bookmarks.open(" + itemId + ");");
+        listItem.appendChild(label);
+        list.appendChild(listItem);
+      }
+      this.panel.openPopup(document.getElementById("tool_bookmarks"), "after_end", 0, 0, false, false);
+    }
+  },
+
+  open : function(aItem) {
+    var bookmarkURI = this.bookmarks.getBookmarkURI(aItem);
+    Browser.content.loadURI(bookmarkURI.spec, null, null, false);
+    this.close();
+  },
+
+  getBookmarks : function() {
+    var items = [];
+
+    var history = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);
+    var options = history.getNewQueryOptions();
+    var query = history.getNewQuery();
+    query.setFolders([this.bookmarks.bookmarksMenuFolder], 1);
+    var result = history.executeQuery(query, options);
+    var rootNode = result.root;
+    rootNode.containerOpen = true;
+    var cc = rootNode.childCount;
+    for (var i=0; i<cc; ++i) {
+      var node = rootNode.getChild(i);
+      if (node.type == node.RESULT_TYPE_URI) {
+        items.push(node.itemId);
+      }
+    }
+    rootNode.containerOpen = false;
+
+    return items;
+  }
+};
+
+
+var Browser = {
+  _content : null,
+
+  _titleChanged : function(aEvent) {
+    if (aEvent.target != this.content.browser.contentDocument)
+      return;
+
+      document.title = "Firefox - " + aEvent.target.title;
+  },
+
+  _tabOpen : function(aEvent) {
+    aEvent.originalTarget.zoomController = new ZoomController(aEvent.originalTarget);
+    aEvent.originalTarget.mouseController = new MouseController(aEvent.originalTarget);
+    aEvent.originalTarget.progressController = new ProgressController(aEvent.originalTarget);
+  },
+
+  _tabClose : function(aEvent) {
+  },
+
+  _tabSelect : function(aEvent) {
+    LocationBar.update(TOOLBARSTATE_INDETERMINATE);
+  },
+
+  _popupShowing : function(aEvent) {
+    var target = document.popupNode;
+    var isContentSelected = !document.commandDispatcher.focusedWindow.getSelection().isCollapsed;
+    var isTextField = target instanceof HTMLTextAreaElement;
+    if (target instanceof HTMLInputElement && (target.type == "text" || target.type == "password"))
+      isTextField = true;
+    var isTextSelected= (isTextField && target.selectionStart != target.selectionEnd);
+
+    /* not ready
+    var cut = document.getElementById("menuitem_cut");
+    var copy = document.getElementById("menuitem_copy");
+    var paste = document.getElementById("menuitem_paste");
+    var del = document.getElementById("menuitem_delete");
+
+    cut.hidden = ((!isTextField || !isTextSelected) ? true : false);
+    copy.hidden = (((!isTextField || !isTextSelected) && !isContentSelected) ? true : false);
+    paste.hidden = (!isTextField ? true : false);
+    del.hidden = (!isTextField ? true : false);
+
+    var copylink = document.getElementById("menuitem_copylink");
+    var copylinkSep = document.getElementById("menusep_copylink");
+    if (target instanceof HTMLAnchorElement && target.href) {
+      copylink.hidden = false;
+      copylinkSep.hidden = false;
+    }
+    else {
+      copylink.hidden = true;
+      copylinkSep.hidden = true;
+    }
+    */
+    InlineSpellCheckerUI.clearSuggestionsFromMenu();
+    InlineSpellCheckerUI.uninit();
+
+    var separator = document.getElementById("menusep_spellcheck");
+    separator.hidden = true;
+    var addToDictionary = document.getElementById("menuitem_addToDictionary");
+    addToDictionary.hidden = true;
+    var noSuggestions = document.getElementById("menuitem_noSuggestions");
+    noSuggestions.hidden = true;
+
+    // if the document is editable, show context menu like in text inputs
+    var win = target.ownerDocument.defaultView;
+    if (win) {
+      var isEditable = false;
+      try {
+        var editingSession = win.QueryInterface(Ci.nsIInterfaceRequestor)
+                                .getInterface(Ci.nsIWebNavigation)
+                                .QueryInterface(Ci.nsIInterfaceRequestor)
+                                .getInterface(Ci.nsIEditingSession);
+        isEditable = editingSession.windowIsEditable(win);
+      }
+      catch(ex) {
+        // If someone built with composer disabled, we can't get an editing session.
+      }
+    }
+
+    var editor = null;
+    if (isTextField && !target.readOnly)
+      editor = target.QueryInterface(Ci.nsIDOMNSEditableElement).editor;
+
+    if (isEditable)
+      editor = editingSession.getEditorForWindow(win);
+dump("ready\n");
+    if (editor) {
+dump("editor\n");
+dump("anchor="+editor.selection.anchorNode+"\n");
+dump("offset="+editor.selection.anchorOffset+"\n");
+dump(editor.selectionController.getSelection(Ci.nsISelectionController.SELECTION_SPELLCHECK).rangeCount);
+      InlineSpellCheckerUI.init(editor);
+dump(InlineSpellCheckerUI.canSpellCheck);
+//      InlineSpellCheckerUI.initFromEvent(document.popupRangeParent, document.popupRangeOffset);
+      InlineSpellCheckerUI.initFromEvent(editor.selection.anchorNode, editor.selection.anchorOffset);
+
+      var onMisspelling = InlineSpellCheckerUI.overMisspelling;
+      if (onMisspelling) {
+dump("misspelling\n");
+        separator.hidden = false;
+        addToDictionary.hidden = false;
+        var menu = document.getElementById("popup_content");
+        var suggestions = InlineSpellCheckerUI.addSuggestionsToMenu(menu, addToDictionary, 5);
+        noSuggestions.hidden = (suggestions > 0);
+      }
+    }
+  },
+
+  startup : function() {
+    this.prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
+
+    window.controllers.appendController(this);
+
+    var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+    var styleSheets = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
+
+    // Should we hide the cursors
+    var hideCursor = this.prefs.getBoolPref("browser.ui.cursor") == false;
+    if (hideCursor) {
+      window.QueryInterface(Ci.nsIDOMChromeWindow).setCursor("none");
+
+      var styleURI = ios.newURI("chrome://browser/content/content.css", null, null);
+      styleSheets.loadAndRegisterSheet(styleURI, styleSheets.AGENT_SHEET);
+    }
+
+    // load styles for scrollbars
+    var styleURI = ios.newURI("chrome://browser/content/scrollbars.css", null, null);
+    styleSheets.loadAndRegisterSheet(styleURI, styleSheets.AGENT_SHEET);
+
+    this._content = document.getElementById("content");
+    this._content.addEventListener("DOMTitleChanged", this, true);
+    this._content.addEventListener("TabOpen", this, true);
+    this._content.addEventListener("TabClose", this, true);
+    this._content.addEventListener("TabSelect", this, true);
+    document.getElementById("popup_content").addEventListener("popupshowing", this, false);
+
+    this._content.addBrowser("about:blank", null, null, false);
+
+    LocationBar.init();
+    Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
+
+    // Determine the initial launch page
+    var whereURI = null;
+    try {
+      // Use a homepage
+      whereURI = this.prefs.getCharPref("browser.startup.homepage");
+    }
+    catch (e) {
+    }
+
+    // Use a commandline parameter
+    if (window.arguments && window.arguments[0]) {
+      var cmdLine = window.arguments[0].QueryInterface(Ci.nsICommandLine);
+      if (cmdLine.length == 1) {
+        whereURI = cmdLine.resolveURI(cmdLine.getArgument(0));
+        if (whereURI)
+          whereURI = whereURI.spec;
+      }
+    }
+
+    if (whereURI) {
+      var self = this;
+      setTimeout(function() { self.content.browser.loadURI(whereURI, null, null, false); }, 10);
+    }
+  },
+
+  get content() {
+    return this._content;
+  },
+
+  handleEvent: function (aEvent) {
+    switch (aEvent.type) {
+      case "DOMTitleChanged":
+        this._titleChanged(aEvent);
+        break;
+      case "TabOpen":
+        this._tabOpen(aEvent);
+        break;
+      case "TabClose":
+        this._tabClose(aEvent);
+        break;
+      case "TabSelect":
+        this._tabSelect(aEvent);
+        break;
+      case "popupshowing":
+        this._popupShowing(aEvent);
+        break;
+    }
+  },
+
+  supportsCommand : function(cmd) {
+    var isSupported = false;
+    switch (cmd) {
+      case "cmd_back":
+      case "cmd_forward":
+      case "cmd_reload":
+      case "cmd_stop":
+      case "cmd_search":
+      case "cmd_go":
+      case "cmd_star":
+      case "cmd_bookmarks":
+      case "cmd_newTab":
+      case "cmd_closeTab":
+      case "cmd_switchTab":
+      case "cmd_menu":
+      case "cmd_fullscreen":
+      case "cmd_addons":
+      case "cmd_downloads":
+        isSupported = true;
+        break;
+      default:
+        isSupported = false;
+        break;
+    }
+    return isSupported;
+  },
+
+  isCommandEnabled : function(cmd) {
+    return true;
+  },
+
+  doCommand : function(cmd) {
+    var browser = this.content.browser;
+
+    switch (cmd) {
+      case "cmd_back":
+        browser.stop();
+        browser.goBack();
+        break;
+      case "cmd_forward":
+        browser.stop();
+        browser.goForward();
+        break;
+      case "cmd_reload":
+        browser.reload();
+        break;
+      case "cmd_stop":
+        browser.stop();
+        break;
+      case "cmd_search":
+      {
+        LocationBar.search();
+        break;
+      }
+      case "cmd_go":
+      {
+        LocationBar.goToURI();
+        break;
+      }
+      case "cmd_star":
+      {
+        var bookmarkURI = browser.currentURI;
+        var bookmarkTitle = browser.contentDocument.title;
+
+        var bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
+        if (bookmarks.getBookmarkIdsForURI(bookmarkURI, {}).length == 0) {
+          var bookmarkId = bookmarks.insertBookmark(bookmarks.bookmarksMenuFolder, bookmarkURI, bookmarks.DEFAULT_INDEX, bookmarkTitle);
+          document.getElementById("tool_star").setAttribute("starred", "true");
+
+          var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+          var favicon = document.getElementById("urlbar-favicon");
+          var faviconURI = ios.newURI(favicon.src, null, null);
+
+          var fis = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
+          fis.setAndLoadFaviconForPage(bookmarkURI, faviconURI, true);
+        }
+        else {
+          Bookmarks.edit(bookmarkURI);
+        }
+        break;
+      }
+      case "cmd_bookmarks":
+        Bookmarks.list();
+        break;
+      case "cmd_newTab":
+        this.content.addBrowser("about:blank", null, null, false);
+        break;
+      case "cmd_closeTab":
+        this.content.removeBrowser();
+        break;
+      case "cmd_switchTab":
+        this.content.select();
+        break;
+      case "cmd_menu":
+      {
+//        var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+//        fp.init(window, "Pick a file", Ci.nsIFilePicker.modeOpen);
+//        fp.appendFilters(Ci.nsIFilePicker.filterAll);
+//        fp.show();
+
+        var menu = document.getElementById("mainmenu");
+        menu.openPopup(window.screenX, window.screenY, true);
+        break;
+      }
+      case "cmd_fullscreen":
+        window.fullScreen = window.fullScreen ? false : true;
+        break;
+      case "cmd_addons":
+      {
+        const EMTYPE = "Extension:Manager";
+
+        var aOpenMode = "extensions";
+        var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
+        var needToOpen = true;
+        var windowType = EMTYPE + "-" + aOpenMode;
+        var windows = wm.getEnumerator(windowType);
+        while (windows.hasMoreElements()) {
+          var theEM = windows.getNext().QueryInterface(Ci.nsIDOMWindowInternal);
+          if (theEM.document.documentElement.getAttribute("windowtype") == windowType) {
+            theEM.focus();
+            needToOpen = false;
+            break;
+          }
+        }
+
+        if (needToOpen) {
+          const EMURL = "chrome://mozapps/content/extensions/extensions.xul?type=" + aOpenMode;
+          const EMFEATURES = "chrome,dialog=no,resizable=yes";
+          window.openDialog(EMURL, "", EMFEATURES);
+        }
+        break;
+      }
+      case "cmd_downloads":
+        Cc["@mozilla.org/download-manager-ui;1"].getService(Ci.nsIDownloadManagerUI).show(window);
+    }
+  }
+};
+
+
+function ProgressController(aBrowser) {
+  this.init(aBrowser);
+}
+
+ProgressController.prototype = {
+  _browser : null,
+
+  init : function(aBrowser) {
+    this._browser = aBrowser;
+    this._browser.addProgressListener(this, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+  },
+
+  onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus) {
+    if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
+      if (aRequest && aWebProgress.DOMWindow == this._browser.contentWindow) {
+        if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
+          LocationBar.update(TOOLBARSTATE_LOADING);
+        }
+        else if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
+          this._browser.zoomController.scale = 1;
+          LocationBar.update(TOOLBARSTATE_LOADED);
+        }
+      }
+    }
+
+    if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) {
+      if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
+        aWebProgress.DOMWindow.focus();
+        //aWebProgress.DOMWindow.scrollbars.visible = false;
+      }
+    }
+  },
+
+  // This method is called to indicate progress changes for the currently
+  // loading page.
+  onProgressChange : function(aWebProgress, aRequest, aCurSelf, aMaxSelf, aCurTotal, aMaxTotal) {
+  },
+
+  // This method is called to indicate a change to the current location.
+  onLocationChange : function(aWebProgress, aRequest, aLocation) {
+    if (aWebProgress.DOMWindow == this._browser.contentWindow) {
+      LocationBar.setURI(aLocation.spec);
+    }
+  },
+
+  // This method is called to indicate a status changes for the currently
+  // loading page.  The message is already formatted for display.
+  onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) {
+  },
+
+  // This method is called when the security state of the browser changes.
+  onSecurityChange : function(aWebProgress, aRequest, aState) {
+  },
+
+  /* nsISupports */
+  QueryInterface : function(aIID) {
+    if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
+        aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
+        aIID.equals(Components.interfaces.nsISupports))
+      return this;
+
+    throw Components.results.NS_ERROR_NO_INTERFACE;
+  }
+};
+/*
+window.addEventListener("keydown", fskey, true);
+
+function fskey(aEvent) {
+  alert(aEvent.keyCode);
+  if (117 == aEvent.keyCode) {
+  }
+}
+*/
+
+var MouseController = function(browser) {
+  this.init(browser);
+}
+
+MouseController.prototype = {
+  _browser: null,
+  _contextID : null,
+
+  init: function(aBrowser)
+  {
+    this._browser = aBrowser;
+    this._browser.addEventListener("mousedown", this, true);
+    this._browser.addEventListener("mouseup",this, true);
+  },
+
+  handleEvent: function(e)
+  {
+    if (! e.type in this)
+      dump("MouseController called with unknown event type " + e.type + "\n");
+    this[e.type](e);
+  },
+
+  mousedown: function(aEvent)
+  {
+    var self = this;
+    this._contextID = setTimeout(function() { self.contextMenu(aEvent); }, 900);
+
+    if (aEvent.target instanceof HTMLInputElement ||
+        aEvent.target instanceof HTMLTextAreaElement ||
+        aEvent.target instanceof HTMLSelectElement)
+      return;
+
+    // Check to see if we should treat this as a double-click
+    if (this.firstEvent &&
+        (aEvent.timeStamp - this.firstEvent.timeStamp) < 400 &&
+        Math.abs(aEvent.clientX - this.firstEvent.clientX) < 30 &&
+        Math.abs(aEvent.clientY - this.firstEvent.clientY) < 30) {
+      this.dblclick(aEvent);
+      return;
+    }
+
+    this.lastEvent = this.firstEvent = aEvent;
+    this.fingerDistance = 100;
+    this.mousemove = aEvent.button != 2 ? this.mousePan : this.mouseZoom;
+    this._browser.addEventListener("mousemove", this, true);
+
+    //FIX Show scrollbars now
+
+    aEvent.stopPropagation();
+    aEvent.preventDefault();
+  },
+
+  mouseup: function(aEvent)
+  {
+    this._browser.removeEventListener("mousemove", this, true);
+    if (this._contextID) {
+      clearTimeout(this._contextID);
+      this._contextID = null;
+    }
+
+    //FIX Hide scrollbars now
+
+    // Cancel link clicks if we've been dragging for a while
+    var totalDistance = Math.sqrt(
+        Math.pow(this.firstEvent.clientX - aEvent.clientX, 2) +
+        Math.pow(this.firstEvent.clientY - aEvent.clientY, 2));
+    if (totalDistance > 10)
+      aEvent.preventDefault();
+
+    // Keep scrolling if there is enough momentum
+    /*
+    if (this.lastEvent && "momentum" in this.lastEvent && this.mousemove == this.mousePan)
+    {
+      var speedX = this.lastEvent.momentum.x / this.lastEvent.momentum.time;
+      var speedY = this.lastEvent.momentum.y / this.lastEvent.momentum.time;
+      const speedLimit = 6;
+      if (Math.abs(speedY) > speedLimit)
+          speedY = speedY > 0 ? speedLimit : -speedLimit;
+      if (Math.abs(speedX) > speedLimit)
+          speedX = speedX > 0 ? speedLimit : -speedLimit;
+
+      var lastCall = Date.now();
+      browser = this._browser;
+      const speedFactor = 0.1;
+      const decayFactor = 0.9995;
+      const cutoff = 0.2;
+      var intervalId = setInterval( function() {
+        var elapsed = (Date.now() - lastCall);
+        var x = elapsed * speedX * speedFactor, y = elapsed * speedY * speedFactor;
+        browser.contentWindow.scrollBy(-x, -y);
+        var slowdown = Math.pow(decayFactor, elapsed);
+        speedX *= slowdown;
+        speedY *= slowdown;
+        if (Math.abs(speedX) < cutoff && Math.abs(speedY) < cutoff)
+          clearInterval(intervalId);
+      }, 0);
+    }*/
+  },
+
+  mouseZoom: function(e)
+  {
+    var deltaX = e.screenX - this.firstEvent.screenX + 100;
+    var deltaY = e.screenY - this.firstEvent.screenY;
+    var newDist = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
+    var scale = newDist / this.fingerDistance;
+    if (e.screenX < this.firstEvent.screenX && scale > 1)
+      scale = 1 / scale;
+    var newZoom = scale * this._browser.markupDocumentViewer.fullZoom;
+    this.fingerDistance = Math.max(0.1, newDist);
+    this._browser.zoomController.scale = newZoom;
+    this.lastEvent = e;
+
+    //FIX Adjust scrollbars now
+    e.stopPropagation();
+    e.preventDefault();
+  },
+
+  mousePan: function(aEvent)
+  {
+    var x = aEvent.clientX - this.lastEvent.clientX;
+    var y = aEvent.clientY - this.lastEvent.clientY;
+    if (Math.abs(x) < 5 && Math.abs(y) < 5)
+      return;
+
+    if (this._contextID) {
+      clearTimeout(this._contextID);
+      this._contextID = null;
+    }
+
+    if (this.lastEvent) {
+      aEvent.momentum = {
+        time: Math.max(aEvent.timeStamp - this.lastEvent.timeStamp, 1),
+        x: x,
+        y: y
+      };
+    }
+    this._browser.contentWindow.scrollBy(-x, -y);
+    this.lastEvent = aEvent;
+
+    //FIX Adjust scrollbars now
+
+    aEvent.stopPropagation();
+    aEvent.preventDefault();
+  },
+
+  dblclick: function(aEvent)
+  {
+    // Find the target by walking the dom. We want to zoom in on the block elements
+    var target = aEvent.target;
+    aEvent.preventDefault();
+    while (target && target.nodeName != "HTML") {
+      var disp = window.getComputedStyle(target, "").getPropertyValue("display");
+      if (!disp.match(/(inline)/g)) {
+        this._browser.zoomController.toggleZoom(target);
+        break;
+      }
+      else {
+        target = target.parentNode;
+      }
+    }
+    aEvent.stopPropagation();
+    aEvent.preventDefault();
+  },
+
+  contextMenu: function(aEvent)
+  {
+    if (this._contextID && this._browser.contextMenu) {
+      document.popupNode = aEvent.target;
+      var popup = document.getElementById(this._browser.contextMenu);
+      popup.openPopup(this._browser, "", aEvent.clientX, aEvent.clientY, true, false);
+
+      this._browser.removeEventListener("mousemove", this, true);
+      this._contextID = null;
+
+      aEvent.stopPropagation();
+      aEvent.preventDefault();
+    }
+  },
+
+  drag : function(aEvent){
+    aEvent.stopPropagation();
+    aEvent.preventDefault();
+    return true;
+  },
+
+  dragstart : function(aEvent){
+    return this.drag(aEvent);
+  },
+
+  draggesture : function(aEvent){
+    return this.drag(aEvent);
+  }
+}
+
+
+function ZoomController(aBrowser) {
+  this._browser = aBrowser;
+};
+
+// ZoomControler sets browser zoom
+ZoomController.prototype = {
+  _minScale : 0.1,
+  _maxScale : 3,
+  _target : null,
+
+  set scale(s)
+  {
+    var clamp = Math.min(this._maxScale, Math.max(this._minScale, s));
+    clamp = Math.floor(clamp * 1000) / 1000;  // Round to 3 digits
+    if (clamp == this._browser.markupDocumentViewer.fullZoom)
+      return;
+
+    this._browser.markupDocumentViewer.fullZoom = clamp;
+
+    // If we've zoomed out of the viewport, scroll us back in
+    var leftEdge = this._browser.contentWindow.scrollX + this._browser.contentWindow.document.documentElement.clientWidth;
+    var scrollX = this._browser.contentWindow.document.documentElement.scrollWidth - leftEdge;
+    if (scrollX < 0)
+      this._browser.contentWindow.scrollBy(scrollX, 0);
+  },
+
+  get scale()
+  {
+    return this._browser.markupDocumentViewer.fullZoom;
+  },
+
+  reset: function()
+  {
+    this._minScale = ZoomController.prototype._minScale;
+    this._maxScale = ZoomController.prototype._maxScale;
+  },
+
+  fitContent: function()
+  {
+    this._target = null;
+    try {
+      var oldScale = this.scale;
+      this.scale = 1;    // reset the scale to 1 forces document to preferred size
+      var body = this._browser.contentWindow.document.body;
+      var html = this._browser.contentWindow.document.documentElement;
+      var newScale = this.scale;
+      var finalWidth = html.clientWidth;
+    }
+    catch(e) {
+      dump(e + "\n");
+      return;
+    }
+
+    var prefScrollWidth = Math.max(html.scrollWidth, body.scrollWidth); // empirical hack, no idea why
+    if (prefScrollWidth > (this._browser.boxObject.width - 10) )  {
+      // body wider than window, scale id down
+      // we substract 10 to compensate for 10 pixel browser left margin
+      newScale = (this._browser.boxObject.width ) / prefScrollWidth;
+      finalWidth = prefScrollWidth;
+    }
+    body.style.minWidth = body.style.maxWidth = (finalWidth -20) + "px";
+    this._minScale = Math.max(this._minScale, newScale);
+    this.scale = newScale;
+  },
+
+  getPagePosition: function (el)
+  {
+    var r = el.getBoundingClientRect();
+    retVal = {
+      width: r.right - r.left,
+      height: r.bottom - r.top,
+      x: r.left + this._browser.contentWindow.scrollX,
+      y: r.top + this._browser.contentWindow.scrollY
+    };
+    return retVal;
+  },
+
+  getWindowRect: function()
+  {
+    return {
+      x: this._browser.contentWindow.scrollX,
+      y: this._browser.contentWindow.scrollY,
+      width: this._browser.boxObject.width / this.scale,
+      height: this._browser.boxObject.height / this.scale
+    };
+  },
+
+  toggleZoom: function(el)
+  {
+    if (!el) return;
+
+    if (this.scale == 1 || el != this._target) {
+      this.zoomToElement(el);
+      this._target = el;
+    }
+    else {
+      this.scale = 1;
+      this._target = null;
+    }
+  },
+
+  zoomToElement: function(el)
+  {
+    var margin = 8;
+
+    // First get the width of the element so we can scale to its width
+    var elRect = this.getPagePosition(el);
+    this.scale = (this._browser.boxObject.width) / (elRect.width + 2 * margin);
+
+    // Now that we are scaled, we need to scroll to the element
+    elRect = this.getPagePosition(el);
+    winRect = this.getWindowRect();
+    this._browser.contentWindow.scrollTo(Math.max(elRect.x - margin, 0), Math.max(0, elRect.y - margin));
+  }
+};
new file mode 100644
--- /dev/null
+++ b/chrome/content/browser.xul
@@ -0,0 +1,189 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is Mozilla Mobile Browser.
+   -
+   - The Initial Developer of the Original Code is
+   - Mozilla Corporation.
+   - Portions created by the Initial Developer are Copyright (C) 2008
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -   Brad Lassey <blassey@mozilla.com>
+   -   Mark Finkle <mfinkle@mozila.com>
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+   - in which case the provisions of the GPL or the LGPL are applicable instead
+   - of those above. If you wish to allow use of your version of this file only
+   - under the terms of either the GPL or the LGPL, and not to allow others to
+   - use your version of this file under the terms of the MPL, indicate your
+   - decision by deleting the provisions above and replace them with the notice
+   - and other provisions required by the LGPL or the GPL. If you do not delete
+   - the provisions above, a recipient may use your version of this file under
+   - the terms of any one of the MPL, the GPL or the LGPL.
+   -
+   - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/deckbrowser.css" type="text/css"?>
+
+<!DOCTYPE window SYSTEM "chrome://browser/locale/browser.dtd">
+
+<window id="main-window" title="&browser.title;"
+        width="800" height="480"
+        onload="Browser.startup();"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <script src="chrome://global/content/inlineSpellCheckUI.js"/>
+  <script src="chrome://browser/content/commandUtil.js"/>
+  <script src="chrome://browser/content/browser.js"/>
+
+  <commandset id="cmdset_main">
+    <command id="cmd_back" label="&back.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_forward" label="&forward.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_reload" label="&reload.label;"  collapsed="true" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_stop" label="&stop.label;"  collapsed="true" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_search" label="&search.label;" collapsed="true" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_go" label="&go.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_star" label="&star.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_bookmarks" label="&bookmarks.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_newTab" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_closeTab" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_switchTab" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_menu" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_fullscreen" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_addons" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_downloads" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_scrollPageUp" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_scrollPageDown" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_cut" label="&cut.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_copy" label="&copy.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_copylink" label="&copylink.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_paste" label="&paste.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_delete" label="&delete.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+    <command id="cmd_selectAll" label="&selectAll.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
+  </commandset>
+
+  <keyset id="mainKeyset">
+    <key id="key_menu" keycode="VK_F4" command="cmd_menu"/>
+    <key id="key_fullscreen" keycode="VK_F6" command="cmd_fullscreen"/>
+
+    <key id="key_back" keycode="VK_LEFT" command="cmd_back" modifiers="control"/>
+    <key id="key_forward" keycode="VK_RIGHT" command="cmd_forward" modifiers="control"/>
+    <key id="key_back2" keycode="VK_BACK" command="cmd_back"/>
+    <key id="key_forward2" keycode="VK_BACK" command="cmd_forward" modifiers="shift"/>
+    <key id="key_reload" keycode="VK_F5" command="cmd_reload"/>
+
+    <key id="key_pageUp" keycode="VK_UP" command="cmd_scrollPageUp" modifiers="shift"/>
+    <key id="key_pageDown" keycode="VK_DOWN" command="cmd_scrollPageDown" modifiers="shift"/>
+
+    <key id="key_newTab" key="T" command="cmd_newTab" modifiers="control"/>
+    <key id="key_removeTab" key="W" command="cmd_removeTab" modifiers="control"/>
+    <key id="key_switchTab" key="S" command="cmd_switchTab" modifiers="control"/>
+
+    <key id="key_downloads" key="J" command="cmd_downloads" modifiers="control"/>
+  </keyset>
+
+  <popupset id="mainPopupSet">
+    <menupopup id="mainmenu">
+      <menuitem label="Hello"/>
+      <menuitem label="World"/>
+    </menupopup>
+
+    <panel type="autocomplete" id="popup_autocomplete" noautofocus="true"/>
+
+    <panel id="bookmark_edit" hidden="true">
+      <hbox flex="1" align="top">
+        <image id="bookmark_star"/>
+        <vbox flex="1">
+          <label id="bookmark_title" value="&editBookmark.title;" flex="1"/>
+          <button label="&removeBookmark.label;" oncommand="Bookmarks.remove();"/>
+        </vbox>
+      </hbox>
+      <separator/>
+      <vbox>
+        <label value="&bookmarkURL.label;" control="bookmark_url"/>
+        <textbox id="bookmark_url"/>
+        <separator class="thin"/>
+        <label value="&bookmarkName.label;" control="bookmark_name"/>
+        <textbox id="bookmark_name"/>
+      </vbox>
+      <separator/>
+      <hbox>
+        <spacer flex="1"/>
+        <button label="&saveBookmark.label;" oncommand="Bookmarks.save();"/>
+        <button label="&closeBookmark.label;" oncommand="Bookmarks.close();"/>
+      </hbox>
+    </panel>
+
+    <panel id="bookmark_picker" hidden="true">
+      <richlistbox id="bookmark_list" style="border: none !important;">
+      </richlistbox>
+    </panel>
+
+    <menupopup id="popup_content">
+      <menuitem id="menuitem_noSuggestions" disabled="true" label="&noSuggestions.label;"/>
+      <menuitem id="menuitem_addToDictionary" label="&addToDictionary.label;" oncommand="InlineSpellCheckerUI.addToDictionary();"/>
+      <menuseparator id="menusep_spellcheck"/>
+      <!--
+      <menuitem id="menuitem_cut" command="cmd_cut"/>
+      <menuitem id="menuitem_copy" command="cmd_copy"/>
+      <menuitem id="menuitem_paste" command="cmd_paste"/>
+      <menuitem id="menuitem_delete" command="cmd_delete"/>
+      <menuseparator id="menusep_edit"/>
+      <menuitem id="menuitem_selectAll" command="cmd_selectAll"/>
+      <menuseparator id="menusep_copylink"/>
+      <menuitem id="menuitem_copylink" command="cmd_copylink"/>
+      <menuseparator id="menusep_tabs"/>
+      -->
+      <menuitem label="&newTab.label;" command="cmd_newTab"/>
+      <menuitem label="&closeTab.label;" command="cmd_closeTab"/>
+      <menuitem label="&switchTab.label;" command="cmd_switchTab"/>
+      <menuseparator id="menusep_tools"/>
+      <menuitem label="&addons.label;" command="cmd_addons"/>
+    </menupopup>
+  </popupset>
+
+  <toolbox>
+    <toolbar id="toolbar_main" mode="icons">
+      <toolbarbutton id="tool_back" tooltiptext="&back.tooltip;" command="cmd_back"/>
+      <toolbarbutton id="tool_forward" tooltiptext="&forward.tooltip;" command="cmd_forward"/>
+      <toolbaritem id="urlbar-container" flex="1">
+        <stack id="urlbar-image-stack">
+          <image id="urlbar-throbber" src="throbber.png"/>
+          <image id="urlbar-favicon" src=""/>
+        </stack>
+        <textbox id="urlbar" type="autocomplete" autocompletesearch="history" enablehistory="false" maxrows="6" completeselectedindex="true" flex="1"
+                 ontextentered="LocationBar.goToURI();" ontextreverted="LocationBar.revertURI();"/>
+        <hbox id="urlbar-icons">
+          <toolbarbutton id="tool_search" tooltiptext="&search.tooltip;" command="cmd_search"/>
+          <toolbarbutton id="tool_go" tooltiptext="&go.tooltip;" command="cmd_go"/>
+          <toolbarbutton id="tool_reload" tooltiptext="&reload.tooltip;" command="cmd_reload"/>
+          <toolbarbutton id="tool_stop" tooltiptext="&stop.tooltip;" command="cmd_stop"/>
+        </hbox>
+      </toolbaritem>
+      <toolbarbutton id="tool_star" tooltiptext="&star.tooltip;" command="cmd_star"/>
+      <toolbarbutton id="tool_bookmarks" tooltiptext="&bookmarks.tooltip;" command="cmd_bookmarks"/>
+    </toolbar>
+  </toolbox>
+
+  <vbox id="browser" flex="1">
+    <deckbrowser id="content" contentcontextmenu="popup_content" autocompletepopup="popup_autocomplete" flex="1">
+    </deckbrowser>
+  </vbox>
+
+</window>
new file mode 100644
--- /dev/null
+++ b/chrome/content/commandUtil.js
@@ -0,0 +1,197 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Finkle <mfinkle@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * Command Updater
+ */
+var CommandUpdater = {
+  /**
+   * Gets a controller that can handle a particular command.
+   * @param   command
+   *          A command to locate a controller for, preferring controllers that
+   *          show the command as enabled.
+   * @returns In this order of precedence:
+   *            - the first controller supporting the specified command
+   *              associated with the focused element that advertises the
+   *              command as ENABLED
+   *            - the first controller supporting the specified command
+   *              associated with the global window that advertises the
+   *              command as ENABLED
+   *            - the first controller supporting the specified command
+   *              associated with the focused element
+   *            - the first controller supporting the specified command
+   *              associated with the global window
+   */
+  _getControllerForCommand: function(command) {
+    try {
+      var controller = top.document.commandDispatcher.getControllerForCommand(command);
+      if (controller && controller.isCommandEnabled(command))
+        return controller;
+    }
+    catch(e) {
+    }
+    var controllerCount = window.controllers.getControllerCount();
+    for (var i = 0; i < controllerCount; ++i) {
+      var current = window.controllers.getControllerAt(i);
+      try {
+        if (current.supportsCommand(command) && current.isCommandEnabled(command))
+          return current;
+      }
+      catch (e) {
+      }
+    }
+    return controller || window.controllers.getControllerForCommand(command);
+  },
+
+  /**
+   * Updates the state of a XUL <command> element for the specified command
+   * depending on its state.
+   * @param   command
+   *          The name of the command to update the XUL <command> element for
+   */
+  updateCommand: function(command) {
+    var enabled = false;
+    try {
+      var controller = this._getControllerForCommand(command);
+      if (controller) {
+        enabled = controller.isCommandEnabled(command);
+      }
+    }
+    catch(ex) { }
+
+    this.enableCommand(command, enabled);
+  },
+
+  /**
+   * Updates the state of a XUL <command> element for the specified command
+   * depending on its state.
+   * @param   command
+   *          The name of the command to update the XUL <command> element for
+   */
+  updateCommands: function(_commands) {
+    var commands = _commands.split(",");
+    for (var command in commands) {
+      this.updateCommand(commands[command]);
+    }
+  },
+
+  /**
+   * Enables or disables a XUL <command> element.
+   * @param   command
+   *          The name of the command to enable or disable
+   * @param   enabled
+   *          true if the command should be enabled, false otherwise.
+   */
+  enableCommand: function(command, enabled) {
+    var element = document.getElementById(command);
+    if (!element)
+      return;
+    if (enabled)
+      element.removeAttribute("disabled");
+    else
+      element.setAttribute("disabled", "true");
+  },
+
+  /**
+   * Performs the action associated with a specified command using the most
+   * relevant controller.
+   * @param   command
+   *          The command to perform.
+   */
+  doCommand: function(command) {
+    var controller = this._getControllerForCommand(command);
+    if (!controller)
+      return;
+    controller.doCommand(command);
+  },
+
+  /**
+   * Changes the label attribute for the specified command.
+   * @param   command
+   *          The command to update.
+   * @param   labelAttribute
+   *          The label value to use.
+   */
+  setMenuValue: function(command, labelAttribute) {
+    var commandNode = top.document.getElementById(command);
+    if (commandNode)
+    {
+      var label = commandNode.getAttribute(labelAttribute);
+      if ( label )
+        commandNode.setAttribute('label', label);
+    }
+  },
+
+  /**
+   * Changes the accesskey attribute for the specified command.
+   * @param   command
+   *          The command to update.
+   * @param   valueAttribute
+   *          The value attribute to use.
+   */
+  setAccessKey: function(command, valueAttribute) {
+    var commandNode = top.document.getElementById(command);
+    if (commandNode)
+    {
+      var value = commandNode.getAttribute(valueAttribute);
+      if ( value )
+        commandNode.setAttribute('accesskey', value);
+    }
+  },
+
+  /**
+   * Inform all the controllers attached to a node that an event has occurred
+   * (e.g. the tree controllers need to be informed of blur events so that they can change some of the
+   * menu items back to their default values)
+   * @param   node
+   *          The node receiving the event
+   * @param   event
+   *          The event.
+   */
+  onEvent: function(node, event) {
+    var numControllers = node.controllers.getControllerCount();
+    var controller;
+
+    for ( var controllerIndex = 0; controllerIndex < numControllers; controllerIndex++ )
+    {
+      controller = node.controllers.getControllerAt(controllerIndex);
+      if ( controller )
+        controller.onEvent(event);
+    }
+  }
+};
new file mode 100644
--- /dev/null
+++ b/chrome/content/content.css
@@ -0,0 +1,42 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Finkle <mfinkle@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+@namespace html url(http://www.w3.org/1999/xhtml);
+
+html|* {
+  cursor: none !important;
+}
new file mode 100644
--- /dev/null
+++ b/chrome/content/deckbrowser.css
@@ -0,0 +1,7 @@
+deckpage {
+    -moz-binding: url("chrome://browser/content/deckbrowser.xml#deckpage");
+}
+
+deckbrowser {
+    -moz-binding: url("chrome://browser/content/deckbrowser.xml#deckbrowser");
+}
new file mode 100644
--- /dev/null
+++ b/chrome/content/deckbrowser.xml
@@ -0,0 +1,248 @@
+<?xml version="1.0"?>
+<!DOCTYPE bindings PUBLIC "-//MOZILLA//DTD XBL V1.0//EN" "http://www.mozilla.org/xbl">
+
+<bindings
+    xmlns="http://www.mozilla.org/xbl"
+    xmlns:xbl="http://www.mozilla.org/xbl"
+    xmlns:html="http://www.w3.org/1999/xhtml"
+    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <binding id="deckpage">
+    <content>
+      <xul:stack anonid="page" class="deckpage-container" flex="1">
+        <html:canvas anonid="canvas" class="deckpage-canvas"/>
+        <xul:vbox align="start">
+          <xul:image anonid="close" class="deckpage-close"/>
+        </xul:vbox>
+      </xul:stack>
+    </content>
+
+  </binding>
+
+  <binding id="deckbrowser">
+    <content>
+      <xul:deck anonid="container" class="deckbrowser-container" flex="1">
+      </xul:deck>
+      <xul:vbox anonid="tabspace" class="deckbrowser-tabspace" collapsed="true" align="center" flex="1">
+        <xul:description anonid="title" class="deckbrowser-title" crop="end"/>
+        <xul:description anonid="uri" class="deckbrowser-uri" crop="center"/>
+        <xul:hbox anonid="tabs" class="deckbrowser-tabs" flex="1" style="overflow-x: auto">
+        </xul:hbox>
+      </xul:vbox>
+    </content>
+
+    <implementation>
+      <constructor>
+      </constructor>
+
+      <field name="_container" readonly="true">
+        document.getAnonymousElementByAttribute(this, "anonid", "container");
+      </field>
+
+      <field name="_browsers">
+        null
+      </field>
+
+      <property name="browser" readonly="true">
+        <getter>
+          return this._container.selectedPanel;
+        </getter>
+      </property>
+
+      <property name="browsers" readonly="true">
+        <getter>
+          <![CDATA[
+            if (!this._browsers) {
+              var browsers = [];
+              for (var i = 0; i < this._container.childNodes.length; i++)
+                browsers.push(this._container.childNodes[i]);
+              this._browsers = browsers;
+            }
+            return this._browsers;
+          ]]>
+        </getter>
+      </property>
+
+      <method name="addBrowser">
+        <parameter name="aURI"/>
+        <parameter name="aReferrer"/>
+        <parameter name="aPostData"/>
+        <parameter name="aFixUp"/>
+        <body>
+          <![CDATA[
+            var b = document.createElement("browser");
+            b.setAttribute("class", "deckbrowser-browser");
+            b.setAttribute("flex", "1");
+            b.setAttribute("type", "content-targetable");
+            if (this.hasAttribute("autocompletepopup"))
+              b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
+            if (this.hasAttribute("contentcontextmenu"))
+              b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
+
+            this._container.appendChild(b);
+            this._container.selectedPanel = b;
+            this._browsers = null;
+
+            if (aURI != "about:blank") {
+              b.stop();
+              this.loadURI(aURI, aReferrer, aPostData, aFixup);
+            }
+
+            // Broadcast creation
+            var event = document.createEvent("Event");
+            event.initEvent("TabOpen", true, false);
+            b.dispatchEvent(event);
+
+            return b;
+          ]]>
+        </body>
+      </method>
+
+      <method name="removeBrowser">
+        <parameter name="aBrowser"/>
+        <body>
+          <![CDATA[
+            this._browsers = null;
+            if (!aBrowser)
+              aBrowser = this.browser;
+
+            var count = this._container.childNodes.length;
+            if (count == 1) {
+                var self = this;
+                setTimeout(function() { self.addBrowser("about:blank"); }, 0);
+            }
+
+            var currentIndex = this._container.selectedIndex;
+            var index = -1;
+            for (var i = 0; i<count; i++) {
+              if (this._container.childNodes[i] == aBrowser)
+                index = i;
+            }
+
+            // Broadcast removal
+            var event = document.createEvent("Event");
+            event.initEvent("TabClose", true, false);
+            aBrowser.dispatchEvent(event);
+
+            this._container.removeChild(aBrowser);
+
+            // Select the new tab
+            var newIndex = -1;
+            if (currentIndex > index)
+              newIndex = currentIndex - 1;
+            else if (currentIndex < index)
+              newIndex = currentIndex;
+            else {
+              newIndex = (index == count - 1) ? index - 1 : index;
+            }
+            this._container.selectedIndex = newIndex;
+          ]]>
+        </body>
+      </method>
+
+      <method name="show">
+        <parameter name="aBrowser"/>
+        <body>
+          <![CDATA[
+            if (aBrowser.constructor.name == "Number")
+              aBrowser = this.browsers[aBrowser];
+            this._container.selectedPanel = aBrowser;
+
+            var event = document.createEvent("Event");
+            event.initEvent("TabSelect", true, false);
+            aBrowser.dispatchEvent(event);
+          ]]>
+        </body>
+      </method>
+
+      <method name="loadURI">
+        <parameter name="aURI"/>
+        <parameter name="aReferrer"/>
+        <parameter name="aPostData"/>
+        <parameter name="aFixUp"/>
+        <body>
+          <![CDATA[
+            if (aPostData === undefined)
+              aPostData = null;
+            var flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
+            if (aFixUp)
+              flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+
+            this.browser.loadURIWithFlags(aURI, flags, aReferrer, null, aPostData);
+          ]]>
+        </body>
+      </method>
+
+      <method name="select">
+        <body>
+          <![CDATA[
+            var tabspace = document.getAnonymousElementByAttribute(this, "anonid", "tabspace");
+            var tabs = document.getAnonymousElementByAttribute(this, "anonid", "tabs");
+            while (tabs.childNodes.length > 0)
+              tabs.removeChild(tabs.childNodes[0]);
+
+            var browsers = this.browsers;
+            for (var i=0; i<browsers.length; i++) {
+              var webContent = browsers[i].contentWindow;
+              var viewW = webContent.innerWidth;
+              var viewH = webContent.innerHeight;
+              var canvasW = this.boxObject.width / 1.5;
+              var canvasH = (viewH / viewW) * canvasW;
+
+              var deckpage = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "deckpage");
+              tabs.appendChild(deckpage);
+
+              var canvas = document.getAnonymousElementByAttribute(deckpage, "anonid", "canvas");
+              canvas.setAttribute("width", canvasW);
+              canvas.setAttribute("height", canvasH);
+              canvas.setAttribute("left", "10");
+              canvas.setAttribute("top", "10");
+
+              let self = this;
+              let target = browsers[i];
+
+              var page = document.getAnonymousElementByAttribute(deckpage, "anonid", "page");
+              function _selectTab(aEvent) {
+                self.show(target);
+                tabspace.collapsed = true;
+                self._container.collapsed = false;
+              }
+              page.addEventListener("click", _selectTab, false);
+
+              var close = document.getAnonymousElementByAttribute(deckpage, "anonid", "close");
+              function _closeTab(aEvent) {
+                self.removeBrowser(target);
+                tabspace.collapsed = true;
+                self._container.collapsed = false;
+              };
+              close.addEventListener("click", _closeTab, false);
+
+              let title = document.getAnonymousElementByAttribute(this, "anonid", "title");
+              let uri = document.getAnonymousElementByAttribute(this, "anonid", "uri");
+              function _hoverTab(aEvent) {
+                title.value = target.contentDocument.title;
+                uri.value = target.currentURI.spec;
+              };
+              page.addEventListener("mouseover", _hoverTab, false);
+
+              var ctx = canvas.getContext("2d");
+              ctx.clearRect(0, 0, canvasW, canvasH);
+              ctx.save();
+              ctx.scale(canvasW/viewW, canvasH/viewH);
+              ctx.drawWindow(webContent, 0, 0, viewW, viewH, "rgba(0,0,0,0)");
+              ctx.restore();
+            }
+
+            this._container.collapsed = true;
+            tabspace.collapsed = false;
+          ]]>
+        </body>
+      </method>
+
+    </implementation>
+
+    <handlers>
+    </handlers>
+  </binding>
+
+</bindings>
new file mode 100644
--- /dev/null
+++ b/chrome/content/scrollbars.css
@@ -0,0 +1,55 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Finkle <mfinkle@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Style the scrollbars */
+scrollbar {
+-moz-appearance: none !important;
+background-color: transparent !important;
+}
+
+scrollbarbutton {
+-moz-appearance: none !important;
+display: none !important;
+}
+
+thumb {
+  min-width: 10px !important;
+  -moz-appearance: none !important;
+  background-color: gray !important;
+  border: 1px solid gray !important;
+  -moz-border-radius: 4px !important;
+}
new file mode 100644
--- /dev/null
+++ b/chrome/jar.mn
@@ -0,0 +1,35 @@
+#filter substitution
+
+browser.jar:
+% content browser %content/
+* content/browser.xul                  (content/browser.xul)
+  content/browser.js                   (content/browser.js)
+  content/commandUtil.js               (content/commandUtil.js)
+  content/deckbrowser.xml              (content/deckbrowser.xml)
+  content/deckbrowser.css              (content/deckbrowser.css)
+  content/scrollbars.css               (content/scrollbars.css)
+  content/content.css                  (content/content.css)
+% content branding %branding/
+% locale branding @AB_CD@ %branding/
+  branding/brand.dtd                   (locale/@AB_CD@/brand/brand.dtd)
+  branding/brand.properties            (locale/@AB_CD@/brand/brand.properties)
+
+classic.jar:
+% skin browser classic/1.0 %
+  browser.css                          (skin/browser.css)
+  images/bookmarks.png                 (skin/images/bookmarks.png)
+  images/close.png                     (skin/images/close.png)
+  images/default-favicon.png           (skin/images/default-favicon.png)
+  images/go-arrow.png                  (skin/images/go-arrow.png)
+  images/page-starred.png              (skin/images/page-starred.png)
+  images/search-glass.png              (skin/images/search-glass.png)
+  images/star-page.png                 (skin/images/star-page.png)
+  images/starred48.png                 (skin/images/starred48.png)
+  images/tap-n-hold.png                (skin/images/tap-n-hold.png)
+  images/throbber.png                  (skin/images/throbber.png)
+  images/throbber.gif                  (skin/images/throbber.gif)
+  images/toolbar.png                   (skin/images/toolbar.png)
+
+@AB_CD@.jar:
+% locale browser @AB_CD@ %
+  browser.dtd                          (locale/@AB_CD@/browser.dtd)
new file mode 100644
--- /dev/null
+++ b/chrome/locale/en-US/brand/brand.dtd
@@ -0,0 +1,2 @@
+<!ENTITY  brandShortName  "Firefox">
+<!ENTITY  brandFullName   "Firefox">
new file mode 100644
--- /dev/null
+++ b/chrome/locale/en-US/brand/brand.properties
@@ -0,0 +1,2 @@
+brandShortName=Firefox
+brandFullName=Firefox
new file mode 100644
--- /dev/null
+++ b/chrome/locale/en-US/browser.dtd
@@ -0,0 +1,38 @@
+<!ENTITY browser.title         "Firefox">
+<!ENTITY back.label            "Back">
+<!ENTITY back.tooltip          "Back">
+<!ENTITY forward.label         "Forward">
+<!ENTITY forward.tooltip       "Forward">
+<!ENTITY reload.label          "Reload">
+<!ENTITY reload.tooltip        "Reload">
+<!ENTITY stop.label            "Stop">
+<!ENTITY stop.tooltip          "Stop">
+<!ENTITY search.label          "Search">
+<!ENTITY search.tooltip        "Search">
+<!ENTITY go.label              "Go">
+<!ENTITY go.tooltip            "Go">
+<!ENTITY star.label            "Star">
+<!ENTITY star.tooltip          "Bookmark this page">
+<!ENTITY bookmarks.label       "Bookmarks">
+<!ENTITY bookmarks.tooltip     "View bookmarks">
+
+<!ENTITY cut.label             "Cut">
+<!ENTITY copy.label            "Copy">
+<!ENTITY copylink.label        "Copy Link Location">
+<!ENTITY paste.label           "Paste">
+<!ENTITY delete.label          "Delete">
+<!ENTITY selectAll.label       "Select All">
+<!ENTITY noSuggestions.label   "(No suggestions)">
+<!ENTITY addToDictionary.label "Add to Dictionary">
+
+<!ENTITY newTab.label          "New Tab">
+<!ENTITY closeTab.label        "Close Tab">
+<!ENTITY switchTab.label       "Switch Tab...">
+<!ENTITY addons.label          "Add-ons">
+
+<!ENTITY editBookmark.title    "Edit Bookmark">
+<!ENTITY bookmarkURL.label     "Address:">
+<!ENTITY bookmarkName.label    "Name:">
+<!ENTITY removeBookmark.label  "Remove Bookmark">
+<!ENTITY saveBookmark.label    "Done">
+<!ENTITY closeBookmark.label   "Cancel">
new file mode 100644
--- /dev/null
+++ b/chrome/skin/browser.css
@@ -0,0 +1,275 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Finkle <mfinkle@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* global skin ------------------------------------------------------------- */
+@import url(chrome://global/skin/);
+
+/* hildon stuff ------------------------------------------------------------ */
+popup,
+panel,
+menupopup {
+  padding: 16px !important;
+}
+
+menu,
+menuitem {
+  padding: 0px !important;
+  margin: 0px !important;
+  font-family: "Nokia Sans", sans-serif !important;
+  font-size: 16.75pt !important;
+}
+
+.menu-text {
+  padding-start-value: 0px !important;
+}
+
+label,
+description,
+textbox {
+  font-family: "Nokia Sans", sans-serif !important;
+  font-size: 16.75pt !important;
+}
+
+richlistitem {
+  font-family: "Nokia Sans", sans-serif !important;
+  font-size: 16.75pt !important;
+}
+
+
+/* toolbar ----------------------------------------------------------------- */
+toolbar {
+  height: 55px;
+  background-color: rgb(247, 247, 247) !important;
+  padding-left: 6px;
+  padding-right: 6px;
+}
+
+toolbar[mode="icons"] .toolbarbutton-text {
+  display: none !important;
+}
+
+toolbar[mode="text"] .toolbarbutton-icon {
+  display: none;
+}
+
+toolbarbutton {
+  -moz-appearance: none !important;
+  -moz-box-orient: vertical;
+  min-width: 0px;
+  padding: 5px !important;
+  margin: 0px !important;
+  -moz-margin-end: 0px;
+  list-style-image: url("chrome://browser/skin/images/toolbar.png");
+}
+
+toolbarbutton:hover,
+toolbarbutton:hover:active,
+toolbarbutton[open="true"] {
+  border-color: transparent;
+}
+
+#tool_back {
+  -moz-image-region: rect(0px 24px 24px 0px);
+  /*list-style-image: url("moz-icon://stock/gtk-go-back?size=toolbar");*/
+}
+
+#tool_back[disabled="true"] {
+  -moz-image-region: rect(48px 24px 72px 0px);
+  /*list-style-image: url("moz-icon://stock/gtk-go-back?size=toolbar&state=disabled");*/
+}
+
+#tool_forward {
+  -moz-image-region: rect(0px 48px 24px 24px);
+  /*list-style-image: url("moz-icon://stock/gtk-go-forward?size=toolbar");*/
+}
+
+#tool_forward[disabled="true"] {
+  -moz-image-region: rect(48px 48px 72px 24px);
+  /*list-style-image: url("moz-icon://stock/gtk-go-forward?size=toolbar&state=disabled");*/
+}
+
+#tool_reload {
+  -moz-image-region: rect(0px 96px 24px 72px);
+  /*list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar");*/
+}
+
+#tool_reload[disabled="true"] {
+  -moz-image-region: rect(48px 96px 72px 72px);
+  /*list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar&state=disabled");*/
+}
+
+#tool_stop {
+  -moz-image-region: rect(0px 72px 24px 48px);
+  /*list-style-image: url("moz-icon://stock/gtk-stop?size=toolbar");*/
+}
+
+#tool_stop[disabled="true"] {
+  -moz-image-region: rect(48px 72px 72px 48px);
+  /*list-style-image: url("moz-icon://stock/gtk-stop?size=toolbar&state=disabled");*/
+}
+
+#tool_search {
+  list-style-image: url(chrome://browser/skin/images/search-glass.png);
+}
+
+#tool_go {
+  list-style-image: url(chrome://browser/skin/images/go-arrow.png);
+}
+
+#tool_star {
+  list-style-image: url(chrome://browser/skin/images/star-page.png);
+}
+
+#tool_star[starred="true"] {
+  list-style-image: url(chrome://browser/skin/images/page-starred.png);
+}
+
+#tool_bookmarks {
+  -moz-image-region: rect(0px 192px 24px 168px);
+  /*list-style-image: url(chrome://browser/skin/images/bookmarks.png);*/
+}
+
+#urlbar-container {
+  -moz-box-orient: horizontal;
+  -moz-box-align: center;
+  background-color: #fff;
+  border: 1px solid #000;
+  -moz-border-radius: 14px;
+  margin: 8px 8px 8px 4px;
+}
+
+/* favicon images are 16x16 */
+#urlbar-image-stack {
+  width: 24px;
+  height: 24px;
+  margin: 2px 2px 2px 4px;
+}
+
+/* urlbar toolbuttons images are 24x24 */
+#urlbar-icons {
+  height: 26px;
+  -moz-box-align: center;
+  -moz-padding-end: 2px;
+}
+
+#urlbar {
+  -moz-appearance: none !important;
+  padding: 0px !important;
+  border: none !important;
+}
+
+#urlbar > .autocomplete-history-popup {
+  -moz-appearance: none !important;
+}
+
+/* bookmark editor --------------------------------------------------------- */
+#bookmark_edit {
+  padding: 4px;
+}
+
+#bookmark_star {
+  list-style-image: url("chrome://browser/skin/images/starred48.png");
+  width: 48px;
+  height: 48px;
+}
+
+#bookmark_title {
+  font-size: 130%;
+}
+
+/* bookmarks picker -------------------------------------------------------- */
+#bookmark_picker {
+  -moz-appearance: none !important;
+  background-color: #fff;
+  border: 1px solid #000 !important;
+  padding: 0px !important;
+  width: 500px;
+}
+
+#bookmark_list {
+  -moz-appearance: none !important;
+  border:  none !important;
+}
+
+.bookmarklist-item {
+  -moz-appearance: none !important;
+  border-top: 1px dotted rgb(192, 192, 192);
+  margin: 2px;
+}
+
+.bookmarklist-item:first-child {
+  border-top: none;
+}
+
+.bookmarklist-item:hover {
+  background-color: Highlight;
+  color: HighlightText;
+}
+
+.bookmarklist-image {
+  width: 24px;
+  height: 24px;
+}
+
+.deckbrowser-tabspace {
+  background-color: #9c9a9c;
+}
+
+.deckbrowser-title {
+  color: #fff;
+  font-size: 2.5em;
+}
+
+.deckbrowser-uri {
+  color: lightgray;
+  font-size: 1.5em;
+}
+
+.deckpage-container {
+  margin: 10px;
+}
+
+.deckpage-close {
+  width: 24px;
+  height: 24px;
+  -moz-image-region: rect(0px, 16px, 16px, 0px);
+  list-style-image: url(chrome://browser/skin/images/close.png);
+}
+
+.deckpage-close:hover {
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..09502fe8334df250721fb4442e48014f0605c704
GIT binary patch
literal 508
zc$@+J0R#StP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10eMM8K~y-6#goq~rBN8iKj*w>yjP0%b&KoHPzsH*U_~kX2Sm+3
zU^P37iH(h|jfJw1EUjlZ6T(KyLU$pq<VT67L6?zS_ug|J8*_8((pwh3%ct}GobU5I
zJxWA)kMz6TfLUGtJ*<?P7m=E%CJ_;>^}g}U52Ll7?d|D{`+h9)uZ2SX+*+FwksD*J
zP5OR}Oy)YO{{mPAmVs0AzZ!;dfD+LC<p#N%O}wfOs*{6dX+^+pIt9Sz`bG+mf61II
z;<CrI^(~R!_{QVi0b%nfrXpS*(DAjinBe+oj<)V;^0`ZtyP~CM2IJRrxIIB#`&0>_
zxW?Uds+giCImqGGD2jXJ;U~x~M_b>iZWwyKg_j9pK^Ond!1F?Kc7RV6wKy!Xpex!8
z08C{Qr#qA6osUsjOl8yCL;R8`eGqRQFKYnQbL$#V#?#)PZ1y1$1mSCj5{Zzo*7iGR
y^T3{3S^G7jlv;4k1(68P(psmDF=Oh(uki_&1&S>xh>axx0000<MNUMnLSTYa#^x0O
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6d37d63214eed5b1856f5e401d3dc3bd8b647123
GIT binary patch
literal 1894
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f3a2036e593357de28dbfda127add800c6446592
GIT binary patch
literal 733
zc$@*<0wVp1P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10$NE#K~y-6jgd=8)KL_NzkBb0CT(iW$j6L1Ns3@$4-H);1R52!
zs8&G{B|WG`ixwgnWJnpli*_lsk~Xbc)FLpG0+BHvrKzbc!skG0jpI1|XKstp$x#V^
zaJcty?)~oh-6OQtRM$Q{sg!zZnq~^?NJ^=N5COw5Iu;if%S%hj-bIR9YijGOCZ;`8
z`hOZ39oC<}^ytS=>b-Rh)pc5HwAM%f(=?M4b|f-5($C;<Uw9qqXJ|!qcX#4&I=OVQ
z*e0dCSyfYc90&uJrKChD10@xPQsMnl2qo|@EP#N5!v(R1#i#%<q5x_+6$r7iB5*jI
zbhz6w%@Ap>G(y49!L<OXKnSLP`e=CZiQaG1ARs3*iQ5-)$w;^1^DU5_y`T4Ot(LVG
zl)^LX=i2?(Bqh&La%GWwxAMqH_i(x54O-c7xm?6-iXj*bQdLtaRsjs^nmajNG)(^9
z5yt0EVTv*G_qB5F#29tWZj@4CQ$lE9H9*lbIE5q8PW#{)re^$XiD|*>x09MYP3OQQ
zhKh0>4UjTS_x~xtwY>@Nyoc{&@mRz#K7U^1k);k;cZ>%zllai}o2{`waK^Xe9yp43
z-bP!Ojod6pWK!!|kWz8y>Jh#UP0}}dh|ShxWbL%m(osZj|19O#3nLvYTQH&ll3k8%
zysSCTgQiyAeslwnvu8K29u<<3VE=b>se|Yr5dt9uyBu*e-aU(4%7u`T+RC#LfW=~&
znEN&7h_lDB5zYJN0cL=J0T2uZi=RDjYzzbfsT%=Ut=92SD0HK=q)h(>8?E#cOGw%Y
P00000NkvXXu0mjf>8wEs
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..259c8a4f01cd6a929a3440a5b579fef5275ce0ae
GIT binary patch
literal 573
zc$@(}0>b@?P)<h;3K|Lk000e1NJLTq000dD000dL1^@s6a_i)L00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10lG;<K~yM_eUi^=6Hyq&e>3-H@^=t15S7+$TnK_9t^}Les1d7q
z3s<gOD9pn3P-tGDh|;ZZPzu64fl3vTLZ=!dwMlBiZ6-6B%v=|mQib%a&*A(&zGJjn
zEqvR33tR@C0dE}TX-<*p+io7HuRK^;Tw1!c0c`uWTR$}fXn>rsxN+@fzH#^7)oS(J
zrf<7jzU^L_7y3uVLYdpQ>V^99@|{wt^xn7KSHA7mPI`>yx|IW>=EFzk=qN;MzyQn2
zA*7(wX{XyCKgDU9t^uo#@<OAzZb=}%-)NY<?jaftTB9`xDX3IR7$yWkFbRUMBjB<8
zdy^4O#vF|lQ8XqThs5!OD2hmugoVWmoWEGJFtioyetRiroKZZYKkO365unM?6w4M1
z)fz$wzI@(^h66P|*+e)|NDD-+fN7ePD@CNpaj@T?9Cn9^)_N6KbCfqe#>0eCr9eJ!
zA*H1EbCB+Lz9%}<ueH`M9Od<ARL6Kiz?riZe)W`Y@3x~X%Qmw#d+I1}@Bg<*M|s+}
zUDP0?y>}2!lk`J6O`kZ*dpB<p@=uGo5$yc9o=&spj`FtVnP>V9B1pwCXWB}@00000
LNkvXXu0mjf?Z5s_
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..efc863368c335baddeb3a85521dd2eb25c46e62f
GIT binary patch
literal 718
zc$@*w0x|uGP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0007&Nkl<ZIE{^x
zy=zlp6o;Spz4zw3P1<NQ3W~8*MX}hVB8r1JIXEb|*g<emsXCR8{soR|Ar69|li=bk
zqJyBlZLI{UwOag4TVrhVb$dTwhgz^0!~<tJ=lmWx=lq0Higq!6yAW1^e+NKF?R@@%
zX}6ox+p2-Uwa=w@70v?ucxyfdZnvA0?TThG9}~JUl09&o?15tlT^})v`PhF00?!#t
zZQI=wO=pRwGo-fl_5_|g_|Fy0Vt-Tx!4?(xJt#H2Y40IWF5r;a+fViVo8gzY`aVgi
z%_7CO!o_h5K$yk+B_YJ1(6p_gSVz`~CnKGkx3jtLDBuAOD3|iobL#V7ahlB)w`G-s
z!2gO;_r=&~-}u&nQ~ewE96=Wr!jK>W@LHgJP`@FX2Y#KvY2p)Qae9vOtCtfJA+CL&
zer9>C8X}ek*9O}H&jEK4>}hC?LG2kd$B~gGoW=r`nUV$KnovqHHoE_0D4u%Id*V_!
znv6rE1nw;OmEU&&5D?!;v(dr3#}l^OS~)W?H2FxZ8EI^E|LJgY<K5oFI};IY4*URw
zwkiaW0?Uar^L)PHG+O5dh9)1bd*i^+>xV1L)snUFc2(>t@B;9Ba9!|SRw_%_4Xd;!
zUI#FXg_LgSxky-o>w{)MN7rg<2Dm<vaDZ-TIkQ+uwKGyu4~c{k)gjRd-5KgNNxdea
zI|GSMjHr$t5(yyrmyuMUa^ZL=rf1Vw%K_yVWvX*O7XZ3<bZyG+=_Z<u5sq6iyJh8o
zkLv)S_Q{aOm#Hd?Gd~^A_HSysybe&At&S{xUcQp)?Fz||2B>|&lXU>8$*J0W^Xbx;
z`Ujzj8wW2>O#ZRnuvyICE0-!)r7m+)lT&MrUq%%gd|}2WQUCw|07*qoM6N<$g7?c)
A8~^|S
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fd006f4cda7a1412c85677e0cc413107c8fd30b3
GIT binary patch
literal 862
zc$@)V1EKthP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10^3PMK~y-6jgw7CRACf`-|xG>&ei#5939P+8n7I(MT$XDxhXWU
z%)~6Hjb*zQ{SZRXriCO1Eo#xCXcJ^21QlxjR7M1ar4m$>{mke%7YFamIHS(oxpQwD
z4V8%A%~_p?_nh+{Vp$ee)X~{q2H+fkN}lJvhGBdMFbd#S+oj8+_=|{TS?K6&rvNT6
z#@Y_m9S*p1T=@hvFP%=$g~M8)xBsbI)3iGPuC`seoLUXwm+N`2x3smU`k>hH;6uT;
znNLm-3PLQl$(?ClY&v0k_x5$e_{10hTv-j^G8C~SQ^~w{?AVE{mg_HMcP_J6cnfHL
zE<?5>iw43;<?)+e=BfIf?AOo9Z9~HYBYSr5oml};04=q(bw6(Od`wl86i9VDHo;qH
zM~+<r04O#Y*-pEByYK5_O-=1AfU~O|Pym&AZg=jN=?E+HxZq|IT$v(dfnp(Pz@8zX
zC@%}4d7U|!V<Ujd^*bo$c_AMJLTEmL2_IluCZ^_=AaE3Rn*c@P5#)H0Q0n4&URe+L
zoJ=MRQREBbiL?|?EI>C*Ea_=D6cG+ZfKB2c3p8b!re+vMaQz6Qfj}T!S)3E`%|xKZ
zbVTAQC=v%|6W~-tX!8jaFz|uE^uls3)&TAf3_bH4uPUPHv>8*iI5H%P43UE*P)yIo
zF+Cea^Ii`b93Jra{ZnfI+~B})WaQNgO;y!hXBu~t_+l#R55>9gg3fEvMcpZ;xRX^y
zq_^)0rl$NP7!2-v*xmL1XjAj#pCkf6M`wGhEX&vS@2mc~A%BBYlEgw?PX&E`pZ@aY
z^DU~Xk}X?{AxaYZdi$3Q!)Wa8>ggxzeql3!)61tS1uzL<)aUb0#$vIX<>lLDhl4>7
z#T7`y8o<BQe7xy^BuS6T%eTvnF>oBk;NVb*{#Q4E?yjExWHNbVY-~IcjYcs$8!`!@
o>VG>}<)m5=`1^!VRoC_U-_24j#;&EI-~a#s07*qoM6N<$g1e)I`Tzg`
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1b804b612de8728491d584f5f397b6b4fae1a2d0
GIT binary patch
literal 718
zc$@*w0x|uGP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0007&Nkl<ZIE{^x
zze`(D6vw~!zI*%f9_E*WvF&1lm_<a2hz?@>7aS_oK`0bDw39f9=nYC-I<`}XLZKaW
zaLa0mxcCDaqX^paAeA<hpqN-m^0+@bB^V5)2hMWN_k7N|_Z(u3K_^S6)3(<70{~D;
zpQqF5MkgKXSPj7U{kh@c;b#Dl&*yUh-gnZ`PC+4r%NScorBaxjoCITRK?vdgH^BG(
z*<>==-_z5BSS*HQGTHC@{_H=Wu(Gn^XssV9rTUFA^W)>=Ez#K67><vR=NA_je^{3F
zol^R1b#=7{07MA!l2STrS=QrVF!(SW4hQ=B`Y<su(E=D_u(Pv+VzG!yrBc7SxhW~7
zei~ywGo{pvR4VmkWMl-KbJ(^G08mQd?uMqOrl7S(y<QLaz8~M)+l%k+?z$Af^5NlO
zty-<Zwrxl$A*F=Y8d_^8r68q5tyV*$(SYMPxVpMRKA*1<LYA#uF83{)%@)qi&Zgt>
zIEzFg@O>XrN+_jTAY%+T=O`A7*x1-;+}_?kU0YkrlIEC8OH0$yX!PUE%uH8zcQ=$$
zZNF_<7Ru!^Ha9o_R4SFZOeV9{w#G~*vvqlSc~UBsKnQ7dZaN_Z<#HL<*ViY_;x>Q~
zA`%D$647WBQc4(OU|AL{%YrcmQc6T35!kk!5JE)m0gN$W$8ow`*99R2lu~$}2ha0B
zDFq<}uIs{aoGxQb_}(FDtrMY8$PEUAD3was-`~gi`T1`E7#J9cjgF3@x3?FeP{^%T
zs|f(bHUNM@&N;TXw^1k*{Cd6qj&uG708UR&7d+2<H8eEzfO8H2g8;s?0T^RP7Z(>f
z&+|OS*xU8>^{;o}^FoME2L}hQIp+z+*ikd_7b_b%B(*v@6951J07*qoM6N<$g04zS
AXaE2J
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2f7e878a7366e37b4b92887de73813c36672dcc6
GIT binary patch
literal 1911
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9f0d06df3466eeb6c1d5aff470d7d70857ad5d70
GIT binary patch
literal 3265
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
Yb-zw6@Nh#ZZO6COQCssWQ+(Wi00`g{@Bjb+
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cce32f20f4734a99416b62adc4d998048331d136
GIT binary patch
literal 825
zc${<hbhEHb6krfwc+9~71X5B`#>U1zK0aw_X$=hxGiT1+v}x0S96<3ux1VcBu(M-;
ztC5}oGb2#H;!hSvE(Q(;9gtxlV;NXH1WtA`ESM2BJDuZdn+*H6+J_#~?s=}wnLTle
zLdoPrg>AjBcimgdeCKBYhit0B2@x&{waK4q^p<ikF$T8AZN9ZuRQ#Tj`Yk^esNwu5
zhJQHu(+Onwa)GPg7#NTYzhY2wxzGk-IKOPG!wCr<sNwxi4~a9p1!VYhiL2jO7?BJY
zaV!yLKrwu2zzG>XsNww0L>hh!WVpKG)o&b3NQQ?5mIMo+7=AS21Oo%i<%fwhoMRy<
z%r&om<6%Y)^Td+L3Mhs@EjYo#1ampV1L6$#0vW#C@ai`K7UVE5EV*oeVmK?q2@V#R
z%N>X`ya#0XbIYsWL|Bo-oS{V65yfy-ffGDzFqbzHY4|yi;pz-mze%tmhq*vWa3G4|
Qt_mjvIAAV6h;Fzw0F}Z{aR2}S
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..891574ea664c0c35a102e8cb058a88ad9179baa6
GIT binary patch
literal 214
zc%17D@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDU1=3PdQpU!{K0ZEaX=x1&
z4KruX+_Y)a1H<`jKsm;eAirP+hi5m^K%69RcNc~ZR#^`qhqJ&VvY3H^TNs2H8D`Cq
z01C2~c>21sUttyG6H%MYY_bt3WbWzW7$R}m)psK=g8@g<=UDT5`HtScF3k!I0lk`+
y7SA$Sp6K_$^-K2S2)(qEFS(P?A9hhGS<3FBBo-KbgEbLo1cRrmpUXO@geCy0)jGof
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..927a9da05a4a25fc1a829e9c738299a698a6e47d
GIT binary patch
literal 19631
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
new file mode 100644
--- /dev/null
+++ b/confvars.sh
@@ -0,0 +1,46 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Mark Finkle <mfinkle@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+MOZ_APP_NAME=fennec
+MOZ_APP_DISPLAYNAME=Fennec
+MOZ_APP_VERSION=0.3
+
+MOZ_XUL_APP=1
+MOZ_UPDATER=0
+MOZ_ENABLE_LIBXUL=1
+MOZ_NO_XPCOM_OBSOLETE=1
+MOZ_XULRUNNER=1
new file mode 100644
--- /dev/null
+++ b/installer/Makefile.in
@@ -0,0 +1,66 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Mark Finkle <mfinkle@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH     = ../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+NO_PKG_FILES = \
+	$(MOZ_APP_NAME)-config \
+	$(MOZ_APP_NAME)-bin.elf \
+	regchrome* \
+	regxpcom* \
+	xpcshell* \
+	xpidl* \
+	xpt_dump* \
+	xpt_link* \
+	res \
+	bloaturls.txt \
+	run-mozilla.sh \
+	nsinstall \
+	$(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
+_BINPATH = /$(_APPNAME)/Contents/Resources
+endif
+
+include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
new file mode 100644
--- /dev/null
+++ b/makefiles.sh
@@ -0,0 +1,45 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Mark Finkle <mfinkle@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+add_makefiles "
+mobile/Makefile
+mobile/chrome/Makefile
+mobile/chrome/branding/Makefile
+mobile/chrome/content/Makefile
+mobile/app/Makefile
+mobile/installer/Makefile
+"