Bug 974318 part.1 Add WidgetTextEvent::mRanges which is an array class of TextRange r=smaug

This commit is contained in:
Masayuki Nakano
2014-03-04 22:48:26 +09:00
parent bee5909fa1
commit 4bb76a0e5f
8 changed files with 138 additions and 45 deletions

View File

@@ -23,6 +23,7 @@ CompositionStringSynthesizer::CompositionStringSynthesizer(
nsPIDOMWindow* aWindow)
{
mWindow = do_GetWeakReference(aWindow);
mClauses = new TextRangeArray();
ClearInternal();
}
@@ -34,7 +35,7 @@ void
CompositionStringSynthesizer::ClearInternal()
{
mString.Truncate();
mClauses.Clear();
mClauses->Clear();
mCaret.mRangeType = 0;
}
@@ -84,10 +85,10 @@ CompositionStringSynthesizer::AppendClause(uint32_t aLength,
case ATTR_SELECTEDCONVERTEDTEXT: {
TextRange textRange;
textRange.mStartOffset =
mClauses.IsEmpty() ? 0 : mClauses[mClauses.Length() - 1].mEndOffset;
mClauses->IsEmpty() ? 0 : mClauses->LastElement().mEndOffset;
textRange.mEndOffset = textRange.mStartOffset + aLength;
textRange.mRangeType = aAttribute;
mClauses.AppendElement(textRange);
mClauses->AppendElement(textRange);
return NS_OK;
}
default:
@@ -118,8 +119,8 @@ CompositionStringSynthesizer::DispatchEvent(bool* aDefaultPrevented)
return NS_ERROR_DOM_SECURITY_ERR;
}
if (!mClauses.IsEmpty() &&
mClauses[mClauses.Length()-1].mEndOffset != mString.Length()) {
if (!mClauses->IsEmpty() &&
mClauses->LastElement().mEndOffset != mString.Length()) {
NS_WARNING("Sum of length of the all clauses must be same as the string "
"length");
ClearInternal();
@@ -131,14 +132,14 @@ CompositionStringSynthesizer::DispatchEvent(bool* aDefaultPrevented)
ClearInternal();
return NS_ERROR_ILLEGAL_VALUE;
}
mClauses.AppendElement(mCaret);
mClauses->AppendElement(mCaret);
}
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
textEvent.time = PR_IntervalNow();
textEvent.theText = mString;
textEvent.rangeCount = mClauses.Length();
textEvent.rangeArray = mClauses.Elements();
textEvent.rangeCount = mClauses->Length();
textEvent.rangeArray = mClauses->Elements();
// XXX How should we set false for this on b2g?
textEvent.mFlags.mIsSynthesizedForTests = true;

View File

@@ -8,7 +8,6 @@
#include "nsICompositionStringSynthesizer.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsWeakReference.h"
#include "mozilla/Attributes.h"
#include "mozilla/TextRange.h"
@@ -32,7 +31,7 @@ public:
private:
nsWeakPtr mWindow; // refers an instance of nsPIDOMWindow
nsString mString;
nsAutoTArray<TextRange, 10> mClauses;
nsRefPtr<TextRangeArray> mClauses;
TextRange mCaret;
nsIWidget* GetWidget();

View File

@@ -113,17 +113,8 @@ TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent)
} else if (aEvent->eventStructType != NS_TEXT_EVENT) {
return;
} else {
WidgetTextEvent* textEvent = aEvent->AsTextEvent();
mCompositionTargetOffset = mCompositionStartOffset;
for (uint32_t i = 0; i < textEvent->rangeCount; i++) {
TextRange& range = textEvent->rangeArray[i];
if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
mCompositionTargetOffset += range.mStartOffset;
break;
}
}
mCompositionTargetOffset =
mCompositionStartOffset + aEvent->AsTextEvent()->TargetClauseOffset();
}
NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE);

View File

