/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ var gUntitledString; function TextEditorOnLoad() { var url = "about:blank"; // See if argument was passed. if (window.arguments && window.arguments[0]) { // Opened via window.openDialog with URL as argument. url = window.arguments[0]; } // Continue with normal startup. EditorStartup(url); } function EditorOnLoad() { var url = "about:blank"; var charset; // See if argument was passed. if (window.arguments) { if (window.arguments[0]) { // Opened via window.openDialog with URL as argument. url = window.arguments[0]; } // get default character set if provided if (window.arguments.length > 1 && window.arguments[1]) { if (window.arguments[1].includes("charset=")) { var arrayArgComponents = window.arguments[1].split("="); if (arrayArgComponents) charset = arrayArgComponents[1]; } } } // XUL elements we use when switching from normal editor to edit source. gContentWindowDeck = document.getElementById("ContentWindowDeck"); gFormatToolbar = document.getElementById("FormatToolbar"); // Continue with normal startup. EditorStartup(url, charset); // Hide Highlight button if we are in an HTML editor with CSS mode off // and tell the editor if a CR in a paragraph creates a new paragraph. var cmd = document.getElementById("cmd_highlight"); if (cmd) { if (!Services.prefs.getBoolPref(kUseCssPref)) cmd.collapsed = true; } // Initialize our source text try { gSourceContentWindow = document.getElementById("content-source"); gSourceContentWindow.makeEditable("text", false); gSourceTextEditor = gSourceContentWindow.getEditor(gSourceContentWindow.contentWindow); gSourceTextEditor.enableUndo(false); gSourceTextEditor.rootElement.style.fontFamily = "-moz-fixed"; gSourceTextEditor.rootElement.style.whiteSpace = "pre"; gSourceTextEditor.rootElement.style.margin = 0; var controller = Cc["@mozilla.org/embedcomp/base-command-controller;1"] .createInstance(Ci.nsIControllerContext); controller.setCommandContext(gSourceContentWindow); gSourceContentWindow.contentWindow.controllers.insertControllerAt(0, controller); var commandTable = controller.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIControllerCommandTable); commandTable.registerCommand("cmd_findReplace", nsFindReplaceCommand); commandTable.registerCommand("cmd_find", nsFindCommand); commandTable.registerCommand("cmd_findNext", nsFindAgainCommand); commandTable.registerCommand("cmd_findPrev", nsFindAgainCommand); } catch (e) { dump("makeEditable failed: "+e+"\n"); } } function toggleAffectedChrome(aHide) { // chrome to toggle includes: // (*) menubar // (*) toolbox // (*) sidebar // (*) statusbar if (!gChromeState) gChromeState = new Object; var statusbar = document.getElementById("status-bar"); // sidebar states map as follows: // hidden => hide/show nothing // collapsed => hide/show only the splitter // shown => hide/show the splitter and the box if (aHide) { // going into print preview mode gChromeState.sidebar = SidebarGetState(); SidebarSetState("hidden"); // deal with the Status Bar gChromeState.statusbarWasHidden = statusbar.hidden; statusbar.hidden = true; } else { // restoring normal mode (i.e., leaving print preview mode) SidebarSetState(gChromeState.sidebar); // restore the Status Bar statusbar.hidden = gChromeState.statusbarWasHidden; } // if we are unhiding and sidebar used to be there rebuild it if (!aHide && gChromeState.sidebar == "visible") SidebarRebuild(); document.getElementById("EditorToolbox").hidden = aHide; document.getElementById("appcontent").collapsed = aHide; } var PrintPreviewListener = { getPrintPreviewBrowser: function () { var browser = document.getElementById("ppBrowser"); if (!browser) { browser = document.createXULElement("browser"); browser.setAttribute("id", "ppBrowser"); browser.setAttribute("flex", "1"); browser.setAttribute("disablehistory", "true"); browser.setAttribute("disablesecurity", "true"); browser.setAttribute("type", "content"); document.getElementById("sidebar-parent"). insertBefore(browser, document.getElementById("appcontent")); } return browser; }, getSourceBrowser: function () { return GetCurrentEditorElement(); }, getNavToolbox: function () { return document.getElementById("EditorToolbox"); }, onEnter: function () { toggleAffectedChrome(true); }, onExit: function () { document.getElementById("ppBrowser").collapsed = true; toggleAffectedChrome(false); } } function EditorStartup(aUrl, aCharset) { gUntitledString = GetFormattedString("untitledTitle", GetNextUntitledValue()); var ds = GetCurrentEditorElement().docShell; ds.useErrorPages = false; var root = ds.QueryInterface(Ci.nsIDocShellTreeItem) .rootTreeItem.QueryInterface(Ci.nsIDocShell); root.QueryInterface(Ci.nsIDocShell).appType = Ci.nsIDocShell.APP_TYPE_EDITOR; // EditorSharedStartup also used by Message Composer. EditorSharedStartup(); // Commands specific to the Composer Application window, // (i.e., not embedded editors) // such as file-related commands, HTML Source editing, Edit Modes... SetupComposerWindowCommands(); gCSSPrefListener = new nsPrefListener(kUseCssPref); gReturnInParagraphPrefListener = new nsPrefListener(kCRInParagraphsPref); Services.obs.addObserver(EditorCanClose, "quit-application-requested"); root.charset = aCharset; // Get url for editor content and load it. The editor gets instantiated by // the editingSession when the URL has finished loading. EditorLoadUrl(aUrl); // Before and after callbacks for the customizeToolbar code. var editorToolbox = getEditorToolbox(); editorToolbox.customizeInit = EditorToolboxCustomizeInit; editorToolbox.customizeDone = EditorToolboxCustomizeDone; editorToolbox.customizeChange = EditorToolboxCustomizeChange; } function EditorShutdown() { Services.obs.removeObserver(EditorCanClose, "quit-application-requested"); gCSSPrefListener.shutdown(); gReturnInParagraphPrefListener.shutdown(); try { var commandManager = GetCurrentCommandManager(); commandManager.removeCommandObserver(gEditorDocumentObserver, "obs_documentCreated"); commandManager.removeCommandObserver(gEditorDocumentObserver, "obs_documentWillBeDestroyed"); commandManager.removeCommandObserver(gEditorDocumentObserver, "obs_documentLocationChanged"); } catch (e) { dump (e); } } // --------------------------- File menu --------------------------- // Check for changes to document and allow saving before closing // This is hooked up to the OS's window close widget (e.g., "X" for Windows) async function EditorCanClose(aCancelQuit, aTopic, aData) { if (aTopic == "quit-application-requested" && aCancelQuit instanceof Ci.nsISupportsPRBool && aCancelQuit.data) return false; // Returns FALSE only if user cancels save action // "true" means allow "Don't Save" button var canClose = await CheckAndSaveDocument("cmd_close", true); // This is our only hook into closing via the "X" in the caption // or "Quit" (or other paths?) // so we must shift association to another // editor or close any non-modal windows now if (canClose && "InsertCharWindow" in window && window.InsertCharWindow) SwitchInsertCharToAnotherEditorOrClose(); if (!canClose && aTopic == "quit-application-requested") aCancelQuit.data = true; return canClose; } function BuildRecentPagesMenu() { var editor = GetCurrentEditor(); if (!editor) return; var popup = document.getElementById("menupopup_RecentFiles"); if (!popup || !editor.document) return; // Delete existing menu while (popup.hasChildNodes()) popup.lastChild.remove(); // Current page is the "0" item in the list we save in prefs, // but we don't include it in the menu. var curUrl = StripPassword(GetDocumentUrl()); var historyCount = Services.prefs.getIntPref("editor.history.url_maximum", 10); var menuIndex = 1; for (var i = 0; i < historyCount; i++) { var url = Services.prefs.getStringPref("editor.history_url_" + i, ""); // Skip over current url if (url && url != curUrl) { // Build the menu var title = Services.prefs.getStringPref("editor.history_title_" + i, ""); var fileType = Services.prefs.getStringPref("editor.history_type_" + i, ""); AppendRecentMenuitem(popup, title, url, fileType, menuIndex); menuIndex++; } } } function AppendRecentMenuitem(aPopup, aTitle, aUrl, aFileType, aIndex) { if (!aPopup) return; var menuItem = document.createXULElement("menuitem"); if (!menuItem) return; var accessKey = aIndex <= 10 ? String(aIndex % 10) : " "; // Show "title [url]" or just the URL. var itemString = aTitle ? aTitle + " [" + aUrl + "]" : aUrl; menuItem.setAttribute("label", accessKey + " " + itemString); menuItem.setAttribute("crop", "center"); menuItem.setAttribute("tooltiptext", aUrl); menuItem.setAttribute("value", aUrl); menuItem.setAttribute("fileType", aFileType); if (accessKey != " ") menuItem.setAttribute("accesskey", accessKey); aPopup.appendChild(menuItem); } function EditorInitFileMenu() { // Disable "Save" menuitem when editing remote url. User should use "Save As" var docUrl = GetDocumentUrl(); var scheme = GetScheme(docUrl); if (scheme && scheme != "file") SetElementEnabledById("menu_saveCmd", false); // Enable recent pages submenu if there are any history entries in prefs. var historyUrl = ""; if (Services.prefs.getIntPref("editor.history.url_maximum", 10)) { historyUrl = Services.prefs.getStringPref("editor.history_url_0", ""); // See if there's more if current file is only entry in history list. if (historyUrl && historyUrl == docUrl) historyUrl = Services.prefs.getStringPref("editor.history_url_1", ""); } SetElementEnabledById("menu_RecentFiles", historyUrl != ""); } function EditorUpdateCharsetMenu(aMenuPopup) { if (IsDocumentModified() && !IsDocumentEmpty()) { for (var i = 0; i < aMenuPopup.childNodes.length; i++) aMenuPopup.childNodes[i].setAttribute("disabled", "true"); } UpdateCharsetMenu(content.document.characterSet, aMenuPopup); } // Zoom support. function getBrowser() { return IsInHTMLSourceMode() ? gSourceContentWindow : GetCurrentEditorElement(); } // override the site-specific zoom object in viewZoomOverlay.js var FullZoom = { init: function() {}, reduce: function() { ZoomManager.reduce(); }, enlarge: function() { ZoomManager.enlarge(); }, zoom: function(aZoomValue) { ZoomManager.zoom = aZoomValue; }, reset: function() { ZoomManager.zoom = 1; }, setOther: function() { openZoomDialog(); } }; function hideEditorUI(aHide) { for (let id of ["EditModeToolbar", "content-source", "content-frame"]) { let element = document.getElementById(id); if (!element) continue; if (aHide) { element.setAttribute("moz-collapsed", true); } else { element.removeAttribute("moz-collapsed"); } } } function getEditorToolbox() { return document.getElementById("EditorToolbox"); } function EditorToolboxCustomizeInit() { if (document.commandDispatcher.focusedWindow == content) window.focus(); hideEditorUI(true); toolboxCustomizeInit("main-menubar"); } function EditorToolboxCustomizeDone(aToolboxChanged) { toolboxCustomizeDone("main-menubar", getEditorToolbox(), aToolboxChanged); hideEditorUI(false); gContentWindow.focus(); } function EditorToolboxCustomizeChange(aEvent) { toolboxCustomizeChange(getEditorToolbox(), aEvent); }