--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/firefox-ui-lockdown.patch Sat Dec 19 22:03:52 2009 +0100
@@ -0,0 +1,360 @@
+diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -1174,32 +1174,186 @@ function prepareForStartup() {
+ // setup our MozApplicationManifest listener
+ gBrowser.addEventListener("MozApplicationManifest",
+ OfflineApps, false);
+
+ // setup simple gestures support
+ gGestureSupport.init(true);
+ }
+
++function lockdownElement(ident, disable, hideCompletely)
++{
++ var e = document.getElementById(ident);
++ if (!e) return;
++ if (hideCompletely) {
++ e.setAttribute("style", (disable) ? "display: none;" : "");
++ } else if (disable) {
++ e.setAttribute("disabled", "true");
++ } else {
++ e.removeAttribute("disabled");
++ }
++}
++
++function applyLockdown(isStartup)
++{
++ // It is important to check that Firefox code does not change the
++ // "disabled" state of these UI elements. Fortunately it mostly hides
++ // elements rather than disables them.
++ var disablePrinting = gPrefService.getBoolPref("config.lockdown.printing");
++ var disablePrintSetup = gPrefService.getBoolPref("config.lockdown.printsetup");
++ if (!isStartup || disablePrintSetup || disablePrintSetup) {
++ lockdownElement("cmd_pageSetup", disablePrinting || disablePrintSetup);
++ lockdownElement("menu_printPreview", disablePrinting || disablePrintSetup);
++ lockdownElement("cmd_print", disablePrinting);
++ }
++
++ var disableSave = gPrefService.getBoolPref("config.lockdown.savepage");
++ if (!isStartup || disableSave) {
++ lockdownElement("Browser:SavePage", disableSave);
++ lockdownElement("Browser:SaveFrame", disableSave);
++ lockdownElement("context-savepage", disableSave);
++ lockdownElement("context-saveframe", disableSave);
++ lockdownElement("context-savelink", disableSave);
++ lockdownElement("context-saveimage", disableSave);
++ lockdownElement("View:PageSource", disableSave);
++ lockdownElement("context-viewpartialsource-selection", disableSave);
++ lockdownElement("context-viewpartialsource-mathml", disableSave);
++ lockdownElement("context-viewsource", disableSave);
++ lockdownElement("context-viewframesource", disableSave);
++ lockdownElement("View:PageInfo", disableSave);
++ lockdownElement("context-viewinfo", disableSave);
++ lockdownElement("context-viewframeinfo", disableSave);
++ lockdownElement("Tasks:InspectPage", disableSave); // from DOMInspector extension
++ }
++
++ var disableBookmarks = gPrefService.getBoolPref("config.lockdown.hidebookmark");
++ var disableBookmarkEditing = gPrefService.getBoolPref("config.lockdown.bookmark");
++ if (!isStartup || disableBookmarks || disableBookmarkEditing) {
++ lockdownElement("bookmarksMenu", disableBookmarks, true);
++ lockdownElement("viewBookmarksSidebar", disableBookmarks);
++ lockdownElement("PersonalToolbar", disableBookmarks); // XXX check
++ lockdownElement("Browser:AddBookmarkAs", disableBookmarks || disableBookmarkEditing);
++ lockdownElement("Browser:ShowAllBookmarks", disableBookmarks || disableBookmarkEditing);
++ lockdownElement("manBookmark", disableBookmarks || disableBookmarkEditing);
++ lockdownElement("context-bookmarkpage", disableBookmarks || disableBookmarkEditing);
++ lockdownElement("context-bookmarklink", disableBookmarks || disableBookmarkEditing);
++
++ // hide the personal bookmarks toolbar if necessary
++ if (disableBookmarks) {
++ document.getElementById("PersonalToolbar").setAttribute("collapsed", "true");
++ }
++ }
++
++ var disableHistory = gPrefService.getBoolPref("config.lockdown.history");
++ if (!isStartup || disableHistory) {
++ lockdownElement("history-menu", disableHistory, true);
++ lockdownElement("viewHistorySidebar", disableHistory);
++ lockdownElement("Browser:ShowAllHistory", disableHistory);
++ gURLBar.setAttribute("enablehistory", disableHistory ? "false" : "true");
++ gURLBar.disableAutoComplete = disableHistory;
++ }
++
++ var defaultPrefs = Cc["@mozilla.org/preferences-service;1"]
++ .getService(Ci.nsIPrefService).getDefaultBranch(null);
++ if (isStartup && disableHistory) {
++ if (!defaultPrefs.prefIsLocked("browser.history_expire_days")) {
++ defaultPrefs.setIntPref("browser.history_expire_days", 0);
++ defaultPrefs.lockPref("browser.history_expire_days");
++ }
++ if (!defaultPrefs.prefIsLocked("browser.formfill.enable")) {
++ defaultPrefs.setBoolPref("browser.formfill.enable", false);
++ defaultPrefs.lockPref("browser.formfill.enable");
++ }
++ if (!defaultPrefs.prefIsLocked("browser.download.manager.retention")) {
++ defaultPrefs.setIntPref("browser.download.manager.retention", 0);
++ defaultPrefs.lockPref("browser.download.manager.retention");
++ }
++ gPrefService.setBoolPref("config.lockdown.history.set", true);
++ } else if (isStartup && gPrefService.prefHasUserValue("config.lockdown.history.set")) {
++ if (!defaultPrefs.prefIsLocked("browser.history_expire_days")) {
++ defaultPrefs.clearUserPref("browser.history_expire_days");
++ }
++ if (!defaultPrefs.prefIsLocked("browser.formfill.enable")) {
++ defaultPrefs.clearUserPref("browser.formfill.enable");
++ }
++ if (!defaultPrefs.prefIsLocked("browser.download.manager.retention")) {
++ defaultPrefs.clearUserPref("browser.download.manager.retention");
++ }
++ gPrefService.clearUserPref("config.lockdown.history.set");
++ }
++
++ var disableURLBar = gPrefService.getBoolPref("config.lockdown.urlbar");
++ if (!isStartup || disableURLBar) {
++ lockdownElement("urlbar", disableURLBar);
++ lockdownElement("Browser:OpenLocation", disableURLBar);
++ lockdownElement("Browser:OpenFile", disableURLBar);
++ }
++
++ var disableSearchBar = gPrefService.getBoolPref("config.lockdown.searchbar");
++ if (!isStartup || disableSearchBar) {
++ document.getElementById("search-container")
++ .setAttribute("style", (disableSearchBar) ? "display: none;" : "");
++ }
++
++ var disableToolbarEditing = gPrefService.getBoolPref("config.lockdown.toolbarediting");
++ if (!isStartup || disableToolbarEditing) {
++ var e = document.getElementById("cmd_CustomizeToolbars");
++ if (!e.getAttribute("inCustomization")) {
++ lockdownElement("cmd_CustomizeToolbars", disableToolbarEditing);
++ }
++ }
++
++ // Close sidebar if we disabled the command that's currently in use
++ var sidebarBox = document.getElementById("sidebar-box");
++ var cmd = sidebarBox.getAttribute("sidebarcommand");
++ if (cmd) {
++ var elt = document.getElementById(cmd);
++ if (elt && elt.getAttribute("disabled") == "true") {
++ toggleSidebar(cmd, false);
++ gMustLoadSidebar = false;
++ }
++ }
++}
++
++var lockdownObserver = {
++ observe: function(aSubject, aTopic, aPrefName)
++ {
++ try {
++ applyLockdown(false);
++ } catch (ex) {
++ dump("Failed lockdown: " + ex + "\n");
++ }
++ }
++};
++
+ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
+ var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ os.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
+ os.addObserver(gXPInstallObserver, "xpinstall-install-blocked", false);
+
++ try {
++ // do lockdown stuff in an exception handler so that if it fails
++ // catastrophically, the browser should still come up and function
++ applyLockdown(true);
++ gPrefService.addObserver("config.lockdown.", lockdownObserver, false);
++ } catch (ex) {
++ dump("Failed lockdown: " + ex + "\n");
++ }
++
+ BrowserOffline.init();
+ OfflineApps.init();
+
+ gBrowser.addEventListener("pageshow", function(evt) { setTimeout(pageShowEventHandlers, 0, evt); }, true);
+
+ // Ensure login manager is up and running.
+ Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
+
+ if (mustLoadSidebar) {
++ let sidebarBox = document.getElementById("sidebar-box");
+ let sidebar = document.getElementById("sidebar");
+- let sidebarBox = document.getElementById("sidebar-box");
+ sidebar.setAttribute("src", sidebarBox.getAttribute("src"));
+ }
+
+ UpdateUrlbarSearchSplitterState();
+
+ PlacesStarButton.init();
+
+ // called when we go into full screen, even if it is
+@@ -1399,16 +1553,18 @@ function BrowserShutdown()
+ Components.utils.reportError(ex);
+ }
+
+ var os = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService);
+ os.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
+ os.removeObserver(gXPInstallObserver, "xpinstall-install-blocked");
+
++ gPrefService.removeObserver("config.lockdown.", lockdownObserver);
++
+ try {
+ gBrowser.removeProgressListener(window.XULBrowserWindow);
+ gBrowser.removeTabsProgressListener(window.TabsProgressListener);
+ } catch (ex) {
+ }
+
+ PlacesStarButton.uninit();
+
+@@ -3208,16 +3364,22 @@ function FillHistoryMenu(aParent) {
+
+ // Remove old entries if any
+ var children = aParent.childNodes;
+ for (var i = children.length - 1; i >= 0; --i) {
+ if (children[i].hasAttribute("index"))
+ aParent.removeChild(children[i]);
+ }
+
++ // lockdown. Don't display anything if locked down.
++ var disableHistory = gPrefService.getBoolPref("config.lockdown.history");
++ if (disableHistory) {
++ return false;
++ }
++
+ var webNav = getWebNavigation();
+ var sessionHistory = webNav.sessionHistory;
+
+ var count = sessionHistory.count;
+ if (count <= 1) // don't display the popup for a single item
+ return false;
+
+ const MAX_HISTORY_MENU_ITEMS = 15;
+@@ -3357,16 +3519,17 @@ function BrowserCustomizeToolbar()
+ {
+ // Disable the toolbar context menu items
+ var menubar = document.getElementById("main-menubar");
+ for (var i = 0; i < menubar.childNodes.length; ++i)
+ menubar.childNodes[i].setAttribute("disabled", true);
+
+ var cmd = document.getElementById("cmd_CustomizeToolbars");
+ cmd.setAttribute("disabled", "true");
++ cmd.setAttribute("inCustomization", "true");
+
+ var splitter = document.getElementById("urlbar-search-splitter");
+ if (splitter)
+ splitter.parentNode.removeChild(splitter);
+
+ var customizeURL = "chrome://global/content/customizeToolbar.xul";
+ gCustomizeSheet = getBoolPref("toolbar.customization.usesheet", false);
+
+@@ -3394,16 +3557,25 @@ function BrowserCustomizeToolbar()
+ } else {
+ return window.openDialog(customizeURL,
+ "CustomizeToolbar",
+ "chrome,titlebar,toolbar,location,resizable,dependent",
+ gNavToolbox);
+ }
+ }
+
++function BrowserRestoreCustomizationDisabledState()
++{
++ var cmd = document.getElementById("cmd_CustomizeToolbars");
++ if (!gPrefService.getBoolPref("config.lockdown.toolbarediting")) {
++ cmd.removeAttribute("disabled", "true");
++ }
++ cmd.removeAttribute("inCustomization");
++}
++
+ function BrowserToolboxCustomizeDone(aToolboxChanged) {
+ if (gCustomizeSheet) {
+ document.getElementById("customizeToolbarSheetIFrame").hidden = true;
+ document.getElementById("customizeToolbarSheetPopup").hidePopup();
+ }
+
+ // Update global UI elements that may have been added or removed
+ if (aToolboxChanged) {
+@@ -3411,16 +3583,23 @@ function BrowserToolboxCustomizeDone(aTo
+ if (gURLBar)
+ gURLBar.emptyText = gURLBarEmptyText.value;
+
+ gProxyFavIcon = document.getElementById("page-proxy-favicon");
+ gHomeButton.updateTooltip();
+ gIdentityHandler._cacheElements();
+ window.XULBrowserWindow.init();
+
++ // make sure the search bar is not put back if locked down
++ var disableSearchBar = gPrefService.getBoolPref("config.lockdown.searchbar");
++ if (disableSearchBar) {
++ document.getElementById("search-container")
++ .setAttribute("style", (disableSearchBar) ? "display: none;" : "");
++ }
++
+ var backForwardDropmarker = document.getElementById("back-forward-dropmarker");
+ if (backForwardDropmarker)
+ backForwardDropmarker.disabled =
+ document.getElementById('Browser:Back').hasAttribute('disabled') &&
+ document.getElementById('Browser:Forward').hasAttribute('disabled');
+
+ // support downgrading to Firefox 2.0
+ var navBar = document.getElementById("nav-bar");
+@@ -3445,18 +3624,17 @@ function BrowserToolboxCustomizeDone(aTo
+ XULBrowserWindow.asyncUpdateUI();
+ PlacesStarButton.updateState();
+ }
+
+ // Re-enable parts of the UI we disabled during the dialog
+ var menubar = document.getElementById("main-menubar");
+ for (var i = 0; i < menubar.childNodes.length; ++i)
+ menubar.childNodes[i].setAttribute("disabled", false);
+- var cmd = document.getElementById("cmd_CustomizeToolbars");
+- cmd.removeAttribute("disabled");
++ BrowserRestoreCustomizationDisabledState();
+
+ #ifdef XP_MACOSX
+ // make sure to re-enable click-and-hold
+ if (!getBoolPref("ui.click_hold_context_menus", false))
+ SetClickAndHoldHandlers();
+ #endif
+
+ // XXX Shouldn't have to do this, but I do
+@@ -4544,16 +4722,19 @@ function onViewToolbarsPopupShowing(aEve
+ var toolbarName = toolbar.getAttribute("toolbarname");
+ if (toolbarName) {
+ let menuItem = document.createElement("menuitem");
+ let hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
+ "autohide" : "collapsed";
+ menuItem.setAttribute("toolbarindex", i);
+ menuItem.setAttribute("type", "checkbox");
+ menuItem.setAttribute("label", toolbarName);
++ if (toolbar.getAttribute("disabled") == "true") {
++ menuItem.setAttribute("disabled", "true");
++ }
+ menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
+ menuItem.setAttribute("checked", toolbar.getAttribute(hidingAttribute) != "true");
+ popup.insertBefore(menuItem, firstMenuItem);
+
+ menuItem.addEventListener("command", onViewToolbarCommand, false);
+ }
+ toolbar = toolbar.nextSibling;
+ }
+@@ -6421,17 +6602,17 @@ BookmarkAllTabsHandler.prototype = {
+
+ _updateCommandState: function BATH__updateCommandState(aTabClose) {
+ var numTabs = gBrowser.tabContainer.childNodes.length;
+
+ // The TabClose event is fired before the tab is removed from the DOM
+ if (aTabClose)
+ numTabs--;
+
+- if (numTabs > 1)
++ if (numTabs > 1 && !gPrefService.getBoolPref("config.lockdown.bookmark"))
+ this._command.removeAttribute("disabled");
+ else
+ this._command.setAttribute("disabled", "true");
+ },
+
+ doCommand: function BATH_doCommand() {
+ PlacesCommandHook.bookmarkCurrentPages();
+ },