nsresult nsSMILParserUtils::ParseValues(const nsAString& aSpec, const nsISMILAnimationElement* aSrcElement, const nsISMILAttr& aAttribute, nsTArray<nsSMILValue>& aValuesArray) { nsresult rv = NS_ERROR_FAILURE; nsAString::const_iterator start; nsAString::const_iterator end; nsAString::const_iterator substr_end; nsAString::const_iterator next; aSpec.BeginReading(start); aSpec.EndReading(end); while (start != end) { rv = NS_ERROR_FAILURE; SkipWsp(start, end); if (start == end || *start == ';') break; substr_end = start; while (substr_end != end && *substr_end != ';') { ++substr_end; } next = substr_end; if (*substr_end == ';') { ++next; if (next == end) break; } do --substr_end; while (start != substr_end && NS_IS_SPACE(*substr_end)); ++substr_end; nsSMILValue newValue; rv = aAttribute.ValueFromString(Substring(start, substr_end), aSrcElement, newValue); if (NS_FAILED(rv)) break; if (!aValuesArray.AppendElement(newValue)) { rv = NS_ERROR_OUT_OF_MEMORY; break; } rv = NS_OK; start = next; } return rv; }
// the following block is to append the accesskey to mTitle if there is an accesskey // but the mTitle doesn't have the character void nsTextBoxFrame::UpdateAccessTitle() { /* * Note that if you change appending access key label spec, * you need to maintain same logic in following methods. See bug 324159. * toolkit/content/commonDialog.js (setLabelForNode) * toolkit/content/widgets/text.xml (formatAccessKey) */ PRInt32 menuAccessKey; nsMenuBarListener::GetMenuAccessKey(&menuAccessKey); if (!menuAccessKey || mAccessKey.IsEmpty()) return; if (!AlwaysAppendAccessKey() && FindInReadable(mAccessKey, mTitle, nsCaseInsensitiveStringComparator())) return; nsAutoString accessKeyLabel; accessKeyLabel += '('; accessKeyLabel += mAccessKey; ToUpperCase(accessKeyLabel); accessKeyLabel += ')'; if (mTitle.IsEmpty()) { mTitle = accessKeyLabel; return; } const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis(); PRUint32 offset = mTitle.Length(); if (StringEndsWith(mTitle, kEllipsis)) { offset -= kEllipsis.Length(); } else if (StringEndsWith(mTitle, OLD_ELLIPSIS)) { // Try to check with our old ellipsis (for old addons) offset -= OLD_ELLIPSIS.Length(); } else { // Try to check with // our default ellipsis (for non-localized addons) or ':' const PRUnichar kLastChar = mTitle.Last(); if (kLastChar == PRUnichar(0x2026) || kLastChar == PRUnichar(':')) offset--; } if (InsertSeparatorBeforeAccessKey() && offset > 0 && !NS_IS_SPACE(mTitle[offset - 1])) { mTitle.Insert(' ', offset); offset++; } mTitle.Insert(accessKeyLabel, offset); }
// static void TextEditRules::HandleNewLines(nsString& aString, int32_t aNewlineHandling) { if (aNewlineHandling < 0) { int32_t caretStyle; TextEditor::GetDefaultEditorPrefs(aNewlineHandling, caretStyle); } switch(aNewlineHandling) { case nsIPlaintextEditor::eNewlinesReplaceWithSpaces: // Strip trailing newlines first so we don't wind up with trailing spaces aString.Trim(CRLF, false, true); aString.ReplaceChar(CRLF, ' '); break; case nsIPlaintextEditor::eNewlinesStrip: aString.StripCRLF(); break; case nsIPlaintextEditor::eNewlinesPasteToFirst: default: { int32_t firstCRLF = aString.FindCharInSet(CRLF); // we get first *non-empty* line. int32_t offset = 0; while (firstCRLF == offset) { offset++; firstCRLF = aString.FindCharInSet(CRLF, offset); } if (firstCRLF > 0) { aString.Truncate(firstCRLF); } if (offset > 0) { aString.Cut(0, offset); } break; } case nsIPlaintextEditor::eNewlinesReplaceWithCommas: aString.Trim(CRLF, true, true); aString.ReplaceChar(CRLF, ','); break; case nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace: { nsAutoString result; uint32_t offset = 0; while (offset < aString.Length()) { int32_t nextCRLF = aString.FindCharInSet(CRLF, offset); if (nextCRLF < 0) { result.Append(nsDependentSubstring(aString, offset)); break; } uint32_t wsBegin = nextCRLF; // look backwards for the first non-whitespace char while (wsBegin > offset && NS_IS_SPACE(aString[wsBegin - 1])) { --wsBegin; } result.Append(nsDependentSubstring(aString, offset, wsBegin - offset)); offset = nextCRLF + 1; while (offset < aString.Length() && NS_IS_SPACE(aString[offset])) { ++offset; } } aString = result; break; } case nsIPlaintextEditor::eNewlinesPasteIntact: // even if we're pasting newlines, don't paste leading/trailing ones aString.Trim(CRLF, true, true); break; } }
// static void nsTextEditRules::HandleNewLines(nsString &aString, PRInt32 aNewlineHandling) { if (aNewlineHandling < 0) { PRInt32 caretStyle; nsPlaintextEditor::GetDefaultEditorPrefs(aNewlineHandling, caretStyle); } switch(aNewlineHandling) { case nsIPlaintextEditor::eNewlinesReplaceWithSpaces: // Strip trailing newlines first so we don't wind up with trailing spaces aString.Trim(CRLF, PR_FALSE, PR_TRUE); aString.ReplaceChar(CRLF, ' '); break; case nsIPlaintextEditor::eNewlinesStrip: aString.StripChars(CRLF); break; case nsIPlaintextEditor::eNewlinesPasteToFirst: default: { PRInt32 firstCRLF = aString.FindCharInSet(CRLF); // we get first *non-empty* line. PRInt32 offset = 0; while (firstCRLF == offset) { offset++; firstCRLF = aString.FindCharInSet(CRLF, offset); } if (firstCRLF > 0) aString.Truncate(firstCRLF); if (offset > 0) aString.Cut(0, offset); } break; case nsIPlaintextEditor::eNewlinesReplaceWithCommas: aString.Trim(CRLF, PR_TRUE, PR_TRUE); aString.ReplaceChar(CRLF, ','); break; case nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace: { // find each newline, and strip all the whitespace before // and after it PRInt32 firstCRLF = aString.FindCharInSet(CRLF); while (firstCRLF >= 0) { PRUint32 wsBegin = firstCRLF, wsEnd = firstCRLF + 1; // look backwards for the first non-whitespace char while (wsBegin > 0 && NS_IS_SPACE(aString[wsBegin - 1])) --wsBegin; while (wsEnd < aString.Length() && NS_IS_SPACE(aString[wsEnd])) ++wsEnd; // now cut this range out of the string aString.Cut(wsBegin, wsEnd - wsBegin); // look for another CR or LF firstCRLF = aString.FindCharInSet(CRLF); } } break; case nsIPlaintextEditor::eNewlinesPasteIntact: // even if we're pasting newlines, don't paste leading/trailing ones aString.Trim(CRLF, PR_TRUE, PR_TRUE); break; } }
nsresult nsTextEditRules::WillInsertText(PRInt32 aAction, nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled, const nsAString *inString, nsAString *outString, PRInt32 aMaxLength) { if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; } if (inString->IsEmpty() && (aAction != kInsertTextIME)) { // HACK: this is a fix for bug 19395 // I can't outlaw all empty insertions // because IME transaction depend on them // There is more work to do to make the // world safe for IME. *aCancel = PR_TRUE; *aHandled = PR_FALSE; return NS_OK; } // initialize out param *aCancel = PR_FALSE; *aHandled = PR_TRUE; // handle docs with a max length // NOTE, this function copies inString into outString for us. nsresult res = TruncateInsertionIfNeeded(aSelection, inString, outString, aMaxLength); if (NS_FAILED(res)) return res; PRUint32 start = 0; PRUint32 end = 0; // handle password field docs if (mFlags & nsIPlaintextEditor::eEditorPasswordMask) { res = mEditor->GetTextSelectionOffsets(aSelection, start, end); NS_ASSERTION((NS_SUCCEEDED(res)), "getTextSelectionOffsets failed!"); if (NS_FAILED(res)) return res; } // if the selection isn't collapsed, delete it. PRBool bCollapsed; res = aSelection->GetIsCollapsed(&bCollapsed); if (NS_FAILED(res)) return res; if (!bCollapsed) { res = mEditor->DeleteSelection(nsIEditor::eNone); if (NS_FAILED(res)) return res; } res = WillInsert(aSelection, aCancel); if (NS_FAILED(res)) return res; // initialize out param // we want to ignore result of WillInsert() *aCancel = PR_FALSE; // handle password field data // this has the side effect of changing all the characters in aOutString // to the replacement character if (mFlags & nsIPlaintextEditor::eEditorPasswordMask) { if (aAction == kInsertTextIME) { res = RemoveIMETextFromPWBuf(start, outString); if (NS_FAILED(res)) return res; } } // People have lots of different ideas about what text fields // should do with multiline pastes. See bugs 21032, 23485, 23485, 50935. // The six possible options are: // 0. paste newlines intact // 1. paste up to the first newline (default) // 2. replace newlines with spaces // 3. strip newlines // 4. replace with commas // 5. strip newlines and surrounding whitespace // So find out what we're expected to do: if (nsIPlaintextEditor::eEditorSingleLineMask & mFlags) { nsAutoString tString(*outString); switch(mEditor->mNewlineHandling) { case nsIPlaintextEditor::eNewlinesReplaceWithSpaces: // Strip trailing newlines first so we don't wind up with trailing spaces tString.Trim(CRLF, PR_FALSE, PR_TRUE); tString.ReplaceChar(CRLF, ' '); break; case nsIPlaintextEditor::eNewlinesStrip: tString.StripChars(CRLF); break; case nsIPlaintextEditor::eNewlinesPasteToFirst: default: { PRInt32 firstCRLF = tString.FindCharInSet(CRLF); // we get first *non-empty* line. PRInt32 offset = 0; while (firstCRLF == offset) { offset++; firstCRLF = tString.FindCharInSet(CRLF, offset); } if (firstCRLF > 0) tString.Truncate(firstCRLF); if (offset > 0) tString.Cut(0, offset); } break; case nsIPlaintextEditor::eNewlinesReplaceWithCommas: tString.Trim(CRLF, PR_TRUE, PR_TRUE); tString.ReplaceChar(CRLF, ','); break; case nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace: { // find each newline, and strip all the whitespace before // and after it PRInt32 firstCRLF = tString.FindCharInSet(CRLF); while (firstCRLF >= 0) { PRUint32 wsBegin = firstCRLF, wsEnd = firstCRLF + 1; // look backwards for the first non-whitespace char while (wsBegin > 0 && NS_IS_SPACE(tString[wsBegin - 1])) --wsBegin; while (wsEnd < tString.Length() && NS_IS_SPACE(tString[wsEnd])) ++wsEnd; // now cut this range out of the string tString.Cut(wsBegin, wsEnd - wsBegin); // look for another CR or LF firstCRLF = tString.FindCharInSet(CRLF); } } break; case nsIPlaintextEditor::eNewlinesPasteIntact: // even if we're pasting newlines, don't paste leading/trailing ones tString.Trim(CRLF, PR_TRUE, PR_TRUE); break; } outString->Assign(tString); } if (mFlags & nsIPlaintextEditor::eEditorPasswordMask) { // manage the password buffer mPasswordText.Insert(*outString, start); nsCOMPtr<nsILookAndFeel> lookAndFeel = do_GetService(kLookAndFeelCID); if (lookAndFeel->GetEchoPassword() && !(mFlags & nsIPlaintextEditor::eEditorDontEchoPassword)) { HideLastPWInput(); mLastStart = start; mLastLength = outString->Length(); if (mTimer) { mTimer->Cancel(); } else { mTimer = do_CreateInstance("@mozilla.org/timer;1", &res); if (NS_FAILED(res)) return res; } mTimer->InitWithCallback(this, 600, nsITimer::TYPE_ONE_SHOT); } else { res = FillBufWithPWChars(outString, outString->Length()); if (NS_FAILED(res)) return res; } } // get the (collapsed) selection location nsCOMPtr<nsIDOMNode> selNode; PRInt32 selOffset; res = mEditor->GetStartNodeAndOffset(aSelection, address_of(selNode), &selOffset); if (NS_FAILED(res)) return res; // don't put text in places that can't have it if (!mEditor->IsTextNode(selNode) && !mEditor->CanContainTag(selNode, NS_LITERAL_STRING("#text"))) return NS_ERROR_FAILURE; // we need to get the doc nsCOMPtr<nsIDOMDocument>doc; res = mEditor->GetDocument(getter_AddRefs(doc)); if (NS_FAILED(res)) return res; if (!doc) return NS_ERROR_NULL_POINTER; if (aAction == kInsertTextIME) { res = mEditor->InsertTextImpl(*outString, address_of(selNode), &selOffset, doc); if (NS_FAILED(res)) return res; } else // aAction == kInsertText { // find where we are nsCOMPtr<nsIDOMNode> curNode = selNode; PRInt32 curOffset = selOffset; // is our text going to be PREformatted? // We remember this so that we know how to handle tabs. PRBool isPRE; res = mEditor->IsPreformatted(selNode, &isPRE); if (NS_FAILED(res)) return res; // don't spaz my selection in subtransactions nsAutoTxnsConserveSelection dontSpazMySelection(mEditor); nsString tString(*outString); const PRUnichar *unicodeBuf = tString.get(); nsCOMPtr<nsIDOMNode> unused; PRInt32 pos = 0; // for efficiency, break out the pre case separately. This is because // it's a lot cheaper to search the input string for only newlines than // it is to search for both tabs and newlines. if (isPRE) { while (unicodeBuf && (pos != -1) && ((PRUint32)pos < tString.Length())) { PRInt32 oldPos = pos; PRInt32 subStrLen; pos = tString.FindChar(nsCRT::LF, oldPos); if (pos != -1) { subStrLen = pos - oldPos; // if first char is newline, then use just it if (subStrLen == 0) subStrLen = 1; } else { subStrLen = tString.Length() - oldPos; pos = tString.Length(); } nsDependentSubstring subStr(tString, oldPos, subStrLen); // is it a return? if (subStr.EqualsLiteral(LFSTR)) { if (nsIPlaintextEditor::eEditorSingleLineMask & mFlags) { NS_ASSERTION((mEditor->mNewlineHandling == nsIPlaintextEditor::eNewlinesPasteIntact), "Newline improperly getting into single-line edit field!"); res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc); } else { res = mEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone); // If the newline is the last character in the string, and the BR we // just inserted is the last node in the content tree, we need to add // a mozBR so that a blank line is created. if (NS_SUCCEEDED(res) && curNode && pos == (PRInt32)(tString.Length() - 1)) { nsCOMPtr<nsIDOMNode> nextChild = mEditor->GetChildAt(curNode, curOffset); if (!nextChild) { // We must be at the end since there isn't a nextChild. // // curNode and curOffset should be set to the position after // the BR we added above, so just create a mozBR at that position. // // Note that we don't update curOffset after we've created/inserted // the mozBR since we never want the selection to be placed after it. res = CreateMozBR(curNode, curOffset, address_of(unused)); } } } pos++; } else { res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc); } if (NS_FAILED(res)) return res; } } else { char specialChars[] = {TAB, nsCRT::LF, 0}; while (unicodeBuf && (pos != -1) && ((PRUint32)pos < tString.Length())) { PRInt32 oldPos = pos; PRInt32 subStrLen; pos = tString.FindCharInSet(specialChars, oldPos); if (pos != -1) { subStrLen = pos - oldPos; // if first char is newline, then use just it if (subStrLen == 0) subStrLen = 1; } else { subStrLen = tString.Length() - oldPos; pos = tString.Length(); } nsDependentSubstring subStr(tString, oldPos, subStrLen); // is it a tab? if (subStr.EqualsLiteral("\t")) { res = mEditor->InsertTextImpl(NS_LITERAL_STRING(" "), address_of(curNode), &curOffset, doc); pos++; } // is it a return? else if (subStr.EqualsLiteral(LFSTR)) { res = mEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone); pos++; } else { res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc); } if (NS_FAILED(res)) return res; } } outString->Assign(tString); if (curNode) { aSelection->Collapse(curNode, curOffset); // Make the caret attach to the inserted text, unless this text ends with a LF, // in which case make the caret attach to the next line. PRBool endsWithLF = !tString.IsEmpty() && tString.get()[tString.Length() - 1] == nsCRT::LF; nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection)); selPrivate->SetInterlinePosition(endsWithLF); } } ASSERT_PASSWORD_LENGTHS_EQUAL() return res; }