summaryrefslogtreecommitdiffstats
path: root/comm/suite/editor/base/content/editingOverlay.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /comm/suite/editor/base/content/editingOverlay.js
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/suite/editor/base/content/editingOverlay.js')
-rw-r--r--comm/suite/editor/base/content/editingOverlay.js387
1 files changed, 387 insertions, 0 deletions
diff --git a/comm/suite/editor/base/content/editingOverlay.js b/comm/suite/editor/base/content/editingOverlay.js
new file mode 100644
index 0000000000..19b41d321b
--- /dev/null
+++ b/comm/suite/editor/base/content/editingOverlay.js
@@ -0,0 +1,387 @@
+/* -*- 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 <editor>
+ 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);
+}