Fix for 29737 -- selecting is slow in large files in composer. r=mjudge, akkana, a=jar.

This commit is contained in:
sfraser%netscape.com 2000-03-03 23:35:11 +00:00
parent 127c8d3906
commit d86d156a86
6 changed files with 165 additions and 27 deletions

View File

@ -32,7 +32,7 @@ IS_COMPONENT = 1
CPPSRCS = \
nsEditor.cpp \
nsEditorService.cpp \
nsEditorService.cpp \
nsEditorController.cpp \
nsEditorCommands.cpp \
nsEditorUtils.cpp \
@ -73,6 +73,7 @@ CPPSRCS = \
EXTRA_DSO_LDOPTS = \
$(MOZ_NECKO_UTIL_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(MOZ_TIMER_LIBS) \
-lmozjs \
$(NULL)

View File

@ -136,6 +136,7 @@ LLIBS= \
$(DIST)\lib\js3250.lib \
$(DIST)\lib\gkparser.lib \
$(DIST)\lib\raptorwidget_s.lib \
$(DIST)\lib\timer_s.lib \
$(LIBNSPR)
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib

View File

@ -38,6 +38,7 @@
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindow.h"
#include "nsITimer.h"
#include "nsIEditor.h"
#include "nsIHTMLEditor.h"
@ -63,11 +64,14 @@ nsInterfaceState::nsInterfaceState()
nsInterfaceState::~nsInterfaceState()
{
// cancel any outstanding udpate timer
if (mUpdateTimer)
mUpdateTimer->Cancel();
}
NS_IMPL_ADDREF(nsInterfaceState);
NS_IMPL_RELEASE(nsInterfaceState);
NS_IMPL_QUERY_INTERFACE3(nsInterfaceState, nsIDOMSelectionListener, nsIDocumentStateListener, nsITransactionListener);
NS_IMPL_QUERY_INTERFACE4(nsInterfaceState, nsIDOMSelectionListener, nsIDocumentStateListener, nsITransactionListener, nsITimerCallback);
NS_IMETHODIMP
nsInterfaceState::Init(nsIHTMLEditor* aEditor, nsIDOMXULDocument *aChromeDoc)
@ -113,17 +117,13 @@ nsInterfaceState::NotifyDocumentStateChanged(PRBool aNowDirty)
NS_IMETHODIMP
nsInterfaceState::NotifySelectionChanged()
{
// if the selection state has changed, update stuff
PRBool isCollapsed = SelectionIsCollapsed();
if (isCollapsed != mSelectionCollapsed)
{
CallUpdateCommands(nsAutoString("select"));
mSelectionCollapsed = isCollapsed;
}
return ForceUpdate();
return PrimeUpdateTimer();
}
#ifdef XP_MAC
#pragma mark -
#endif
NS_IMETHODIMP nsInterfaceState::WillDo(nsITransactionManager *aManager,
nsITransaction *aTransaction, PRBool *aInterrupt)
@ -144,7 +144,7 @@ NS_IMETHODIMP nsInterfaceState::DidDo(nsITransactionManager *aManager,
CallUpdateCommands(nsAutoString("undo"));
mFirstDoOfFirstUndo = PR_FALSE;
}
return NS_OK;
}
@ -217,6 +217,44 @@ NS_IMETHODIMP nsInterfaceState::DidMerge(nsITransactionManager *aManager,
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -
#endif
nsresult nsInterfaceState::PrimeUpdateTimer()
{
nsresult rv = NS_OK;
if (mUpdateTimer)
{
// i'd love to be able to just call SetDelay on the existing timer, but
// i think i have to tear it down and make a new one.
mUpdateTimer->Cancel();
mUpdateTimer = NULL; // free it
}
rv = NS_NewTimer(getter_AddRefs(mUpdateTimer));
if (NS_FAILED(rv)) return rv;
const PRUint32 kUpdateTimerDelay = 150;
return mUpdateTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this), kUpdateTimerDelay);
}
void nsInterfaceState::TimerCallback()
{
// if the selection state has changed, update stuff
PRBool isCollapsed = SelectionIsCollapsed();
if (isCollapsed != mSelectionCollapsed)
{
CallUpdateCommands(nsAutoString("select"));
mSelectionCollapsed = isCollapsed;
}
(void)ForceUpdate();
}
nsresult nsInterfaceState::CallUpdateCommands(const nsString& aCommand)
{
@ -252,13 +290,16 @@ nsInterfaceState::ForceUpdate()
// update bold
rv = UpdateTextState("b", "Editor:Bold", "bold", mBoldState);
// update italic
rv = UpdateTextState("i", "Editor:Italic", "italic", mItalicState);
// update underline
rv = UpdateTextState("u", "Editor:Underline", "underline", mUnderlineState);
// update the paragraph format popup
rv = UpdateParagraphState("Editor:Paragraph:Format", "format", mParagraphFormat);
// udpate the font face
rv = UpdateFontFace("Editor:Font:Face", "font", mFontString);
@ -473,6 +514,24 @@ nsInterfaceState::UnsetNodeAttribute(const char* nodeID, const char* attributeNa
}
#ifdef XP_MAC
#pragma mark -
#endif
void
nsInterfaceState::Notify(nsITimer *timer)
{
NS_ASSERTION(timer == mUpdateTimer.get(), "Hey, this ain't my timer!");
mUpdateTimer = NULL; // release my hold
TimerCallback();
}
#ifdef XP_MAC
#pragma mark -
#endif
nsresult NS_NewInterfaceState(nsIHTMLEditor* aEditor, nsIDOMXULDocument* aChromeDoc, nsIDOMSelectionListener** aInstancePtrResult)
{
nsInterfaceState* newThang = new nsInterfaceState;

View File

@ -29,6 +29,7 @@
#include "nsIDocumentStateListener.h"
#include "nsITransactionListener.h"
#include "nsIWebShell.h"
#include "nsITimerCallback.h"
class nsIHTMLEditor;
class nsIDOMXULDocument;
@ -38,7 +39,8 @@ class nsIDOMXULDocument;
class nsInterfaceState : public nsIDOMSelectionListener,
public nsIDocumentStateListener,
public nsITransactionListener
public nsITransactionListener,
public nsITimerCallback
{
public:
@ -55,10 +57,12 @@ public:
// nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
NS_DECL_NSIDOCUMENTSTATELISTENER
// nsITimerCallback interfaces
NS_IMETHOD_(void) Notify(nsITimer *timer);
/** nsITransactionListener interfaces
*/
@ -100,6 +104,9 @@ protected:
nsresult CallUpdateCommands(const nsString& aCommand);
nsresult PrimeUpdateTimer();
void TimerCallback();
// this class should not hold references to the editor or editorShell. Doing
// so would result in cirular reference chains.
@ -108,6 +115,8 @@ protected:
nsIDOMWindow* mDOMWindow; // nsIDOMWindow used for calling UpdateCommands
nsCOMPtr<nsITimer> mUpdateTimer;
// current state
PRInt8 mBoldState;
PRInt8 mItalicState;

View File

@ -38,6 +38,7 @@
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindow.h"
#include "nsITimer.h"
#include "nsIEditor.h"
#include "nsIHTMLEditor.h"
@ -63,11 +64,14 @@ nsInterfaceState::nsInterfaceState()
nsInterfaceState::~nsInterfaceState()
{
// cancel any outstanding udpate timer
if (mUpdateTimer)
mUpdateTimer->Cancel();
}
NS_IMPL_ADDREF(nsInterfaceState);
NS_IMPL_RELEASE(nsInterfaceState);
NS_IMPL_QUERY_INTERFACE3(nsInterfaceState, nsIDOMSelectionListener, nsIDocumentStateListener, nsITransactionListener);
NS_IMPL_QUERY_INTERFACE4(nsInterfaceState, nsIDOMSelectionListener, nsIDocumentStateListener, nsITransactionListener, nsITimerCallback);
NS_IMETHODIMP
nsInterfaceState::Init(nsIHTMLEditor* aEditor, nsIDOMXULDocument *aChromeDoc)
@ -113,17 +117,13 @@ nsInterfaceState::NotifyDocumentStateChanged(PRBool aNowDirty)
NS_IMETHODIMP
nsInterfaceState::NotifySelectionChanged()
{
// if the selection state has changed, update stuff
PRBool isCollapsed = SelectionIsCollapsed();
if (isCollapsed != mSelectionCollapsed)
{
CallUpdateCommands(nsAutoString("select"));
mSelectionCollapsed = isCollapsed;
}
return ForceUpdate();
return PrimeUpdateTimer();
}
#ifdef XP_MAC
#pragma mark -
#endif
NS_IMETHODIMP nsInterfaceState::WillDo(nsITransactionManager *aManager,
nsITransaction *aTransaction, PRBool *aInterrupt)
@ -144,7 +144,7 @@ NS_IMETHODIMP nsInterfaceState::DidDo(nsITransactionManager *aManager,
CallUpdateCommands(nsAutoString("undo"));
mFirstDoOfFirstUndo = PR_FALSE;
}
return NS_OK;
}
@ -217,6 +217,44 @@ NS_IMETHODIMP nsInterfaceState::DidMerge(nsITransactionManager *aManager,
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -
#endif
nsresult nsInterfaceState::PrimeUpdateTimer()
{
nsresult rv = NS_OK;
if (mUpdateTimer)
{
// i'd love to be able to just call SetDelay on the existing timer, but
// i think i have to tear it down and make a new one.
mUpdateTimer->Cancel();
mUpdateTimer = NULL; // free it
}
rv = NS_NewTimer(getter_AddRefs(mUpdateTimer));
if (NS_FAILED(rv)) return rv;
const PRUint32 kUpdateTimerDelay = 150;
return mUpdateTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this), kUpdateTimerDelay);
}
void nsInterfaceState::TimerCallback()
{
// if the selection state has changed, update stuff
PRBool isCollapsed = SelectionIsCollapsed();
if (isCollapsed != mSelectionCollapsed)
{
CallUpdateCommands(nsAutoString("select"));
mSelectionCollapsed = isCollapsed;
}
(void)ForceUpdate();
}
nsresult nsInterfaceState::CallUpdateCommands(const nsString& aCommand)
{
@ -252,13 +290,16 @@ nsInterfaceState::ForceUpdate()
// update bold
rv = UpdateTextState("b", "Editor:Bold", "bold", mBoldState);
// update italic
rv = UpdateTextState("i", "Editor:Italic", "italic", mItalicState);
// update underline
rv = UpdateTextState("u", "Editor:Underline", "underline", mUnderlineState);
// update the paragraph format popup
rv = UpdateParagraphState("Editor:Paragraph:Format", "format", mParagraphFormat);
// udpate the font face
rv = UpdateFontFace("Editor:Font:Face", "font", mFontString);
@ -473,6 +514,24 @@ nsInterfaceState::UnsetNodeAttribute(const char* nodeID, const char* attributeNa
}
#ifdef XP_MAC
#pragma mark -
#endif
void
nsInterfaceState::Notify(nsITimer *timer)
{
NS_ASSERTION(timer == mUpdateTimer.get(), "Hey, this ain't my timer!");
mUpdateTimer = NULL; // release my hold
TimerCallback();
}
#ifdef XP_MAC
#pragma mark -
#endif
nsresult NS_NewInterfaceState(nsIHTMLEditor* aEditor, nsIDOMXULDocument* aChromeDoc, nsIDOMSelectionListener** aInstancePtrResult)
{
nsInterfaceState* newThang = new nsInterfaceState;

View File

@ -29,6 +29,7 @@
#include "nsIDocumentStateListener.h"
#include "nsITransactionListener.h"
#include "nsIWebShell.h"
#include "nsITimerCallback.h"
class nsIHTMLEditor;
class nsIDOMXULDocument;
@ -38,7 +39,8 @@ class nsIDOMXULDocument;
class nsInterfaceState : public nsIDOMSelectionListener,
public nsIDocumentStateListener,
public nsITransactionListener
public nsITransactionListener,
public nsITimerCallback
{
public:
@ -55,10 +57,12 @@ public:
// nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
NS_DECL_NSIDOCUMENTSTATELISTENER
// nsITimerCallback interfaces
NS_IMETHOD_(void) Notify(nsITimer *timer);
/** nsITransactionListener interfaces
*/
@ -100,6 +104,9 @@ protected:
nsresult CallUpdateCommands(const nsString& aCommand);
nsresult PrimeUpdateTimer();
void TimerCallback();
// this class should not hold references to the editor or editorShell. Doing
// so would result in cirular reference chains.
@ -108,6 +115,8 @@ protected:
nsIDOMWindow* mDOMWindow; // nsIDOMWindow used for calling UpdateCommands
nsCOMPtr<nsITimer> mUpdateTimer;
// current state
PRInt8 mBoldState;
PRInt8 mItalicState;