nsresult nsTextEditRules::TruncateInsertionIfNeeded(Selection* aSelection, const nsAString *aInString, nsAString *aOutString, int32_t aMaxLength, bool *aTruncated) { if (!aSelection || !aInString || !aOutString) {return NS_ERROR_NULL_POINTER;} nsresult res = NS_OK; *aOutString = *aInString; if (aTruncated) { *aTruncated = false; } NS_ENSURE_STATE(mEditor); if ((-1 != aMaxLength) && IsPlaintextEditor() && !mEditor->IsIMEComposing() ) { // Get the current text length. // Get the length of inString. // Get the length of the selection. // If selection is collapsed, it is length 0. // Subtract the length of the selection from the len(doc) // since we'll delete the selection on insert. // This is resultingDocLength. // Get old length of IME composing string // which will be replaced by new one. // If (resultingDocLength) is at or over max, cancel the insert // If (resultingDocLength) + (length of input) > max, // set aOutString to subset of inString so length = max int32_t docLength; res = mEditor->GetTextLength(&docLength); if (NS_FAILED(res)) { return res; } int32_t start, end; nsContentUtils::GetSelectionInTextControl(aSelection, mEditor->GetRoot(), start, end); TextComposition* composition = mEditor->GetComposition(); int32_t oldCompStrLength = composition ? composition->String().Length() : 0; const int32_t selectionLength = end - start; const int32_t resultingDocLength = docLength - selectionLength - oldCompStrLength; if (resultingDocLength >= aMaxLength) { aOutString->Truncate(); if (aTruncated) { *aTruncated = true; } } else { int32_t inCount = aOutString->Length(); if (inCount + resultingDocLength > aMaxLength) { aOutString->Truncate(aMaxLength - resultingDocLength); if (aTruncated) { *aTruncated = true; } } } } return res; }
nsresult TextEditRules::TruncateInsertionIfNeeded(Selection* aSelection, const nsAString* aInString, nsAString* aOutString, int32_t aMaxLength, bool* aTruncated) { if (!aSelection || !aInString || !aOutString) { return NS_ERROR_NULL_POINTER; } if (!aOutString->Assign(*aInString, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } if (aTruncated) { *aTruncated = false; } NS_ENSURE_STATE(mTextEditor); if (-1 != aMaxLength && IsPlaintextEditor() && !mTextEditor->IsIMEComposing()) { // Get the current text length. // Get the length of inString. // Get the length of the selection. // If selection is collapsed, it is length 0. // Subtract the length of the selection from the len(doc) // since we'll delete the selection on insert. // This is resultingDocLength. // Get old length of IME composing string // which will be replaced by new one. // If (resultingDocLength) is at or over max, cancel the insert // If (resultingDocLength) + (length of input) > max, // set aOutString to subset of inString so length = max int32_t docLength; nsresult rv = mTextEditor->GetTextLength(&docLength); if (NS_FAILED(rv)) { return rv; } uint32_t start, end; nsContentUtils::GetSelectionInTextControl(aSelection, mTextEditor->GetRoot(), start, end); TextComposition* composition = mTextEditor->GetComposition(); uint32_t oldCompStrLength = composition ? composition->String().Length() : 0; const uint32_t selectionLength = end - start; const int32_t resultingDocLength = docLength - selectionLength - oldCompStrLength; if (resultingDocLength >= aMaxLength) { // This call is guaranteed to reduce the capacity of the string, so it // cannot cause an OOM. aOutString->Truncate(); if (aTruncated) { *aTruncated = true; } } else { int32_t oldLength = aOutString->Length(); if (oldLength + resultingDocLength > aMaxLength) { int32_t newLength = aMaxLength - resultingDocLength; MOZ_ASSERT(newLength > 0); char16_t newLastChar = aOutString->CharAt(newLength - 1); char16_t removingFirstChar = aOutString->CharAt(newLength); // Don't separate the string between a surrogate pair. if (NS_IS_HIGH_SURROGATE(newLastChar) && NS_IS_LOW_SURROGATE(removingFirstChar)) { newLength--; } // XXX What should we do if we're removing IVS and its preceding // character won't be removed? // This call is guaranteed to reduce the capacity of the string, so it // cannot cause an OOM. aOutString->Truncate(newLength); if (aTruncated) { *aTruncated = true; } } } } return NS_OK; }