From 5e0a77611f6f0593ddf299e8d47e6c21ad1edc04 Mon Sep 17 00:00:00 2001 From: "cmanske%netscape.com" Date: Wed, 20 Oct 1999 14:15:25 +0000 Subject: [PATCH] Fixed bugs 12515, 16493,16494,16495,16692,16794,most of 9758. Replaced old 'target' icon with interim 'anchor' icon. r=sfraser git-svn-id: svn://10.0.0.236/trunk@51255 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/editor/base/nsEditorShell.cpp | 201 +++++++++++++----- mozilla/editor/base/nsEditorShell.h | 3 + mozilla/editor/base/nsTextEditRules.cpp | 3 +- mozilla/editor/composer/src/nsEditorShell.cpp | 201 +++++++++++++----- mozilla/editor/composer/src/nsEditorShell.h | 3 + mozilla/editor/idl/nsIEditorShell.idl | 8 +- .../editor/libeditor/text/nsTextEditRules.cpp | 3 +- .../ui/composer/content/EditorAppShell.xul | 9 +- .../ui/composer/content/EditorContent.css | 2 +- .../composer/content/TextEditorAppShell.xul | 5 +- .../ui/composer/content/editorOverlay.xul | 6 +- .../composer/locale/en-US/EditorAppShell.dtd | 15 +- .../composer/locale/en-US/editor.properties | 12 +- .../composer/locale/en-US/editorOverlay.dtd | 2 +- mozilla/editor/ui/composer/skin/Editor.css | 3 +- mozilla/editor/ui/composer/skin/MANIFEST | 4 +- mozilla/editor/ui/composer/skin/Makefile.in | 2 +- .../editor/ui/composer/skin/images/anchor.gif | Bin 0 -> 196 bytes mozilla/editor/ui/composer/skin/makefile.win | 4 +- .../editor/ui/dialogs/content/EdHLineProps.js | 5 +- .../ui/dialogs/content/EdInsertTable.js | 6 +- .../editor/ui/dialogs/content/EdLinkProps.js | 103 ++++----- .../editor/ui/dialogs/content/EdLinkProps.xul | 6 +- .../locale/en-US/EditorLinkProperties.dtd | 5 +- .../content/debugQATextEditorShell.xul | 5 +- 25 files changed, 421 insertions(+), 195 deletions(-) create mode 100644 mozilla/editor/ui/composer/skin/images/anchor.gif diff --git a/mozilla/editor/base/nsEditorShell.cpp b/mozilla/editor/base/nsEditorShell.cpp index 2e07fa6df88..01094424eda 100644 --- a/mozilla/editor/base/nsEditorShell.cpp +++ b/mozilla/editor/base/nsEditorShell.cpp @@ -1173,7 +1173,10 @@ nsEditorShell::CheckAndSaveDocument(PRBool *_retval) // Ask user if they want to save current changes nsAutoString tmp1 = GetString("Save"); nsAutoString tmp2 = GetString("DontSave"); - EConfirmResult result = ConfirmWithCancel(GetString("SaveDocument"), GetString("SaveFilePrompt"), + nsAutoString title; + GetDocumentTitle(title); + nsAutoString saveMsg = GetString("SaveFilePrompt")+" "+"\""+title+"\""+GetString("QuestionMark"); + EConfirmResult result = ConfirmWithCancel(GetString("SaveDocument"), saveMsg, &tmp1, &tmp2); if (result == eCancel) { @@ -1216,7 +1219,8 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) // find out if the doc already has a fileSpec associated with it. nsFileSpec docFileSpec; - PRBool mustShowFileDialog = saveAs || (diskDoc->GetFileSpec(docFileSpec) == NS_ERROR_NOT_INITIALIZED); + PRBool noFileSpec = (diskDoc->GetFileSpec(docFileSpec) == NS_ERROR_NOT_INITIALIZED); + PRBool mustShowFileDialog = saveAs || noFileSpec; PRBool replacing = !saveAs; if (mustShowFileDialog) @@ -1230,7 +1234,8 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) nsString title; res = HTMLDoc->GetTitle(title); - if (NS_SUCCEEDED(res) && title.Length() == 0) + // Prompt for title ONLY for a new blank doc (no filespec yet) + if (noFileSpec && NS_SUCCEEDED(res) && title.Length() == 0) { // Use a "prompt" common dialog to get title string from user NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &res); @@ -1250,7 +1255,8 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) return NS_OK; } //This will call UpdateWindowTitle - SetTitle(titleUnicode); + SetDocumentTitle(titleUnicode); + title = titleUnicode; bUpdateWindowTitle = PR_FALSE; nsCRT::free(titleUnicode); } @@ -1260,14 +1266,16 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) res = nsComponentManager::CreateInstance(kCFileWidgetCID, nsnull, nsIFileWidget::GetIID(), getter_AddRefs(fileWidget)); if (NS_SUCCEEDED(res) && fileWidget) { - nsString promptString = GetString("SaveDocumentAs"); + nsAutoString promptString = GetString("SaveDocumentAs"); nsString* titles = nsnull; nsString* filters = nsnull; nsString* nextTitle; nsString* nextFilter; - nsString HTMLFiles; - nsString TextFiles; + nsAutoString HTMLFiles; + nsAutoString TextFiles; + nsAutoString fileName; + nsFileSpec parentPath; titles = new nsString[2]; if (!titles) @@ -1289,15 +1297,50 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) if (HTMLFiles.Length() == 0 || TextFiles.Length() == 0) goto SkipFilters; - *nextTitle++ = "HTML Files"; + *nextTitle++ = HTMLFiles; *nextFilter++ = "*.htm; *.html; *.shtml"; - *nextTitle++ = "Text Files"; + *nextTitle++ = TextFiles; *nextFilter++ = "*.txt"; fileWidget->SetFilterList(2, titles, filters); + + if (noFileSpec) + { + // Use page title as suggested name for new document + if (title.Length() > 0) + { + //Replace "bad" filename characteres with "_" + PRUnichar space = (PRUnichar)' '; + PRUnichar dot = (PRUnichar)'.'; + PRUnichar bslash = (PRUnichar)'\\'; + PRUnichar fslash = (PRUnichar)'/'; + PRUnichar amp = (PRUnichar)'@'; + PRUnichar colon = (PRUnichar)':'; + PRUnichar underscore = (PRUnichar)'_'; + title = title.ReplaceChar(space, underscore); + title = title.ReplaceChar(dot, underscore); + title = title.ReplaceChar(bslash, underscore); + title = title.ReplaceChar(fslash, underscore); + title = title.ReplaceChar(amp, underscore); + title = title.ReplaceChar(colon, underscore); + fileName = title + nsString(".html"); + } + } else { + char *leafName = docFileSpec.GetLeafName(); + if (leafName) + { + fileName = leafName; + nsCRT::free(leafName); + } + docFileSpec.GetParent(parentPath); + + // TODO: CHANGE TO THE DIRECTORY OF THE PARENT PATH? + } + if (fileName.Length() > 0) + fileWidget->SetDefaultString(fileName); SkipFilters: nsFileDlgResults dialogResult; // 1ST PARAM SHOULD BE nsIDOMWindow*, not nsIWidget* - dialogResult = fileWidget->PutFile(/*mContentWindow*/nsnull, promptString, docFileSpec); + dialogResult = fileWidget->PutFile(nsnull, promptString, docFileSpec); delete [] titles; delete [] filters; @@ -1449,20 +1492,43 @@ nsEditorShell::GetLocalFileURL(nsIDOMWindow *parent, const PRUnichar *filterType if (NS_SUCCEEDED(res)) { nsFileDlgResults dialogResult; + nsString* titles = nsnull; + nsString* filters = nsnull; + nsString* nextTitle; + nsString* nextFilter; + if (htmlFilter) { - nsAutoString titles[] = {"HTML Files"}; - nsAutoString filters[] = {"*.htm; *.html; *.shtml"}; - fileWidget->SetFilterList(1, titles, filters); - // First param should be Parent window, but type is nsIWidget* - // Bug is filed to change this to a more suitable window type - dialogResult = fileWidget->GetFile(/*parent*/ nsnull, title, fileSpec); + titles = new nsString[3]; + filters = new nsString[3]; + if (!titles || ! filters) + return NS_ERROR_OUT_OF_MEMORY; + nextTitle = titles; + nextFilter = filters; + *nextTitle++ = GetString("HTMLFiles"); + *nextTitle++ = GetString("TextFiles"); + *nextFilter++ = "*.htm; *.html; *.shtml"; + *nextFilter++ = "*.txt"; + fileWidget->SetFilterList(3, titles, filters); } else { - nsAutoString imgTitles[] = {"Image Files"}; - nsAutoString imgFilters[] = {"*.gif; *.jpg; *.jpeg; *.png"}; - fileWidget->SetFilterList(1, imgTitles, imgFilters); - dialogResult = fileWidget->GetFile(/*parent*/ nsnull, title, fileSpec); + titles = new nsString[2]; + filters = new nsString[2]; + if (!titles || ! filters) + return NS_ERROR_OUT_OF_MEMORY; + nextTitle = titles; + nextFilter = filters; + *nextTitle++ = GetString("IMGFiles"); + *nextFilter++ = "*.gif; *.jpg; *.jpeg; *.png", "*.*"; + fileWidget->SetFilterList(2, titles, filters); } + *nextTitle++ = GetString("AllFiles"); + *nextFilter++ = "*.*"; + // First param should be Parent window, but type is nsIWidget* + // Bug is filed to change this to a more suitable window type + dialogResult = fileWidget->GetFile(/*parent*/ nsnull, title, fileSpec); + delete [] titles; + delete [] filters; + // Do this after we get this from preferences //fileWidget->SetDisplayDirectory(aDisplayDirectory); @@ -1484,10 +1550,23 @@ nsEditorShell::GetLocalFileURL(nsIDOMWindow *parent, const PRUnichar *filterType NS_IMETHODIMP nsEditorShell::UpdateWindowTitle() +{ + if (!mContentAreaWebShell) + return NS_ERROR_NOT_INITIALIZED; + + nsAutoString windowCaption; + nsresult res = GetDocumentTitle(windowCaption); + if (NS_SUCCEEDED(res)) + res = mContentAreaWebShell->SetTitle(windowCaption.GetUnicode()); + return res; +} + +NS_IMETHODIMP +nsEditorShell::GetDocumentTitle(nsString& title) { nsresult res = NS_ERROR_NOT_INITIALIZED; - if (!mEditor && !mContentAreaWebShell) + if (!mEditor) return res; nsCOMPtr editor = do_QueryInterface(mEditor); @@ -1495,41 +1574,59 @@ nsEditorShell::UpdateWindowTitle() return res; nsCOMPtr domDoc; - editor->GetDocument(getter_AddRefs(domDoc)); - if (domDoc) + res = editor->GetDocument(getter_AddRefs(domDoc)); + if (NS_SUCCEEDED(res) && domDoc) { // Get the document title nsCOMPtr HTMLDoc = do_QueryInterface(domDoc); if (HTMLDoc) - { - nsAutoString windowCaption; - HTMLDoc->GetTitle(windowCaption); - if (windowCaption.Length() == 0) - { - // Set the window title to be "untitled" - windowCaption = GetString("UntitledWithParens"); - } + res = HTMLDoc->GetTitle(title); - // Append " - Composer" to the title - windowCaption += (nsString(" ") + GetString("ComposerCaptionSuffix")); - res = mContentAreaWebShell->SetTitle(windowCaption.GetUnicode()); - } + // If title is empty, use "untitled" + if (title.Length() == 0) + title = GetString("untitled"); + } + return res; +} + +// JavaScript version +NS_IMETHODIMP +nsEditorShell::GetDocumentTitle(PRUnichar **title) +{ + if (!title) + return NS_ERROR_NULL_POINTER; + + nsAutoString titleStr; + nsresult res = GetDocumentTitle(titleStr); + if (NS_SUCCEEDED(res)) + { + *title = titleStr.ToNewUnicode(); + } else { + // Don't fail, just return an empty string + nsAutoString empty(""); + *title = empty.ToNewUnicode(); + res = NS_OK; } return res; } NS_IMETHODIMP -nsEditorShell::SetTitle(const PRUnichar *title) +nsEditorShell::SetDocumentTitle(const PRUnichar *title) { nsresult res = NS_ERROR_NOT_INITIALIZED; if (!mEditor && !mContentAreaWebShell) return res; + // This should only be allowed for HTML documents + if (mEditorType != eHTMLTextEditorType) + return NS_ERROR_NOT_IMPLEMENTED; + nsCOMPtr editor = do_QueryInterface(mEditor); if (!editor) - return res; + return NS_ERROR_FAILURE; + nsAutoString titleStr(title); nsCOMPtr domDoc; res = editor->GetDocument(getter_AddRefs(domDoc)); @@ -1541,7 +1638,7 @@ nsEditorShell::SetTitle(const PRUnichar *title) { // This sets the window title, and saves the title as a member varialble, // but does NOT insert the node. - HTMLDoc->SetTitle(nsString(title)); + HTMLDoc->SetTitle(titleStr); nsCOMPtr<nsIDOMNodeList> titleList; nsCOMPtr<nsIDOMNode>titleNode; @@ -1590,7 +1687,8 @@ nsEditorShell::SetTitle(const PRUnichar *title) if (headNode) { PRBool newTitleNode = PR_FALSE; - if (!titleNode) { + if (!titleNode) + { // Didn't find one above: Create a new one nsCOMPtr<nsIDOMElement>titleElement; res = domDoc->CreateElement("title",getter_AddRefs(titleElement)); @@ -1599,23 +1697,24 @@ nsEditorShell::SetTitle(const PRUnichar *title) titleNode = do_QueryInterface(titleElement); newTitleNode = PR_TRUE; } + // Note: There should ALWAYS be a <title> in any HTML document, + // so we will insert the node and not make it undoable + res = headNode->AppendChild(titleNode, getter_AddRefs(resultNode)); + if (NS_FAILED(res)) + return NS_ERROR_FAILURE; } - if (titleNode) + // Append a text node under the TITLE + // only if the title text isn't empty + if (titleNode && titleStr.Length() > 0) { - // Append a text node under the TITLE nsCOMPtr<nsIDOMText> textNode; - res = domDoc->CreateTextNode(title, getter_AddRefs(textNode)); + res = domDoc->CreateTextNode(titleStr, getter_AddRefs(textNode)); if (NS_SUCCEEDED(res) && textNode) { - - // Finally, append the titleNode+child text node to the document <head> - // SHOULD THIS GO THROUGH TRANSACTION SYSTEM? - // If yes, use: editor->InsertElement(titleNode, headNode, 0) for the created node - // or editor->InsertElement(textNode, headNode, 0) if we already had a title node - res = titleNode->AppendChild(textNode,getter_AddRefs(resultNode)); - // Append the new node to the head - if (NS_SUCCEEDED(res) && newTitleNode) - res = headNode->AppendChild(titleNode, getter_AddRefs(resultNode)); + // Go through the editor API so action is undoable + res = editor->InsertNode(textNode, headNode, 0); + // This is the non-undoable code: + //res = titleNode->AppendChild(textNode,getter_AddRefs(resultNode)); } } } diff --git a/mozilla/editor/base/nsEditorShell.h b/mozilla/editor/base/nsEditorShell.h index bafbd12a365..5cca0711402 100644 --- a/mozilla/editor/base/nsEditorShell.h +++ b/mozilla/editor/base/nsEditorShell.h @@ -204,6 +204,9 @@ class nsEditorShell : public nsIEditorShell, // Get a string from the string bundle file nsString GetString(const nsString& name); + + // Get the text of the <title> tag + NS_IMETHOD GetDocumentTitle(nsString& title); // Get the current document title an use it as part of the window title // Uses "(Untitled)" for empty title diff --git a/mozilla/editor/base/nsTextEditRules.cpp b/mozilla/editor/base/nsTextEditRules.cpp index c00c306d1c8..27ea87c1cfb 100644 --- a/mozilla/editor/base/nsTextEditRules.cpp +++ b/mozilla/editor/base/nsTextEditRules.cpp @@ -197,7 +197,8 @@ nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection, case kOutputText: return DidOutputText(aSelection, aResult); } - return NS_ERROR_FAILURE; + // Don't fail on transactions we don't handle here! + return NS_OK; } diff --git a/mozilla/editor/composer/src/nsEditorShell.cpp b/mozilla/editor/composer/src/nsEditorShell.cpp index 2e07fa6df88..01094424eda 100644 --- a/mozilla/editor/composer/src/nsEditorShell.cpp +++ b/mozilla/editor/composer/src/nsEditorShell.cpp @@ -1173,7 +1173,10 @@ nsEditorShell::CheckAndSaveDocument(PRBool *_retval) // Ask user if they want to save current changes nsAutoString tmp1 = GetString("Save"); nsAutoString tmp2 = GetString("DontSave"); - EConfirmResult result = ConfirmWithCancel(GetString("SaveDocument"), GetString("SaveFilePrompt"), + nsAutoString title; + GetDocumentTitle(title); + nsAutoString saveMsg = GetString("SaveFilePrompt")+" "+"\""+title+"\""+GetString("QuestionMark"); + EConfirmResult result = ConfirmWithCancel(GetString("SaveDocument"), saveMsg, &tmp1, &tmp2); if (result == eCancel) { @@ -1216,7 +1219,8 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) // find out if the doc already has a fileSpec associated with it. nsFileSpec docFileSpec; - PRBool mustShowFileDialog = saveAs || (diskDoc->GetFileSpec(docFileSpec) == NS_ERROR_NOT_INITIALIZED); + PRBool noFileSpec = (diskDoc->GetFileSpec(docFileSpec) == NS_ERROR_NOT_INITIALIZED); + PRBool mustShowFileDialog = saveAs || noFileSpec; PRBool replacing = !saveAs; if (mustShowFileDialog) @@ -1230,7 +1234,8 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) nsString title; res = HTMLDoc->GetTitle(title); - if (NS_SUCCEEDED(res) && title.Length() == 0) + // Prompt for title ONLY for a new blank doc (no filespec yet) + if (noFileSpec && NS_SUCCEEDED(res) && title.Length() == 0) { // Use a "prompt" common dialog to get title string from user NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &res); @@ -1250,7 +1255,8 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) return NS_OK; } //This will call UpdateWindowTitle - SetTitle(titleUnicode); + SetDocumentTitle(titleUnicode); + title = titleUnicode; bUpdateWindowTitle = PR_FALSE; nsCRT::free(titleUnicode); } @@ -1260,14 +1266,16 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) res = nsComponentManager::CreateInstance(kCFileWidgetCID, nsnull, nsIFileWidget::GetIID(), getter_AddRefs(fileWidget)); if (NS_SUCCEEDED(res) && fileWidget) { - nsString promptString = GetString("SaveDocumentAs"); + nsAutoString promptString = GetString("SaveDocumentAs"); nsString* titles = nsnull; nsString* filters = nsnull; nsString* nextTitle; nsString* nextFilter; - nsString HTMLFiles; - nsString TextFiles; + nsAutoString HTMLFiles; + nsAutoString TextFiles; + nsAutoString fileName; + nsFileSpec parentPath; titles = new nsString[2]; if (!titles) @@ -1289,15 +1297,50 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval) if (HTMLFiles.Length() == 0 || TextFiles.Length() == 0) goto SkipFilters; - *nextTitle++ = "HTML Files"; + *nextTitle++ = HTMLFiles; *nextFilter++ = "*.htm; *.html; *.shtml"; - *nextTitle++ = "Text Files"; + *nextTitle++ = TextFiles; *nextFilter++ = "*.txt"; fileWidget->SetFilterList(2, titles, filters); + + if (noFileSpec) + { + // Use page title as suggested name for new document + if (title.Length() > 0) + { + //Replace "bad" filename characteres with "_" + PRUnichar space = (PRUnichar)' '; + PRUnichar dot = (PRUnichar)'.'; + PRUnichar bslash = (PRUnichar)'\\'; + PRUnichar fslash = (PRUnichar)'/'; + PRUnichar amp = (PRUnichar)'@'; + PRUnichar colon = (PRUnichar)':'; + PRUnichar underscore = (PRUnichar)'_'; + title = title.ReplaceChar(space, underscore); + title = title.ReplaceChar(dot, underscore); + title = title.ReplaceChar(bslash, underscore); + title = title.ReplaceChar(fslash, underscore); + title = title.ReplaceChar(amp, underscore); + title = title.ReplaceChar(colon, underscore); + fileName = title + nsString(".html"); + } + } else { + char *leafName = docFileSpec.GetLeafName(); + if (leafName) + { + fileName = leafName; + nsCRT::free(leafName); + } + docFileSpec.GetParent(parentPath); + + // TODO: CHANGE TO THE DIRECTORY OF THE PARENT PATH? + } + if (fileName.Length() > 0) + fileWidget->SetDefaultString(fileName); SkipFilters: nsFileDlgResults dialogResult; // 1ST PARAM SHOULD BE nsIDOMWindow*, not nsIWidget* - dialogResult = fileWidget->PutFile(/*mContentWindow*/nsnull, promptString, docFileSpec); + dialogResult = fileWidget->PutFile(nsnull, promptString, docFileSpec); delete [] titles; delete [] filters; @@ -1449,20 +1492,43 @@ nsEditorShell::GetLocalFileURL(nsIDOMWindow *parent, const PRUnichar *filterType if (NS_SUCCEEDED(res)) { nsFileDlgResults dialogResult; + nsString* titles = nsnull; + nsString* filters = nsnull; + nsString* nextTitle; + nsString* nextFilter; + if (htmlFilter) { - nsAutoString titles[] = {"HTML Files"}; - nsAutoString filters[] = {"*.htm; *.html; *.shtml"}; - fileWidget->SetFilterList(1, titles, filters); - // First param should be Parent window, but type is nsIWidget* - // Bug is filed to change this to a more suitable window type - dialogResult = fileWidget->GetFile(/*parent*/ nsnull, title, fileSpec); + titles = new nsString[3]; + filters = new nsString[3]; + if (!titles || ! filters) + return NS_ERROR_OUT_OF_MEMORY; + nextTitle = titles; + nextFilter = filters; + *nextTitle++ = GetString("HTMLFiles"); + *nextTitle++ = GetString("TextFiles"); + *nextFilter++ = "*.htm; *.html; *.shtml"; + *nextFilter++ = "*.txt"; + fileWidget->SetFilterList(3, titles, filters); } else { - nsAutoString imgTitles[] = {"Image Files"}; - nsAutoString imgFilters[] = {"*.gif; *.jpg; *.jpeg; *.png"}; - fileWidget->SetFilterList(1, imgTitles, imgFilters); - dialogResult = fileWidget->GetFile(/*parent*/ nsnull, title, fileSpec); + titles = new nsString[2]; + filters = new nsString[2]; + if (!titles || ! filters) + return NS_ERROR_OUT_OF_MEMORY; + nextTitle = titles; + nextFilter = filters; + *nextTitle++ = GetString("IMGFiles"); + *nextFilter++ = "*.gif; *.jpg; *.jpeg; *.png", "*.*"; + fileWidget->SetFilterList(2, titles, filters); } + *nextTitle++ = GetString("AllFiles"); + *nextFilter++ = "*.*"; + // First param should be Parent window, but type is nsIWidget* + // Bug is filed to change this to a more suitable window type + dialogResult = fileWidget->GetFile(/*parent*/ nsnull, title, fileSpec); + delete [] titles; + delete [] filters; + // Do this after we get this from preferences //fileWidget->SetDisplayDirectory(aDisplayDirectory); @@ -1484,10 +1550,23 @@ nsEditorShell::GetLocalFileURL(nsIDOMWindow *parent, const PRUnichar *filterType NS_IMETHODIMP nsEditorShell::UpdateWindowTitle() +{ + if (!mContentAreaWebShell) + return NS_ERROR_NOT_INITIALIZED; + + nsAutoString windowCaption; + nsresult res = GetDocumentTitle(windowCaption); + if (NS_SUCCEEDED(res)) + res = mContentAreaWebShell->SetTitle(windowCaption.GetUnicode()); + return res; +} + +NS_IMETHODIMP +nsEditorShell::GetDocumentTitle(nsString& title) { nsresult res = NS_ERROR_NOT_INITIALIZED; - if (!mEditor && !mContentAreaWebShell) + if (!mEditor) return res; nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor); @@ -1495,41 +1574,59 @@ nsEditorShell::UpdateWindowTitle() return res; nsCOMPtr<nsIDOMDocument> domDoc; - editor->GetDocument(getter_AddRefs(domDoc)); - if (domDoc) + res = editor->GetDocument(getter_AddRefs(domDoc)); + if (NS_SUCCEEDED(res) && domDoc) { // Get the document title nsCOMPtr<nsIDOMHTMLDocument> HTMLDoc = do_QueryInterface(domDoc); if (HTMLDoc) - { - nsAutoString windowCaption; - HTMLDoc->GetTitle(windowCaption); - if (windowCaption.Length() == 0) - { - // Set the window title to be "untitled" - windowCaption = GetString("UntitledWithParens"); - } + res = HTMLDoc->GetTitle(title); - // Append " - Composer" to the title - windowCaption += (nsString(" ") + GetString("ComposerCaptionSuffix")); - res = mContentAreaWebShell->SetTitle(windowCaption.GetUnicode()); - } + // If title is empty, use "untitled" + if (title.Length() == 0) + title = GetString("untitled"); + } + return res; +} + +// JavaScript version +NS_IMETHODIMP +nsEditorShell::GetDocumentTitle(PRUnichar **title) +{ + if (!title) + return NS_ERROR_NULL_POINTER; + + nsAutoString titleStr; + nsresult res = GetDocumentTitle(titleStr); + if (NS_SUCCEEDED(res)) + { + *title = titleStr.ToNewUnicode(); + } else { + // Don't fail, just return an empty string + nsAutoString empty(""); + *title = empty.ToNewUnicode(); + res = NS_OK; } return res; } NS_IMETHODIMP -nsEditorShell::SetTitle(const PRUnichar *title) +nsEditorShell::SetDocumentTitle(const PRUnichar *title) { nsresult res = NS_ERROR_NOT_INITIALIZED; if (!mEditor && !mContentAreaWebShell) return res; + // This should only be allowed for HTML documents + if (mEditorType != eHTMLTextEditorType) + return NS_ERROR_NOT_IMPLEMENTED; + nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor); if (!editor) - return res; + return NS_ERROR_FAILURE; + nsAutoString titleStr(title); nsCOMPtr<nsIDOMDocument> domDoc; res = editor->GetDocument(getter_AddRefs(domDoc)); @@ -1541,7 +1638,7 @@ nsEditorShell::SetTitle(const PRUnichar *title) { // This sets the window title, and saves the title as a member varialble, // but does NOT insert the <title> node. - HTMLDoc->SetTitle(nsString(title)); + HTMLDoc->SetTitle(titleStr); nsCOMPtr<nsIDOMNodeList> titleList; nsCOMPtr<nsIDOMNode>titleNode; @@ -1590,7 +1687,8 @@ nsEditorShell::SetTitle(const PRUnichar *title) if (headNode) { PRBool newTitleNode = PR_FALSE; - if (!titleNode) { + if (!titleNode) + { // Didn't find one above: Create a new one nsCOMPtr<nsIDOMElement>titleElement; res = domDoc->CreateElement("title",getter_AddRefs(titleElement)); @@ -1599,23 +1697,24 @@ nsEditorShell::SetTitle(const PRUnichar *title) titleNode = do_QueryInterface(titleElement); newTitleNode = PR_TRUE; } + // Note: There should ALWAYS be a <title> in any HTML document, + // so we will insert the node and not make it undoable + res = headNode->AppendChild(titleNode, getter_AddRefs(resultNode)); + if (NS_FAILED(res)) + return NS_ERROR_FAILURE; } - if (titleNode) + // Append a text node under the TITLE + // only if the title text isn't empty + if (titleNode && titleStr.Length() > 0) { - // Append a text node under the TITLE nsCOMPtr<nsIDOMText> textNode; - res = domDoc->CreateTextNode(title, getter_AddRefs(textNode)); + res = domDoc->CreateTextNode(titleStr, getter_AddRefs(textNode)); if (NS_SUCCEEDED(res) && textNode) { - - // Finally, append the titleNode+child text node to the document <head> - // SHOULD THIS GO THROUGH TRANSACTION SYSTEM? - // If yes, use: editor->InsertElement(titleNode, headNode, 0) for the created node - // or editor->InsertElement(textNode, headNode, 0) if we already had a title node - res = titleNode->AppendChild(textNode,getter_AddRefs(resultNode)); - // Append the new node to the head - if (NS_SUCCEEDED(res) && newTitleNode) - res = headNode->AppendChild(titleNode, getter_AddRefs(resultNode)); + // Go through the editor API so action is undoable + res = editor->InsertNode(textNode, headNode, 0); + // This is the non-undoable code: + //res = titleNode->AppendChild(textNode,getter_AddRefs(resultNode)); } } } diff --git a/mozilla/editor/composer/src/nsEditorShell.h b/mozilla/editor/composer/src/nsEditorShell.h index bafbd12a365..5cca0711402 100644 --- a/mozilla/editor/composer/src/nsEditorShell.h +++ b/mozilla/editor/composer/src/nsEditorShell.h @@ -204,6 +204,9 @@ class nsEditorShell : public nsIEditorShell, // Get a string from the string bundle file nsString GetString(const nsString& name); + + // Get the text of the <title> tag + NS_IMETHOD GetDocumentTitle(nsString& title); // Get the current document title an use it as part of the window title // Uses "(Untitled)" for empty title diff --git a/mozilla/editor/idl/nsIEditorShell.idl b/mozilla/editor/idl/nsIEditorShell.idl index 615c6c10d9e..814b29aae1d 100644 --- a/mozilla/editor/idl/nsIEditorShell.idl +++ b/mozilla/editor/idl/nsIEditorShell.idl @@ -62,8 +62,14 @@ interface nsIEditorShell : nsISupports void SetToolbarWindow(in nsIDOMWindow win); void SetContentWindow(in nsIDOMWindow win); void SetWebShellWindow(in nsIDOMWindow win); - void SetTitle(in wstring title); void LoadUrl(in wstring url); + + /* Set the value of the <title> tag in the <head> of a document + * Also uses this to set the editing window caption + */ + void SetDocumentTitle(in wstring title); + /* Get value of the <title> tag */ + wstring GetDocumentTitle(); /** Register a doc state listener. This gets added to a list of listeners which are registered with the editor when that gets instantiated. diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.cpp b/mozilla/editor/libeditor/text/nsTextEditRules.cpp index c00c306d1c8..27ea87c1cfb 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditRules.cpp @@ -197,7 +197,8 @@ nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection, case kOutputText: return DidOutputText(aSelection, aResult); } - return NS_ERROR_FAILURE; + // Don't fail on transactions we don't handle here! + return NS_OK; } diff --git a/mozilla/editor/ui/composer/content/EditorAppShell.xul b/mozilla/editor/ui/composer/content/EditorAppShell.xul index 4eb6d143a8b..db39a6ef9b8 100644 --- a/mozilla/editor/ui/composer/content/EditorAppShell.xul +++ b/mozilla/editor/ui/composer/content/EditorAppShell.xul @@ -38,11 +38,16 @@ <window id="main-window" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="EditorOnLoad()" - onunload="EditorShutdown()" title="&editorWindow.title;" align="vertical" + onunload="EditorShutdown()" + titlemodifier="&editorWindow.titlemodifier;" + titlemenuseparator="&editorWindow.titlemodifiermenuseparator;" + align="vertical" width="640" height="480"> <html:script language="JavaScript" src="chrome://editor/content/EditorCommands.js"/> + <!-- Use this when we abandon the default startup page --> + <!-- broadcaster id="args" value="about:blank"/ --> <broadcaster id="args" value="chrome://editor/content/EditorInitPage.html"/> <broadcaster id="canPrint"/> @@ -203,7 +208,7 @@ <editor type="content-primary" id="content-frame" src="about:blank" flex="100%"/> - <box align="horizontal" id="DisplayModeBar"> + <box align="horizontal" id="DisplayModeBar" style="padding-top: 0px"> <spring class="spacer"/> <!-- This is a pain: can't use CSS margin to add extra space above text? --> <box align="vertical"> diff --git a/mozilla/editor/ui/composer/content/EditorContent.css b/mozilla/editor/ui/composer/content/EditorContent.css index 9fb025a0404..a36c9e01a94 100644 --- a/mozilla/editor/ui/composer/content/EditorContent.css +++ b/mozilla/editor/ui/composer/content/EditorContent.css @@ -29,7 +29,7 @@ a[name] { padding-left: 20px; - background: url(chrome://editor/skin/images/left.gif) 5px 50% no-repeat; + background: url(chrome://editor/skin/images/anchor.gif) 5px 50% no-repeat; } table { diff --git a/mozilla/editor/ui/composer/content/TextEditorAppShell.xul b/mozilla/editor/ui/composer/content/TextEditorAppShell.xul index 4fa595017d2..0677a4db0bb 100644 --- a/mozilla/editor/ui/composer/content/TextEditorAppShell.xul +++ b/mozilla/editor/ui/composer/content/TextEditorAppShell.xul @@ -32,7 +32,10 @@ <window id="main-window" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - onunload="EditorShutdown()" title="&textEditorWindow.title;" align="vertical" + onunload="EditorShutdown()" + titlemodifier="&textEditorWindow.titlemodifier;" + titlemenuseparator="&editorWindow.titlemodifiermenuseparator;" + align="vertical" width="640" height="480"> <html:script language="JavaScript" src="chrome://editor/content/EditorCommands.js"> diff --git a/mozilla/editor/ui/composer/content/editorOverlay.xul b/mozilla/editor/ui/composer/content/editorOverlay.xul index a5353c0ec67..fe57023c473 100644 --- a/mozilla/editor/ui/composer/content/editorOverlay.xul +++ b/mozilla/editor/ui/composer/content/editorOverlay.xul @@ -21,8 +21,6 @@ - Contributor(s): --> -<?xul-overlay href="chrome://global/content/globalOverlay.xul"?> - <!DOCTYPE window SYSTEM "chrome://editor/locale/editorOverlay.dtd"> <overlay id="editorOverlay" @@ -134,7 +132,6 @@ <!-- Broadcaster nodes --> - <!-- Note: NewEditor items are now in globalOverlay.xul --> <broadcaster id="Editor:Open" value="&openCmd.label;" oncommand="EditorOpen()"/> <broadcaster id="Editor:Save" value="&saveCmd.label;" disabled="true" oncommand="EditorSave()"/> <broadcaster id="Editor:SaveAs" value="&saveAsCmd.label;" disabled="false" oncommand="EditorSaveAs()"/> @@ -638,7 +635,7 @@ <titledbutton id="hlineButton" src="&hlineIcon.url;" value="&hruleToolbarCmd.label;" onclick="EditorInsertHLine()"/> <titledbutton id="tableButton" src="&tableIcon.url;" value="&tableToolbarCmd.label;" onclick="EditorInsertOrEditTable(true)"/> <titledbutton id="linkButton" src="&linkIcon.url;" value="&linkToolbarCmd.label;" onclick="EditorInsertLink()"/> - <titledbutton id="namedAnchorButton" src="&targetIcon.url;" value="&anchorToolbarCmd.label;" onclick="EditorInsertNamedAnchor()"/> + <titledbutton id="namedAnchorButton" src="&anchorIcon.url;" value="&anchorToolbarCmd.label;" onclick="EditorInsertNamedAnchor()"/> <!-- Formatting toolbar items --> <titledbutton style="width:68pt" id="ParagraphPopupButton" value="¶graphToolbarMenu.label;" class="popup" align="left" popupanchor="bottomleft"> @@ -676,6 +673,7 @@ <!-- DEBUG only --> <menu id="debugMenu" value="&debugMenu.label;"> <menupopup> + <menuitem value="Composer with Test Page" oncommand="window.openDialog('chrome://editor/content','_blank','chrome,all,dialog=no','chrome://editor/content/EditorInitPage.html')"/> <menuitem value="&outputTextCmd.label;" oncommand="EditorGetText()"/> <menuitem value="&outputHTMLCmd.label;" diff --git a/mozilla/editor/ui/composer/locale/en-US/EditorAppShell.dtd b/mozilla/editor/ui/composer/locale/en-US/EditorAppShell.dtd index 28af47c46fd..0666089278c 100644 --- a/mozilla/editor/ui/composer/locale/en-US/EditorAppShell.dtd +++ b/mozilla/editor/ui/composer/locale/en-US/EditorAppShell.dtd @@ -21,8 +21,10 @@ --> <!-- Window title --> -<!ENTITY editorWindow.title "Editor"> -<!ENTITY textEditorWindow.title "Text Editor"> +<!-- LOCALIZATION NOTE mainWindow.title: Do NOT localize "Composer" --> +<!ENTITY editorWindow.titlemodifier "Composer"> +<!ENTITY editorWindow.titlemodifiermenuseparator " - "> +<!ENTITY textEditorWindow.titlemodifier "Text Editor"> <!-- Menu items: the . means that the menu item isn't implemented yet --> @@ -42,6 +44,9 @@ <!ENTITY aboutCmd.label ".About"> <!-- Display Mode Toolbar --> -<!ENTITY displayMode.label "Display Mode:"> -<!ENTITY editModeButton.label "Normal Editing"> -<!ENTITY browserModeButton.label "Edit in Browser Layout"> +<!ENTITY displayMode.label "Edit Mode:"> +<!ENTITY editModeButton.label "Normal"> +<!ENTITY browserModeButton.label "Browser"> +<!ENTITY viewModeButton.label "View Mode:"> +<!ENTITY htmlModeButton.label "HTML Source"> +<!ENTITY treeModeButton.label "Tag Tree"> diff --git a/mozilla/editor/ui/composer/locale/en-US/editor.properties b/mozilla/editor/ui/composer/locale/en-US/editor.properties index eababf50d08..7f825540dc2 100644 --- a/mozilla/editor/ui/composer/locale/en-US/editor.properties +++ b/mozilla/editor/ui/composer/locale/en-US/editor.properties @@ -22,8 +22,11 @@ NoSuggestedWords=(no suggested words) NoMisspelledWord=No misspelled word was found. CheckSpelling=Check Spelling HTMLFiles=HTML Files +IMGFiles=Image Files TextFiles=Text Files -SaveFilePrompt=Save changes to current file? +AllFiles=All Files +SaveFilePrompt=Save changes to +QuestionMark=? SaveFileFailed=Saving file failed! DocumentTitle=Document Title NeedDocTitle=Enter a title for the current page./nThe title identifies the page in the window title and bookmarks. @@ -33,8 +36,6 @@ EmptyHREFError=You must enter or choose<br>a location (URL) to create a new link LinkText=Link text: EnterLinkText=Enter text to display for the link: EmptyLinkTextError=You must enter some text for this link. -HeadingsCaption=Headings: -NamedAnchorsCaption=NamedAnchors: ValidateNumber1=The number you entered ( ValidateNumber2=) is outside of allowed range.<br>Please enter a number between ValidateNumber3=and @@ -55,6 +56,7 @@ Pixels=pixels Percent=percent PercentOfCell=% of cell PercentOfWindow=% of window -UntitledWithParens=(Untitled) +untitled=untitled ComposerCaptionSuffix=- Composer - +NoNamedAnchors=(No named anchors in this page) +NoHeadings=(No headings in this page) diff --git a/mozilla/editor/ui/composer/locale/en-US/editorOverlay.dtd b/mozilla/editor/ui/composer/locale/en-US/editorOverlay.dtd index 245c76452dd..f5ab9ca3dfb 100644 --- a/mozilla/editor/ui/composer/locale/en-US/editorOverlay.dtd +++ b/mozilla/editor/ui/composer/locale/en-US/editorOverlay.dtd @@ -435,7 +435,7 @@ <!ENTITY findIcon.url "chrome://editor/skin/images/find.gif"> <!ENTITY linkIcon.url "chrome://editor/skin/images/link.gif"> <!ENTITY imageIcon.url "chrome://editor/skin/images/image.gif"> -<!ENTITY targetIcon.url "chrome://editor/skin/images/target.gif"> +<!ENTITY anchorIcon.url "chrome://editor/skin/images/anchor.gif"> <!ENTITY hlineIcon.url "chrome://editor/skin/images/hline.gif"> <!ENTITY tableIcon.url "chrome://editor/skin/images/table.gif"> <!ENTITY spellingIcon.url "chrome://editor/skin/images/spell.gif"> diff --git a/mozilla/editor/ui/composer/skin/Editor.css b/mozilla/editor/ui/composer/skin/Editor.css index d692d915cd7..c923b97c79c 100644 --- a/mozilla/editor/ui/composer/skin/Editor.css +++ b/mozilla/editor/ui/composer/skin/Editor.css @@ -40,7 +40,8 @@ box#EditorProgessBox { } box#DisplayModeBar { - margin-top: -2px; + /*margin-top: -2px;*/ + border-top: 1px solid darkgray; min-width:30px; background-color: inherit; } diff --git a/mozilla/editor/ui/composer/skin/MANIFEST b/mozilla/editor/ui/composer/skin/MANIFEST index fe1c7dcd847..844c26d51d5 100644 --- a/mozilla/editor/ui/composer/skin/MANIFEST +++ b/mozilla/editor/ui/composer/skin/MANIFEST @@ -35,7 +35,7 @@ images:justify.gif images:numbers.gif images:redo.gif images:spell.gif -images:target.gif +images:anchor.gif images:undo.gif images:bullets.gif images:copy.gif @@ -73,4 +73,4 @@ images:savemod.gif images:publish.gif images:preview.gif images:print.gif -images:find.gif \ No newline at end of file +images:find.gif diff --git a/mozilla/editor/ui/composer/skin/Makefile.in b/mozilla/editor/ui/composer/skin/Makefile.in index 96f0175cf63..b092ea9fd4a 100644 --- a/mozilla/editor/ui/composer/skin/Makefile.in +++ b/mozilla/editor/ui/composer/skin/Makefile.in @@ -45,7 +45,7 @@ EXPORT_RESOURCE_TOOLBAR = \ $(srcdir)/images/redo.gif \ $(srcdir)/images/spell.gif \ $(srcdir)/images/table.gif \ - $(srcdir)/images/target.gif \ + $(srcdir)/images/anchor.gif \ $(srcdir)/images/underline.gif \ $(srcdir)/images/undo.gif \ $(srcdir)/images/text-color.gif \ diff --git a/mozilla/editor/ui/composer/skin/images/anchor.gif b/mozilla/editor/ui/composer/skin/images/anchor.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a99ceb6f1591f1653093cd1d1e036e7442d4ebd GIT binary patch literal 196 zcmZ?wbhEHb6lM@)_{_j?;J|_Zzdsx}z~JD(uwVg0Lj%Ks2MiA$G%Q%KgaI2+{K>)y z64wC{ATt<P3I$Ghu3qcNQ@ETXflYu#gX4%pEkneT)<U7ySFE`O8BIOcI->Kof4s=% z$jR;U=4^wL+If!9Z#-7_4klQrF{(Q{UU2DLoiMNXjP#OywoD1lQaoH+zjICB_?R=c cN>tujpE1_dLss6X(<5HCtY3DDxFCZy06r@|UjP6A literal 0 HcmV?d00001 diff --git a/mozilla/editor/ui/composer/skin/makefile.win b/mozilla/editor/ui/composer/skin/makefile.win index c635e29f74a..aaf9d05ed64 100644 --- a/mozilla/editor/ui/composer/skin/makefile.win +++ b/mozilla/editor/ui/composer/skin/makefile.win @@ -43,7 +43,7 @@ install:: $(DLL) $(MAKE_INSTALL) images\redo.gif $(DIST)\bin\chrome\editor\skin\default\images $(MAKE_INSTALL) images\spell.gif $(DIST)\bin\chrome\editor\skin\default\images $(MAKE_INSTALL) images\table.gif $(DIST)\bin\chrome\editor\skin\default\images - $(MAKE_INSTALL) images\target.gif $(DIST)\bin\chrome\editor\skin\default\images + $(MAKE_INSTALL) images\anchor.gif $(DIST)\bin\chrome\editor\skin\default\images $(MAKE_INSTALL) images\underline.gif $(DIST)\bin\chrome\editor\skin\default\images $(MAKE_INSTALL) images\undo.gif $(DIST)\bin\chrome\editor\skin\default\images $(MAKE_INSTALL) images\text-color.gif $(DIST)\bin\chrome\editor\skin\default\images @@ -87,7 +87,7 @@ clobber:: rm -f $(DIST)\bin\chrome\editor\skin\default\images\redo.gif rm -f $(DIST)\bin\chrome\editor\skin\default\images\spell.gif rm -f $(DIST)\bin\chrome\editor\skin\default\images\table.gif - rm -f $(DIST)\bin\chrome\editor\skin\default\images\target.gif + rm -f $(DIST)\bin\chrome\editor\skin\default\images\anchor.gif rm -f $(DIST)\bin\chrome\editor\skin\default\images\underline.gif rm -f $(DIST)\bin\chrome\editor\skin\default\images\undo.gif rm -f $(DIST)\bin\chrome\editor\skin\default\images\text-color.gif diff --git a/mozilla/editor/ui/dialogs/content/EdHLineProps.js b/mozilla/editor/ui/dialogs/content/EdHLineProps.js index b1897dbba47..535fdf3ceac 100644 --- a/mozilla/editor/ui/dialogs/content/EdHLineProps.js +++ b/mozilla/editor/ui/dialogs/content/EdHLineProps.js @@ -65,6 +65,9 @@ function Startup() // SET FOCUS TO FIRST CONTROL dialog.heightInput.focus(); + + // Resize window + window.sizeToContent(); } // Set dialog widgets with attribute data @@ -79,8 +82,6 @@ function InitDialog() // Get the width attribute of the element, stripping out "%" // This sets contents of combobox (adds pixel and percent option elements) dialog.widthInput.value = InitPixelOrPercentCombobox(globalElement,"width","pixelOrPercentSelect"); - // Resize window after filling combobox - window.sizeToContent(); align = globalElement.getAttribute("align"); if (align == "center") { diff --git a/mozilla/editor/ui/dialogs/content/EdInsertTable.js b/mozilla/editor/ui/dialogs/content/EdInsertTable.js index 63b19bb4f0a..62596f00d32 100644 --- a/mozilla/editor/ui/dialogs/content/EdInsertTable.js +++ b/mozilla/editor/ui/dialogs/content/EdInsertTable.js @@ -75,6 +75,9 @@ function Startup() dialog.columnsInput.value = 2; dialog.rowsInput.focus(); + + // Resize window + window.sizeToContent(); } // Set dialog widgets with attribute data @@ -87,9 +90,6 @@ function InitDialog() // This sets contents of select combobox list dialog.widthInput.value = InitPixelOrPercentCombobox(globalElement,"width","pixelOrPercentSelect"); dialog.borderInput.value = globalElement.getAttribute("border"); - - // Resize window after filling combobox - window.sizeToContent(); } // Get and validate data from widgets. diff --git a/mozilla/editor/ui/dialogs/content/EdLinkProps.js b/mozilla/editor/ui/dialogs/content/EdLinkProps.js index 33b294503ed..83cc67abe30 100644 --- a/mozilla/editor/ui/dialogs/content/EdLinkProps.js +++ b/mozilla/editor/ui/dialogs/content/EdLinkProps.js @@ -30,11 +30,10 @@ var hrefInput; var linkMessage; var href; var newLinkText; -var HeadingsIndex = -1; -var NamedAnchorsIndex = -1; var NamedAnchorList = 0; var HNodeArray; -var NamedAnchorLink = ""; +var haveNamedAnchors = false; +var haveHeadings = false; // NOTE: Use "href" instead of "a" to distinguish from Named Anchor // The returned node is has an "a" tagName @@ -49,11 +48,12 @@ function Startup() doSetOKCancel(onOK, null); // Message was wrapped in a <label> or <div>, so actual text is a child text node - linkCaption = (document.getElementById("linkTextCaption")).firstChild; - linkMessage = (document.getElementById("linkTextMessage")).firstChild; - linkTextInput = document.getElementById("linkTextInput"); - hrefInput = document.getElementById("hrefInput"); + linkCaption = (document.getElementById("linkTextCaption")).firstChild; + linkMessage = (document.getElementById("linkTextMessage")).firstChild; + linkTextInput = document.getElementById("linkTextInput"); + hrefInput = document.getElementById("hrefInput"); NamedAnchorList = document.getElementById("NamedAnchorList"); + HeadingsList = document.getElementById("HeadingsList"); // Get a single selected anchor element anchorElement = editorShell.GetSelectedElement(tagName); @@ -99,18 +99,13 @@ function Startup() dump("Element not selected - calling createElementWithDefaults\n"); anchorElement = editorShell.CreateElementWithDefaults(tagName); -dump("1\n"); - // We will insert a new link at caret location if there's no selection // TODO: This isn't entirely correct. If selection doesn't have any text // or an image, then shouldn't we clear the selection and insert new text? insertNew = selection.isCollapsed; -dump("2\n"); dump("insertNew is " + insertNew + "\n"); linkCaption.data = GetString("EnterLinkText"); -dump("3\n"); linkMessage.data = ""; -dump("4\n"); } } if(!anchorElement) @@ -121,21 +116,17 @@ dump("4\n"); // Replace the link message with the link source string selectedText = GetSelectionAsText(); -dump("5\n"); if (selectedText.length > 0) { // Use just the first 50 characters and add "..." selectedText = TruncateStringAtWordEnd(selectedText, 50, true); -dump("6\n"); } else { dump("Selected text for link source not found. Non-text elements selected?\n"); } linkMessage.data = selectedText; -dump("7\n"); // The label above the selected text: linkCaption.data = GetString("LinkText"); } -dump("8\n"); if (!selection.isCollapsed) { // HREF is a weird case: If selection extends beyond @@ -148,14 +139,11 @@ dump("8\n"); dump("insertLinkAroundSelection is TRUE\n"); } -dump("9\n"); // Make a copy to use for AdvancedEdit and onSaveDefault globalElement = anchorElement.cloneNode(false); -dump("10\n"); // Get the list of existing named anchors and headings - FillNamedAnchorList(); -dump("11\n"); + FillListboxes(); // Set data for the dialog controls InitDialog(); @@ -177,6 +165,8 @@ dump("11\n"); linkTextInput = null; } } + + window.sizeToContent(); } // Set dialog widgets with attribute data @@ -205,18 +195,18 @@ function RemoveLink() hrefInput.value = ""; } -function FillNamedAnchorList() +function FillListboxes() { NamedAnchorNodeList = editorShell.editorDocument.anchors; var NamedAnchorCount = NamedAnchorNodeList.length; if (NamedAnchorCount > 0) { - // Save index so we ignore if user selects it - NamedAnchorsIndex = 0; - AppendStringToListByID(NamedAnchorList,"NamedAnchorsCaption"); for (var i = 0; i < NamedAnchorCount; i++) { - // Prefix with some spaces to give an indented look - AppendStringToList(NamedAnchorList," "+NamedAnchorNodeList.item(i).name); + AppendStringToList(NamedAnchorList,NamedAnchorNodeList.item(i).name); } + haveNamedAnchors = true; + } else { + // Message to tell user there are none + AppendStringToList(NamedAnchorList,GetString("NoNamedAnchors")); } var firstHeading = true; for (var j = 1; j <= 6; j++) { @@ -240,21 +230,14 @@ function FillNamedAnchorList() range.setEnd(heading,lastChildIndex); var text = range.toString(); if (text) { - if (firstHeading) { - // Save index so we ignore if user selects it - HeadingsIndex = NamedAnchorList.length; - AppendStringToListByID(NamedAnchorList,"HeadingsCaption"); - firstHeading = false; - } // Use just first 40 characters, don't add "...", // and replace whitespace with "_" and strip non-word characters text = PrepareStringForURL(TruncateStringAtWordEnd(text, 40, false)); // Append "_" to any name already in the list - if (GetExistingAnchorIndex(text) > -1) + if (GetExistingHeadingIndex(text) > -1) text += "_"; - // Prefix with some spaces to give an indented look - AppendStringToList(NamedAnchorList," "+text); - dump("Heading text for Named Anchor: "+text+"\n"); + AppendStringToList(HeadingsList, text); + // Save nodes in an array so we can create anchor node under it later if (!HNodeArray) HNodeArray = new Array(heading) @@ -263,13 +246,18 @@ function FillNamedAnchorList() } } } + if (HNodeArray) { + haveHeadings = true; + } else { + // Message to tell user there are none + AppendStringToList(HeadingsList,GetString("NoHeadings")); + } } -function GetExistingAnchorIndex(text) +function GetExistingHeadingIndex(text) { - for (i=0; i < NamedAnchorList.length; i++) { - if (i != HeadingsIndex && i != NamedAnchorsIndex && - NamedAnchorList[i].name == name) + for (i=0; i < HeadingsList.length; i++) { + if (HeadingsList[i].name == name) return i; } return -1; @@ -277,9 +265,16 @@ function GetExistingAnchorIndex(text) function SelectNamedAnchor() { - var selIndex = NamedAnchorList.selectedIndex; - if (selIndex != HeadingsIndex && selIndex != NamedAnchorsIndex) - hrefInput.value = "#" + NamedAnchorList.options[selIndex].value.trimString(); + if (haveNamedAnchors) { + hrefInput.value = "#"+NamedAnchorList.options[NamedAnchorList.selectedIndex].value; + } +} + +function SelectHeading() +{ + if (haveHeadings) { + hrefInput.value = "#"+HeadingsList.options[HeadingsList.selectedIndex].value; + } } // Get and validate data from widgets. @@ -347,28 +342,24 @@ function onOK() return true; } } - // Check if the link was to a heading in - // the named anchor list. - if (HeadingsIndex > -1 && href[0] == "#") { + // Check if the link was to a heading + if (href[0] == "#") { var name = href.substr(1); - var index = GetExistingAnchorIndex(name); - - // This assumes Headings are always AFTER the Named Anchors in the list - dump("HeadingsIndex="+HeadingsIndex+" SelectIndex="+index+"\n"); - if (index > HeadingsIndex) { + var index = GetExistingHeadingIndex(name); + dump("Heading name="+name+" Index="+index+"\n"); + if (index >= 0) { // We need to create a named anchor // and insert it as the first child of the heading element - var headNode = HNodeList[index - (HeadingsIndex+1)]; + var headNode = HNodeArray[index]; var anchorNode = editorShell.editorDocument.createElement("a"); if (anchorNode) { anchorNode.name = name; // Remember to use editorShell method so it is undoable! - editorShell.InsertElement(anchorNode, headNode.parentNode, 0); + editorShell.InsertElement(anchorNode, headNode, 0); dump("Anchor node created and inserted under heading\n"); } - } - else { - dump("HREF is a named anchor but is not in the list!\n"); + } else { + dump("HREF is a heading but is not in the list!\n"); } } editorShell.EndBatchChanges(); diff --git a/mozilla/editor/ui/dialogs/content/EdLinkProps.xul b/mozilla/editor/ui/dialogs/content/EdLinkProps.xul index c1e95b8c80c..792feb894e9 100644 --- a/mozilla/editor/ui/dialogs/content/EdLinkProps.xul +++ b/mozilla/editor/ui/dialogs/content/EdLinkProps.xul @@ -68,7 +68,11 @@ </xul:box> <xul:spring class="spacer"/> <div>&NamedAnchorMsg.label;</div> - <select id="NamedAnchorList" style="width: 15em;" size="5" onchange="SelectNamedAnchor()"/> + <select id="NamedAnchorList" style="width: 15em;" size="3" onchange="SelectNamedAnchor()"/> + <xul:spring class="spacer"/> + <div>&HeadingMsg.label;</div> + <select id="HeadingsList" style="width: 15em;" size="3" onchange="SelectHeading()"/> + <div>&HeadingMsg2.label;</div> </fieldset> </xul:box> diff --git a/mozilla/editor/ui/dialogs/locale/en-US/EditorLinkProperties.dtd b/mozilla/editor/ui/dialogs/locale/en-US/EditorLinkProperties.dtd index a0ae992f11d..a3e8c7d7975 100644 --- a/mozilla/editor/ui/dialogs/locale/en-US/EditorLinkProperties.dtd +++ b/mozilla/editor/ui/dialogs/locale/en-US/EditorLinkProperties.dtd @@ -38,7 +38,8 @@ <!ENTITY LinkURLEditField.label "Enter a web page location or local file:"> <!ENTITY LinkChooseFileButton.label "Choose File..."> <!ENTITY RemoveLinkButton.label "Remove Link"> -<!ENTITY NamedAnchorMsg.label "Or select a named anchor or heading:"> -<!ENTITY NamedAnchorMissingMsg.label "Create named anchors and/or headings and they will appear in this list"> +<!ENTITY NamedAnchorMsg.label "or select a Named Anchor:"> +<!ENTITY HeadingMsg.label "or select a Heading:"> +<!ENTITY HeadingMsg2.label "(A named anchor will be created automatically)"> diff --git a/mozilla/suite/debugQA/content/debugQATextEditorShell.xul b/mozilla/suite/debugQA/content/debugQATextEditorShell.xul index 4fa595017d2..0677a4db0bb 100644 --- a/mozilla/suite/debugQA/content/debugQATextEditorShell.xul +++ b/mozilla/suite/debugQA/content/debugQATextEditorShell.xul @@ -32,7 +32,10 @@ <window id="main-window" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - onunload="EditorShutdown()" title="&textEditorWindow.title;" align="vertical" + onunload="EditorShutdown()" + titlemodifier="&textEditorWindow.titlemodifier;" + titlemenuseparator="&editorWindow.titlemodifiermenuseparator;" + align="vertical" width="640" height="480"> <html:script language="JavaScript" src="chrome://editor/content/EditorCommands.js">