Added command to notify when document url changes. b=181091, r=akkana, sr=sfraser

This commit is contained in:
cmanske%netscape.com 2002-11-27 00:35:09 +00:00
Родитель 14f4ce9143
Коммит 1c667569a9
7 изменённых файлов: 145 добавлений и 23 удалений

Просмотреть файл

@ -47,6 +47,8 @@
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIDOMWindowInternal.h" #include "nsIDOMWindowInternal.h"
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIURI.h"
#include "nsIClipboard.h" #include "nsIClipboard.h"
@ -58,6 +60,7 @@
#include "nsICommandParams.h" #include "nsICommandParams.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "nsCRT.h" #include "nsCRT.h"
//prototype //prototype
nsresult GetListState(nsIEditor *aEditor, PRBool *aMixed, PRUnichar **tagStr); nsresult GetListState(nsIEditor *aEditor, PRBool *aMixed, PRUnichar **tagStr);
nsresult RemoveOneProperty(nsIHTMLEditor *aEditor,const nsString& aProp, nsresult RemoveOneProperty(nsIHTMLEditor *aEditor,const nsString& aProp,
@ -1747,9 +1750,10 @@ nsSetDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
/** /**
* Commands just for state notification * Commands just for state notification
* As of 11/11/02, possible commands are: * As of 11/21/02, possible commands are:
* "obs_documentCreated" * "obs_documentCreated"
* "obs_documentWillBeDestroyed" * "obs_documentWillBeDestroyed"
* "obs_documentLocationChanged"
* Note that you can use the same command class, nsDocumentStateCommand * Note that you can use the same command class, nsDocumentStateCommand
* for these or future observer commands. * for these or future observer commands.
* We check the input command param for different behavior * We check the input command param for different behavior
@ -1817,13 +1821,13 @@ nsDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
nsICommandParams *aParams, nsICommandParams *aParams,
nsISupports *refCon) nsISupports *refCon)
{ {
NS_ENSURE_ARG_POINTER(aParams);
NS_ENSURE_ARG_POINTER(aCommandName); NS_ENSURE_ARG_POINTER(aCommandName);
nsCOMPtr<nsIEditingSession> editingSession = do_QueryInterface(refCon); nsCOMPtr<nsIEditingSession> editingSession = do_QueryInterface(refCon);
nsresult rv;
if (!nsCRT::strcmp(aCommandName, "obs_documentCreated")) if (!nsCRT::strcmp(aCommandName, "obs_documentCreated"))
{ {
NS_ENSURE_ARG_POINTER(aParams);
PRUint32 editorStatus = nsIEditingSession::eEditorErrorUnknown; PRUint32 editorStatus = nsIEditingSession::eEditorErrorUnknown;
if (editingSession) if (editingSession)
@ -1833,7 +1837,7 @@ nsDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
// Embedder gets error status if this fails // Embedder gets error status if this fails
// If called before startup is finished, // If called before startup is finished,
// status = eEditorCreationInProgress // status = eEditorCreationInProgress
nsresult rv = editingSession->GetEditorStatus(&editorStatus); rv = editingSession->GetEditorStatus(&editorStatus);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
else else
@ -1849,6 +1853,25 @@ nsDocumentStateCommand::GetCommandStateParams(const char *aCommandName,
aParams->SetLongValue(STATE_DATA, editorStatus); aParams->SetLongValue(STATE_DATA, editorStatus);
return NS_OK; return NS_OK;
} }
else if (!nsCRT::strcmp(aCommandName, "obs_documentLocationChanged"))
{
nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
if (editor)
{
nsCOMPtr<nsIDOMDocument> domDoc;
editor->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (!doc) return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> uri;
rv = doc->GetDocumentURL(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
if (!uri) return NS_ERROR_FAILURE;
return aParams->SetISupportsValue(STATE_DATA, (nsISupports*)uri);
}
return NS_OK;
}
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }

Просмотреть файл

@ -97,6 +97,7 @@ nsComposerController::RegisterEditorDocStateCommands(
// observer commands for document state // observer commands for document state
NS_REGISTER_ONE_COMMAND(nsDocumentStateCommand, "obs_documentCreated") NS_REGISTER_ONE_COMMAND(nsDocumentStateCommand, "obs_documentCreated")
NS_REGISTER_ONE_COMMAND(nsDocumentStateCommand, "obs_documentWillBeDestroyed") NS_REGISTER_ONE_COMMAND(nsDocumentStateCommand, "obs_documentWillBeDestroyed")
NS_REGISTER_ONE_COMMAND(nsDocumentStateCommand, "obs_documentLocationChanged")
// commands that may get or change state // commands that may get or change state
NS_REGISTER_ONE_COMMAND(nsSetDocumentStateCommand, "cmd_setDocumentModified") NS_REGISTER_ONE_COMMAND(nsSetDocumentStateCommand, "cmd_setDocumentModified")

Просмотреть файл

@ -41,7 +41,9 @@
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIDOMWindowInternal.h" #include "nsIDOMWindowInternal.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
#include "nsIURI.h"
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
#include "nsISelectionPrivate.h" #include "nsISelectionPrivate.h"
#include "nsITransactionManager.h" #include "nsITransactionManager.h"
@ -55,6 +57,8 @@
#include "nsIControllers.h" #include "nsIControllers.h"
#include "nsIController.h" #include "nsIController.h"
#include "nsIControllerContext.h" #include "nsIControllerContext.h"
#include "nsICommandManager.h"
#include "nsPICommandUpdater.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
@ -74,7 +78,6 @@
#include "nsEditorParserObserver.h" #include "nsEditorParserObserver.h"
#if DEBUG #if DEBUG
#include "nsIURI.h"
//#define NOISY_DOC_LOADING 1 //#define NOISY_DOC_LOADING 1
#endif #endif
@ -571,7 +574,8 @@ nsEditingSession::OnStateChange(nsIWebProgress *aWebProgress,
{ {
nsXPIDLCString spec; nsXPIDLCString spec;
uri->GetSpec(spec); uri->GetSpec(spec);
printf(" **** STATE_START: CHANNEL URI=%s, flags=%x\n",spec.get(), aStateFlags); printf(" **** STATE_START: CHANNEL URI=%s,
flags=%x\n",spec.get(), aStateFlags);
} }
} }
else else
@ -636,7 +640,8 @@ nsEditingSession::OnStateChange(nsIWebProgress *aWebProgress,
{ {
nsXPIDLCString spec; nsXPIDLCString spec;
uri->GetSpec(spec); uri->GetSpec(spec);
printf(" **** STATE_STOP: CHANNEL URI=%s, flags=%x\n",spec.get(), aStateFlags); printf(" **** STATE_STOP: CHANNEL URI=%s,
flags=%x\n",spec.get(), aStateFlags);
} }
} }
else else
@ -699,10 +704,34 @@ nsEditingSession::OnProgressChange(nsIWebProgress *aWebProgress,
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
NS_IMETHODIMP NS_IMETHODIMP
nsEditingSession::OnLocationChange(nsIWebProgress *aWebProgress, nsEditingSession::OnLocationChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest, nsIURI *location) nsIRequest *aRequest, nsIURI *aURI)
{ {
NS_NOTREACHED("notification excluded in AddProgressListener(...)"); nsCOMPtr<nsIDOMWindow> domWindow;
return NS_OK; nsresult rv = aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMDocument> domDoc;
rv = domWindow->GetDocument(getter_AddRefs(domDoc));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (!doc) return NS_ERROR_FAILURE;
rv = doc->SetDocumentURL(aURI);
if (NS_FAILED(rv)) return rv;
// Notify the location-changed observer that
// the document URL has changed
nsCOMPtr<nsIDocShell> docShell;
rv = GetDocShellFromWindow(domWindow, getter_AddRefs(docShell));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(docShell);
nsCOMPtr<nsPICommandUpdater> commandUpdater =
do_QueryInterface(commandManager);
if (!commandUpdater) return NS_ERROR_FAILURE;
return commandUpdater->CommandStatusChanged("obs_documentLocationChanged");
} }
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
@ -812,7 +841,8 @@ nsEditingSession::EndDocumentLoad(nsIWebProgress *aWebProgress,
#ifdef NOISY_DOC_LOADING #ifdef NOISY_DOC_LOADING
printf("Editing shell EndDocumentLoad\n"); printf("Editing shell EndDocumentLoad\n");
#endif #endif
// We want to call the base class EndDocumentLoad, but avoid some of the stuff // We want to call the base class EndDocumentLoad,
// but avoid some of the stuff
// that nsWebShell does (need to refactor). // that nsWebShell does (need to refactor).
// OK, time to make an editor on this document // OK, time to make an editor on this document
@ -853,9 +883,10 @@ nsEditingSession::EndDocumentLoad(nsIWebProgress *aWebProgress,
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
mEditorStatus = eEditorCreationInProgress; mEditorStatus = eEditorCreationInProgress;
mLoadBlankDocTimer->InitWithFuncCallback(nsEditingSession::TimerCallback, mLoadBlankDocTimer->InitWithFuncCallback(
(void*)docShell, nsEditingSession::TimerCallback,
10, nsITimer::TYPE_ONE_SHOT); (void*)docShell,
10, nsITimer::TYPE_ONE_SHOT);
} }
} }
} }
@ -977,7 +1008,10 @@ nsEditingSession::PrepareForEditing()
nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell); nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell);
if (!webProgress) return NS_ERROR_FAILURE; if (!webProgress) return NS_ERROR_FAILURE;
return webProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_ALL); return webProgress->AddProgressListener(this,
(nsIWebProgress::NOTIFY_STATE_NETWORK |
nsIWebProgress::NOTIFY_STATE_DOCUMENT |
nsIWebProgress::NOTIFY_LOCATION));
} }
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
@ -988,10 +1022,11 @@ nsEditingSession::PrepareForEditing()
get and return the controller ID, and set the refCon get and return the controller ID, and set the refCon
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
nsresult nsresult
nsEditingSession::SetupEditorCommandController(const char *aControllerClassName, nsEditingSession::SetupEditorCommandController(
nsIDOMWindow *aWindow, const char *aControllerClassName,
nsISupports *aRefCon, nsIDOMWindow *aWindow,
PRUint32 *aControllerId) nsISupports *aRefCon,
PRUint32 *aControllerId)
{ {
NS_ENSURE_ARG_POINTER(aControllerClassName); NS_ENSURE_ARG_POINTER(aControllerClassName);
NS_ENSURE_ARG_POINTER(aWindow); NS_ENSURE_ARG_POINTER(aWindow);
@ -999,7 +1034,8 @@ nsEditingSession::SetupEditorCommandController(const char *aControllerClassName,
NS_ENSURE_ARG_POINTER(aControllerId); NS_ENSURE_ARG_POINTER(aControllerId);
nsresult rv; nsresult rv;
nsCOMPtr<nsIDOMWindowInternal> domWindowInt = do_QueryInterface(aWindow, &rv); nsCOMPtr<nsIDOMWindowInternal> domWindowInt =
do_QueryInterface(aWindow, &rv);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIControllers> controllers; nsCOMPtr<nsIControllers> controllers;
@ -1043,7 +1079,8 @@ nsEditingSession::SetEditorOnControllers(nsIDOMWindow *aWindow,
nsresult rv; nsresult rv;
// set the editor on the controller // set the editor on the controller
nsCOMPtr<nsIDOMWindowInternal> domWindowInt = do_QueryInterface(aWindow, &rv); nsCOMPtr<nsIDOMWindowInternal> domWindowInt =
do_QueryInterface(aWindow, &rv);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIControllers> controllers; nsCOMPtr<nsIControllers> controllers;

Просмотреть файл

@ -239,10 +239,21 @@ interface nsIHTMLEditor : nsISupports
void insertElementAtSelection(in nsIDOMElement aElement, void insertElementAtSelection(in nsIDOMElement aElement,
in boolean aDeleteSelection); in boolean aDeleteSelection);
/** Set the documents title. /**
* Set the documents title.
*/ */
void setDocumentTitle(in AString aTitle); void setDocumentTitle(in AString aTitle);
/**
* Set the BaseURL for the document to the current URL
* but only if the page doesn't have a <base> tag
* This should be done after the document URL has changed,
* such as after saving a file
* This is used as base for relativizing link and image urls
*/
void updateBaseURL();
/* ------------ Selection manipulation -------------- */ /* ------------ Selection manipulation -------------- */
/* Should these be moved to nsISelection? */ /* Should these be moved to nsISelection? */

Просмотреть файл

@ -1238,6 +1238,44 @@ PRBool nsHTMLEditor::IsModifiable()
#pragma mark - #pragma mark -
#endif #endif
NS_IMETHODIMP
nsHTMLEditor::UpdateBaseURL()
{
nsCOMPtr<nsIDOMDocument> domDoc;
GetDocument(getter_AddRefs(domDoc));
if (!domDoc) return NS_ERROR_FAILURE;
// Look for an HTML <base> tag
nsCOMPtr<nsIDOMNodeList> nodeList;
nsresult rv = domDoc->GetElementsByTagName(NS_LITERAL_STRING("base"), getter_AddRefs(nodeList));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> baseNode;
if (nodeList)
{
PRUint32 count;
nodeList->GetLength(&count);
if (count >= 1)
{
rv = nodeList->Item(0, getter_AddRefs(baseNode));
NS_ENSURE_SUCCESS(rv, rv);
}
}
// If no base tag, then set baseURL to the document's URL
// This is very important, else relative URLs for links and images are wrong
if (!baseNode)
{
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (!doc) return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> uri;
rv = doc->GetDocumentURL(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
return doc->SetBaseURL(uri);
}
return NS_OK;
}
NS_IMETHODIMP nsHTMLEditor::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent) NS_IMETHODIMP nsHTMLEditor::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent)
{ {
PRUint32 keyCode, character; PRUint32 keyCode, character;

Просмотреть файл

@ -124,6 +124,8 @@ public:
NS_IMETHODIMP BeginningOfDocument(); NS_IMETHODIMP BeginningOfDocument();
/* ------------ nsIHTMLEditor methods -------------- */ /* ------------ nsIHTMLEditor methods -------------- */
NS_IMETHOD UpdateBaseURL();
NS_IMETHOD CopyLastEditableChildStyles(nsIDOMNode *aPreviousBlock, nsIDOMNode *aNewBlock, NS_IMETHOD CopyLastEditableChildStyles(nsIDOMNode *aPreviousBlock, nsIDOMNode *aNewBlock,
nsIDOMNode **aOutBrNode); nsIDOMNode **aOutBrNode);

Просмотреть файл

@ -389,6 +389,15 @@ var gEditorDocumentObserver =
dump("obs_documentWillBeDestroyed notification\n"); dump("obs_documentWillBeDestroyed notification\n");
break; break;
case "obs_documentLocationChanged":
// Ignore this when editor doesn't exist,
// which happens once when page load starts
if (editor)
try {
editor.updateBaseURL();
} catch(e) { dump (e); }
break;
case "cmd_bold": case "cmd_bold":
// Update all style items // Update all style items
window.updateCommands("style"); window.updateCommands("style");
@ -483,6 +492,7 @@ function EditorSharedStartup()
commandManager.addCommandObserver(gEditorDocumentObserver, "obs_documentCreated"); commandManager.addCommandObserver(gEditorDocumentObserver, "obs_documentCreated");
commandManager.addCommandObserver(gEditorDocumentObserver, "cmd_setDocumentModified"); commandManager.addCommandObserver(gEditorDocumentObserver, "cmd_setDocumentModified");
commandManager.addCommandObserver(gEditorDocumentObserver, "obs_documentWillBeDestroyed"); commandManager.addCommandObserver(gEditorDocumentObserver, "obs_documentWillBeDestroyed");
commandManager.addCommandObserver(gEditorDocumentObserver, "obs_documentLocationChanged");
// Until nsIControllerCommandGroup-based code is implemented, // Until nsIControllerCommandGroup-based code is implemented,
// we will observe just the bold command to trigger update of // we will observe just the bold command to trigger update of
@ -564,6 +574,7 @@ function EditorShutdown()
var commandManager = GetCurrentCommandManager(); var commandManager = GetCurrentCommandManager();
commandManager.removeCommandObserver(gEditorDocumentObserver, "obs_documentCreated"); commandManager.removeCommandObserver(gEditorDocumentObserver, "obs_documentCreated");
commandManager.removeCommandObserver(gEditorDocumentObserver, "obs_documentWillBeDestroyed"); commandManager.removeCommandObserver(gEditorDocumentObserver, "obs_documentWillBeDestroyed");
commandManager.removeCommandObserver(gEditorDocumentObserver, "obs_documentLocationChanged");
} catch (e) { dump (e); } } catch (e) { dump (e); }
} }
@ -3199,4 +3210,3 @@ function FillInHTMLTooltip(tooltip)
} }
return false; return false;
} }