nscoord nsTextControlFrame::GetBoxAscent(nsBoxLayoutState& aState) { // Return the baseline of the first (nominal) row, with centering for // single-line controls. // First calculate the ascent wrt the client rect nsRect clientRect; GetClientRect(clientRect); nscoord lineHeight = IsSingleLineTextControl() ? clientRect.height : nsHTMLReflowState::CalcLineHeight(GetStyleContext(), NS_AUTOHEIGHT); nsRefPtr<nsFontMetrics> fontMet; nsresult rv = nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)); NS_ENSURE_SUCCESS(rv, 0); nscoord ascent = nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight); // Now adjust for our borders and padding ascent += clientRect.y; return ascent; }
nsresult nsTextControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements) { NS_ASSERTION(mContent, "We should have a content!"); mState |= NS_FRAME_INDEPENDENT_SELECTION; nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent()); NS_ASSERTION(txtCtrl, "Content not a text control element"); // Bind the frame to its text control nsresult rv = txtCtrl->BindToFrame(this); NS_ENSURE_SUCCESS(rv, rv); nsIContent* rootNode = txtCtrl->GetRootEditorNode(); NS_ENSURE_TRUE(rootNode, NS_ERROR_OUT_OF_MEMORY); if (!aElements.AppendElement(rootNode)) return NS_ERROR_OUT_OF_MEMORY; // Do we need a placeholder node? nsAutoString placeholderTxt; mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholderTxt); nsContentUtils::RemoveNewlines(placeholderTxt); mUsePlaceholder = !placeholderTxt.IsEmpty(); // Create the placeholder anonymous content if needed. if (mUsePlaceholder) { nsIContent* placeholderNode = txtCtrl->CreatePlaceholderNode(); NS_ENSURE_TRUE(placeholderNode, NS_ERROR_OUT_OF_MEMORY); if (!aElements.AppendElement(placeholderNode)) return NS_ERROR_OUT_OF_MEMORY; } rv = UpdateValueDisplay(PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); // textareas are eagerly initialized PRBool initEagerly = !IsSingleLineTextControl(); if (!initEagerly) { nsCOMPtr<nsIDOMNSHTMLElement> element = do_QueryInterface(txtCtrl); if (element) { // so are input text controls with spellcheck=true element->GetSpellcheck(&initEagerly); } } if (initEagerly) { NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), "Someone forgot a script blocker?"); if (!nsContentUtils::AddScriptRunner(new EditorInitializer(this))) { return NS_ERROR_OUT_OF_MEMORY; } } return NS_OK; }
nsresult nsTextControlFrame::GetText(nsString& aText) { nsresult rv = NS_OK; nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent()); NS_ASSERTION(txtCtrl, "Content not a text control element"); if (IsSingleLineTextControl()) { // There will be no line breaks so we can ignore the wrap property. txtCtrl->GetTextEditorValue(aText, PR_TRUE); } else { nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea = do_QueryInterface(mContent); if (textArea) { rv = textArea->GetValue(aText); } } return rv; }
nsresult nsTextControlFrame::UpdateValueDisplay(PRBool aNotify, PRBool aBeforeEditorInit, const nsAString *aValue) { if (!IsSingleLineTextControl()) // textareas don't use this return NS_OK; nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent()); NS_ASSERTION(txtCtrl, "Content not a text control element"); nsIContent* rootNode = txtCtrl->GetRootEditorNode(); NS_PRECONDITION(rootNode, "Must have a div content\n"); NS_PRECONDITION(!mUseEditor, "Do not call this after editor has been initialized"); NS_ASSERTION(!mUsePlaceholder || txtCtrl->GetPlaceholderNode(), "A placeholder div must exist"); nsIContent *textContent = rootNode->GetChildAt(0); if (!textContent) { // Set up a textnode with our value nsCOMPtr<nsIContent> textNode; nsresult rv = NS_NewTextNode(getter_AddRefs(textNode), mContent->NodeInfo()->NodeInfoManager()); NS_ENSURE_SUCCESS(rv, rv); NS_ASSERTION(textNode, "Must have textcontent!\n"); rootNode->AppendChildTo(textNode, aNotify); textContent = textNode; } NS_ENSURE_TRUE(textContent, NS_ERROR_UNEXPECTED); // Get the current value of the textfield from the content. nsAutoString value; if (aValue) { value = *aValue; } else { txtCtrl->GetTextEditorValue(value, PR_TRUE); } // Update the display of the placeholder value if needed. // We don't need to do this if we're about to initialize the // editor, since EnsureEditorInitialized takes care of this. if (mUsePlaceholder && !aBeforeEditorInit) { nsWeakFrame weakFrame(this); txtCtrl->SetPlaceholderClass(value.IsEmpty(), aNotify); NS_ENSURE_STATE(weakFrame.IsAlive()); } if (aBeforeEditorInit && value.IsEmpty()) { rootNode->RemoveChildAt(0, PR_TRUE); return NS_OK; } if (!value.IsEmpty() && IsPasswordTextControl()) { nsTextEditRules::FillBufWithPWChars(&value, value.Length()); } return textContent->SetText(value, aNotify); }
PRBool nsTextControlFrame::IsScrollable() const { return !IsSingleLineTextControl(); }
nsresult nsTextControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) { NS_ASSERTION(mContent, "We should have a content!"); mState |= NS_FRAME_INDEPENDENT_SELECTION; nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent()); NS_ASSERTION(txtCtrl, "Content not a text control element"); // Bind the frame to its text control nsresult rv = txtCtrl->BindToFrame(this); NS_ENSURE_SUCCESS(rv, rv); nsIContent* rootNode = txtCtrl->GetRootEditorNode(); NS_ENSURE_TRUE(rootNode, NS_ERROR_OUT_OF_MEMORY); if (!aElements.AppendElement(rootNode)) return NS_ERROR_OUT_OF_MEMORY; // Do we need a placeholder node? nsAutoString placeholderTxt; mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholderTxt); nsContentUtils::RemoveNewlines(placeholderTxt); mUsePlaceholder = !placeholderTxt.IsEmpty(); // Create the placeholder anonymous content if needed. if (mUsePlaceholder) { nsIContent* placeholderNode = txtCtrl->CreatePlaceholderNode(); NS_ENSURE_TRUE(placeholderNode, NS_ERROR_OUT_OF_MEMORY); if (!aElements.AppendElement(placeholderNode)) return NS_ERROR_OUT_OF_MEMORY; } rv = UpdateValueDisplay(false); NS_ENSURE_SUCCESS(rv, rv); // textareas are eagerly initialized bool initEagerly = !IsSingleLineTextControl(); if (!initEagerly) { // Also, input elements which have a cached selection should get eager // editor initialization. nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent()); NS_ASSERTION(txtCtrl, "Content not a text control element"); initEagerly = txtCtrl->HasCachedSelection(); } if (!initEagerly) { nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(txtCtrl); if (element) { // so are input text controls with spellcheck=true element->GetSpellcheck(&initEagerly); } } if (initEagerly) { NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), "Someone forgot a script blocker?"); EditorInitializer* initializer = (EditorInitializer*) Properties().Get(TextControlInitializer()); if (initializer) { initializer->Revoke(); } initializer = new EditorInitializer(this); Properties().Set(TextControlInitializer(),initializer); if (!nsContentUtils::AddScriptRunner(initializer)) { initializer->Revoke(); // paranoia Properties().Delete(TextControlInitializer()); delete initializer; return NS_ERROR_OUT_OF_MEMORY; } } return NS_OK; }