diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index b8f69b4b0cf..cd6901de3bb 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -783,6 +783,10 @@ protected: PRBool aGetTextDimensions/* true=get dimensions false = return length up to aDimensionsResult->width size*/); nsresult GetContentAndOffsetsForSelection(nsIPresContext* aPresContext,nsIContent **aContent, PRInt32 *aOffset, PRInt32 *aLength); + // prefs used to configure the double-click word selection behavior + static PRPackedBool sWordSelectPrefInited; // have we read the prefs yet? + static PRPackedBool sWordSelectEatSpaceAfter; // should we include whitespace up to next word? + #ifdef IBMBIDI private: NS_IMETHOD_(nsrefcnt) AddRef(void); @@ -806,6 +810,11 @@ NS_IMETHODIMP nsTextFrame::GetAccessible(nsIAccessible** aAccessible) } #endif + +PRPackedBool nsTextFrame::sWordSelectPrefInited = PR_FALSE; +PRPackedBool nsTextFrame::sWordSelectEatSpaceAfter = PR_TRUE; + + //----------------------------------------------------------------------------- NS_IMETHODIMP nsTextFrame::QueryInterface(const nsIID& aIID, void** aInstancePtrResult) @@ -1251,6 +1260,16 @@ NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) nsTextFrame::nsTextFrame() { + // read in our global word selection prefs + if ( !sWordSelectPrefInited ) { + nsCOMPtr prefService ( do_GetService(NS_PREF_CONTRACTID) ); + if ( prefService ) { + PRBool temp = PR_FALSE; + prefService->GetBoolPref("layout.word_select.eat_space_to_next_word", &temp); + sWordSelectEatSpaceAfter = temp; + } + sWordSelectPrefInited = PR_TRUE; + } } nsTextFrame::~nsTextFrame() @@ -4055,37 +4074,44 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos) if ((aPos->mEatingWS && isWhitespace) || !aPos->mEatingWS){ aPos->mContentOffset = aPos->mStartOffset + contentLen; - //check for whitespace next. - keepSearching = PR_TRUE; - aPos->mEatingWS = PR_TRUE; - if (!isWhitespace){ - while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) - { - if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) - goto TryNextFrame; - if (isWhitespace) - aPos->mContentOffset += contentLen; - else - break; - } - keepSearching = PR_FALSE; - found = PR_TRUE; - } - else //we just need to jump the space, done here - { - while(tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) - { - if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) - goto TryNextFrame; + // check for whitespace next. On some platforms (mac), we want the selection to end + // at the end of the word (not the beginning of the next one), so don't slurp up any extra whitespace. + if ( sWordSelectEatSpaceAfter ) { + keepSearching = PR_TRUE; + aPos->mEatingWS = PR_TRUE; + if (!isWhitespace){ + while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) + { + if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) + goto TryNextFrame; + if (isWhitespace) + aPos->mContentOffset += contentLen; + else + break; + } + keepSearching = PR_FALSE; + found = PR_TRUE; + } + else //we just need to jump the space, done here + { + while(tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) + { + if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) + goto TryNextFrame; - if (isWhitespace) - aPos->mContentOffset += contentLen; - else - break; - } - keepSearching = PR_FALSE; - found = PR_TRUE; - } + if (isWhitespace) + aPos->mContentOffset += contentLen; + else + break; + } + keepSearching = PR_FALSE; + found = PR_TRUE; + } + } // if we should eat space to the next word + else { + keepSearching = PR_FALSE; + found = PR_TRUE; + } } else if (aPos->mEatingWS) { diff --git a/mozilla/layout/generic/nsTextTransformer.cpp b/mozilla/layout/generic/nsTextTransformer.cpp index 334b4d6af1b..f314affa5fc 100644 --- a/mozilla/layout/generic/nsTextTransformer.cpp +++ b/mozilla/layout/generic/nsTextTransformer.cpp @@ -49,6 +49,12 @@ #include "nsUnicharUtilCIID.h" #include "nsICaseConversion.h" #include "prenv.h" +#include "nsIPref.h" + + +PRPackedBool nsTextTransformer::sWordSelectPrefInited = PR_FALSE; +PRPackedBool nsTextTransformer::sWordSelectStopAtPunctuation = PR_FALSE; + nsAutoTextBuffer::nsAutoTextBuffer() : mBuffer(mAutoBuffer), @@ -102,6 +108,18 @@ nsresult nsTextTransformer::Initialize() { nsresult res = NS_OK; + + // read in our global word selection prefs + if ( !sWordSelectPrefInited ) { + nsCOMPtr prefService ( do_GetService(NS_PREF_CONTRACTID) ); + if ( prefService ) { + PRBool temp = PR_FALSE; + prefService->GetBoolPref("layout.word_select.stop_at_punctuation", &temp); + sWordSelectStopAtPunctuation = temp; + } + sWordSelectPrefInited = PR_TRUE; + } + return res; } static nsresult EnsureCaseConv() @@ -377,6 +395,10 @@ nsTextTransformer::ScanNormalAsciiText_F_ForWordBreak(PRInt32* aWordLen, else if (XP_IS_SPACE(ch)) { break; } + else if (sWordSelectStopAtPunctuation && !isalnum(ch)) { + // on some platforms, punctuation breaks words too. + break; + } else if (IS_DISCARDED(ch)) { // Strip discarded characters from the transformed output continue; diff --git a/mozilla/layout/generic/nsTextTransformer.h b/mozilla/layout/generic/nsTextTransformer.h index a57445ab136..a7a694952a7 100644 --- a/mozilla/layout/generic/nsTextTransformer.h +++ b/mozilla/layout/generic/nsTextTransformer.h @@ -275,6 +275,10 @@ protected: // Flag for controling mLeaveAsAscii, mHasMultibyte, mTransformedTextIsAscii PRUint8 mFlags; + // prefs used to configure the double-click word selection behavior + static PRPackedBool sWordSelectPrefInited; // have we read the prefs yet? + static PRPackedBool sWordSelectStopAtPunctuation; // should we stop at punctuation? + #ifdef DEBUG static void SelfTest(nsILineBreaker* aLineBreaker, nsIWordBreaker* aWordBreaker, diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index b8f69b4b0cf..cd6901de3bb 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -783,6 +783,10 @@ protected: PRBool aGetTextDimensions/* true=get dimensions false = return length up to aDimensionsResult->width size*/); nsresult GetContentAndOffsetsForSelection(nsIPresContext* aPresContext,nsIContent **aContent, PRInt32 *aOffset, PRInt32 *aLength); + // prefs used to configure the double-click word selection behavior + static PRPackedBool sWordSelectPrefInited; // have we read the prefs yet? + static PRPackedBool sWordSelectEatSpaceAfter; // should we include whitespace up to next word? + #ifdef IBMBIDI private: NS_IMETHOD_(nsrefcnt) AddRef(void); @@ -806,6 +810,11 @@ NS_IMETHODIMP nsTextFrame::GetAccessible(nsIAccessible** aAccessible) } #endif + +PRPackedBool nsTextFrame::sWordSelectPrefInited = PR_FALSE; +PRPackedBool nsTextFrame::sWordSelectEatSpaceAfter = PR_TRUE; + + //----------------------------------------------------------------------------- NS_IMETHODIMP nsTextFrame::QueryInterface(const nsIID& aIID, void** aInstancePtrResult) @@ -1251,6 +1260,16 @@ NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) nsTextFrame::nsTextFrame() { + // read in our global word selection prefs + if ( !sWordSelectPrefInited ) { + nsCOMPtr prefService ( do_GetService(NS_PREF_CONTRACTID) ); + if ( prefService ) { + PRBool temp = PR_FALSE; + prefService->GetBoolPref("layout.word_select.eat_space_to_next_word", &temp); + sWordSelectEatSpaceAfter = temp; + } + sWordSelectPrefInited = PR_TRUE; + } } nsTextFrame::~nsTextFrame() @@ -4055,37 +4074,44 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos) if ((aPos->mEatingWS && isWhitespace) || !aPos->mEatingWS){ aPos->mContentOffset = aPos->mStartOffset + contentLen; - //check for whitespace next. - keepSearching = PR_TRUE; - aPos->mEatingWS = PR_TRUE; - if (!isWhitespace){ - while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) - { - if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) - goto TryNextFrame; - if (isWhitespace) - aPos->mContentOffset += contentLen; - else - break; - } - keepSearching = PR_FALSE; - found = PR_TRUE; - } - else //we just need to jump the space, done here - { - while(tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) - { - if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) - goto TryNextFrame; + // check for whitespace next. On some platforms (mac), we want the selection to end + // at the end of the word (not the beginning of the next one), so don't slurp up any extra whitespace. + if ( sWordSelectEatSpaceAfter ) { + keepSearching = PR_TRUE; + aPos->mEatingWS = PR_TRUE; + if (!isWhitespace){ + while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) + { + if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) + goto TryNextFrame; + if (isWhitespace) + aPos->mContentOffset += contentLen; + else + break; + } + keepSearching = PR_FALSE; + found = PR_TRUE; + } + else //we just need to jump the space, done here + { + while(tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) + { + if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) + goto TryNextFrame; - if (isWhitespace) - aPos->mContentOffset += contentLen; - else - break; - } - keepSearching = PR_FALSE; - found = PR_TRUE; - } + if (isWhitespace) + aPos->mContentOffset += contentLen; + else + break; + } + keepSearching = PR_FALSE; + found = PR_TRUE; + } + } // if we should eat space to the next word + else { + keepSearching = PR_FALSE; + found = PR_TRUE; + } } else if (aPos->mEatingWS) { diff --git a/mozilla/layout/html/base/src/nsTextTransformer.cpp b/mozilla/layout/html/base/src/nsTextTransformer.cpp index 334b4d6af1b..f314affa5fc 100644 --- a/mozilla/layout/html/base/src/nsTextTransformer.cpp +++ b/mozilla/layout/html/base/src/nsTextTransformer.cpp @@ -49,6 +49,12 @@ #include "nsUnicharUtilCIID.h" #include "nsICaseConversion.h" #include "prenv.h" +#include "nsIPref.h" + + +PRPackedBool nsTextTransformer::sWordSelectPrefInited = PR_FALSE; +PRPackedBool nsTextTransformer::sWordSelectStopAtPunctuation = PR_FALSE; + nsAutoTextBuffer::nsAutoTextBuffer() : mBuffer(mAutoBuffer), @@ -102,6 +108,18 @@ nsresult nsTextTransformer::Initialize() { nsresult res = NS_OK; + + // read in our global word selection prefs + if ( !sWordSelectPrefInited ) { + nsCOMPtr prefService ( do_GetService(NS_PREF_CONTRACTID) ); + if ( prefService ) { + PRBool temp = PR_FALSE; + prefService->GetBoolPref("layout.word_select.stop_at_punctuation", &temp); + sWordSelectStopAtPunctuation = temp; + } + sWordSelectPrefInited = PR_TRUE; + } + return res; } static nsresult EnsureCaseConv() @@ -377,6 +395,10 @@ nsTextTransformer::ScanNormalAsciiText_F_ForWordBreak(PRInt32* aWordLen, else if (XP_IS_SPACE(ch)) { break; } + else if (sWordSelectStopAtPunctuation && !isalnum(ch)) { + // on some platforms, punctuation breaks words too. + break; + } else if (IS_DISCARDED(ch)) { // Strip discarded characters from the transformed output continue; diff --git a/mozilla/layout/html/base/src/nsTextTransformer.h b/mozilla/layout/html/base/src/nsTextTransformer.h index a57445ab136..a7a694952a7 100644 --- a/mozilla/layout/html/base/src/nsTextTransformer.h +++ b/mozilla/layout/html/base/src/nsTextTransformer.h @@ -275,6 +275,10 @@ protected: // Flag for controling mLeaveAsAscii, mHasMultibyte, mTransformedTextIsAscii PRUint8 mFlags; + // prefs used to configure the double-click word selection behavior + static PRPackedBool sWordSelectPrefInited; // have we read the prefs yet? + static PRPackedBool sWordSelectStopAtPunctuation; // should we stop at punctuation? + #ifdef DEBUG static void SelfTest(nsILineBreaker* aLineBreaker, nsIWordBreaker* aWordBreaker, diff --git a/mozilla/modules/libpref/src/init/all.js b/mozilla/modules/libpref/src/init/all.js index cdb5b8f19c0..9b41ff8150e 100644 --- a/mozilla/modules/libpref/src/init/all.js +++ b/mozilla/modules/libpref/src/init/all.js @@ -580,3 +580,7 @@ pref("bidi.characterset", 1); pref("browser.throbber.url","chrome://navigator-region/locale/region.properties"); + +// used for double-click word selection behavior. Mac will override. +pref("layout.word_select.eat_space_to_next_word", true); +pref("layout.word_select.stop_at_punctuation", false); diff --git a/mozilla/modules/libpref/src/mac/macprefs.js b/mozilla/modules/libpref/src/mac/macprefs.js index 45817b35012..0d41b0f51a6 100644 --- a/mozilla/modules/libpref/src/mac/macprefs.js +++ b/mozilla/modules/libpref/src/mac/macprefs.js @@ -44,6 +44,13 @@ pref("ui.key.saveLink.shift", false); // true = shift, false = meta pref("editor.use_html_editor", false); pref("editor.use_image_editor", false); +// override double-click word selection behavior. +pref("layout.word_select.eat_space_to_next_word", false); +pref("layout.word_select.stop_at_punctuation", true); + +// should a GURL event open a new window or re-use (4.x compat) +pref("browser.always_reuse_window", false); + pref("mail.notification.sound", ""); pref("mail.close_message_window.on_delete", true); pref("mail.close_message_window.on_file", true);