@@ -39,13 +39,13 @@ nsDOMTextEvent::nsDOMTextEvent(mozilla::dom::EventTarget* aOwner,
// IME transaction will hold a ref, the widget representation
// isn't persistent
//
mTextRange = new nsPrivateTextRangeList(te->rangeCount);
mTextRange = new nsPrivateTextRangeList(te->RangeCount());
if (mTextRange) {
uint16_t i;
for(i = 0; i < te->rangeCount; i++) {
nsRefPtr<nsPrivateTextRange> tempPrivateTextRange = new
nsPrivateTextRange(te->rangeArray[i]);
nsPrivateTextRange(te->mRanges->ElementAt(i));
if (tempPrivateTextRange) {
mTextRange->AppendTextRange(tempPrivateTextRange);

View File

@@ -69,7 +69,7 @@ struct AlternativeCharCode;
struct TextRangeStyle;
struct TextRange;
typedef TextRange* TextRangeArray;
class TextRangeArray;
} // namespace mozilla

View File

@@ -221,12 +221,14 @@ public:
// Note that the range array may not specify a caret position; in that
// case there will be no range of type NS_TEXTRANGE_CARETPOSITION in the
// array.
TextRangeArray rangeArray;
TextRange* rangeArray;
// Indicates whether the event signifies printable text.
// XXX This is not a standard, and most platforms don't set this properly.
// So, perhaps, we can get rid of this.
bool isChar;
nsRefPtr<TextRangeArray> mRanges;
void AssignTextEventData(const WidgetTextEvent& aEvent, bool aCopyTargets)
{
AssignGUIEventData(aEvent, aCopyTargets);
@@ -237,14 +239,35 @@ public:
// for internal use only (not available from JS).
}
// XXX This copies all ranges from legacy member to new member.
// This will be removed later.
void EnsureRanges()
{
if (mRanges || !rangeCount) {
return;
}
mRanges = new TextRangeArray();
for (uint32_t i = 0; i < rangeCount; i++) {
mRanges->AppendElement(rangeArray[i]);
}
}
bool IsComposing() const
{
for (uint32_t i = 0; i < rangeCount; i++) {
if (rangeArray[i].IsClause()) {
return true;
}
}
return false;
const_cast<WidgetTextEvent*>(this)->EnsureRanges();
return mRanges && mRanges->IsComposing();
}
uint32_t TargetClauseOffset() const
{
const_cast<WidgetTextEvent*>(this)->EnsureRanges();
return mRanges ? mRanges->TargetClauseOffset() : 0;
}
uint32_t RangeCount() const
{
const_cast<WidgetTextEvent*>(this)->EnsureRanges();
return mRanges ? mRanges->Length() : 0;
}
};

View File

@@ -8,8 +8,10 @@
#include <stdint.h>
#include "nsAutoPtr.h"
#include "nsColor.h"
#include "nsStyleConsts.h"
#include "nsTArray.h"
namespace mozilla {
@@ -159,11 +161,36 @@ struct TextRange
/******************************************************************************
* mozilla::TextRangeArray
*
* XXX This should be replaced with nsTArray<TextRange>.
******************************************************************************/
class TextRangeArray MOZ_FINAL : public nsAutoTArray<TextRange, 10>
{
NS_INLINE_DECL_REFCOUNTING(TextRangeArray)
typedef TextRange* TextRangeArray;
public:
bool IsComposing() const
{
for (uint32_t i = 0; i < Length(); ++i) {
if (ElementAt(i).IsClause()) {
return true;
}
}
return false;
}
// Returns target clase offset. If there are selected clauses, this returns
// the first selected clause offset. Otherwise, 0.
uint32_t TargetClauseOffset() const
{
for (uint32_t i = 0; i < Length(); ++i) {
const TextRange& range = ElementAt(i);
if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
return range.mStartOffset;
}
}
return 0;
}
};
} // namespace mozilla

View File

@@ -378,6 +378,37 @@ struct ParamTraits<mozilla::TextRange>
}
};
template<>
struct ParamTraits<mozilla::TextRangeArray>
{
typedef mozilla::TextRangeArray paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.Length());
for (uint32_t index = 0; index < aParam.Length(); index++) {
WriteParam(aMsg, aParam[index]);
}
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
uint32_t length;
if (!ReadParam(aMsg, aIter, &length)) {
return false;
}
for (uint32_t index = 0; index < length; index++) {
mozilla::TextRange textRange;
if (!ReadParam(aMsg, aIter, &textRange)) {
aResult->Clear();
return false;
}
aResult->AppendElement(textRange);
}
return true;
}
};
template<>
struct ParamTraits<mozilla::WidgetTextEvent>
{
@@ -390,34 +421,55 @@ struct ParamTraits<mozilla::WidgetTextEvent>
WriteParam(aMsg, aParam.theText);
WriteParam(aMsg, aParam.isChar);
WriteParam(aMsg, aParam.rangeCount);
bool hasRanges = !!aParam.mRanges;
WriteParam(aMsg, hasRanges);
for (uint32_t index = 0; index < aParam.rangeCount; index++)
WriteParam(aMsg, aParam.rangeArray[index]);
if (hasRanges) {
WriteParam(aMsg, *aParam.mRanges.get());
}
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
bool hasRanges;
if (!ReadParam(aMsg, aIter,
static_cast<mozilla::WidgetGUIEvent*>(aResult)) ||
!ReadParam(aMsg, aIter, &aResult->mSeqno) ||
!ReadParam(aMsg, aIter, &aResult->theText) ||
!ReadParam(aMsg, aIter, &aResult->isChar) ||
!ReadParam(aMsg, aIter, &aResult->rangeCount))
!ReadParam(aMsg, aIter, &aResult->rangeCount) ||
!ReadParam(aMsg, aIter, &hasRanges)) {
return false;
}
if (!aResult->rangeCount) {
aResult->rangeArray = nullptr;
return true;
}
aResult->rangeArray = new mozilla::TextRange[aResult->rangeCount];
if (!aResult->rangeArray)
return false;
for (uint32_t index = 0; index < aResult->rangeCount; index++)
if (!ReadParam(aMsg, aIter, &aResult->rangeArray[index])) {
Free(*aResult);
} else {
aResult->rangeArray = new mozilla::TextRange[aResult->rangeCount];
if (!aResult->rangeArray) {
return false;
}
for (uint32_t index = 0; index < aResult->rangeCount; index++) {
if (!ReadParam(aMsg, aIter, &aResult->rangeArray[index])) {
Free(*aResult);
return false;
}
}
}
if (!hasRanges) {
aResult->mRanges = nullptr;
} else {
aResult->mRanges = new mozilla::TextRangeArray();
if (!aResult->mRanges) {
return false;
}
if (!ReadParam(aMsg, aIter, aResult->mRanges.get())) {
return false;
}
}
return true;
}