☠☠ backed out by 3f90e402ef50 ☠ ☠ | |
author | Ray Lin <ralin@mozilla.com> |
Wed, 03 May 2017 17:08:44 +0800 | |
changeset 357238 | 656b4466e33b889ae1263f110dd0eb97b89c3912 |
parent 357237 | 38346bf36faaff4fa4d99ba88d66475f8a18ac57 |
child 357239 | aeb03a50c12ee0cf614f2e433036e48a63e70f20 |
push id | 31788 |
push user | kwierso@gmail.com |
push date | Tue, 09 May 2017 20:48:49 +0000 |
treeherder | mozilla-central@2b6f6881a24a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | baku, heycam |
bugs | 1340488 |
milestone | 55.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/html/HTMLSelectElement.cpp +++ b/dom/html/HTMLSelectElement.cpp @@ -1927,16 +1927,36 @@ HTMLSelectElement::SetOpenInParentProces { nsIFormControlFrame* formControlFrame = GetFormControlFrame(false); nsIComboboxControlFrame* comboFrame = do_QueryFrame(formControlFrame); if (comboFrame) { comboFrame->SetOpenInParentProcess(aVal); } } +void +HTMLSelectElement::GetPreviewValue(nsAString& aValue) +{ + nsIFormControlFrame* formControlFrame = GetFormControlFrame(false); + nsIComboboxControlFrame* comboFrame = do_QueryFrame(formControlFrame); + if (comboFrame) { + comboFrame->GetPreviewText(aValue); + } +} + +void +HTMLSelectElement::SetPreviewValue(const nsAString& aValue) +{ + nsIFormControlFrame* formControlFrame = GetFormControlFrame(false); + nsIComboboxControlFrame* comboFrame = do_QueryFrame(formControlFrame); + if (comboFrame) { + comboFrame->SetPreviewText(aValue); + } +} + JSObject* HTMLSelectElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { return HTMLSelectElementBinding::Wrap(aCx, this, aGivenProto); } } // namespace dom } // namespace mozilla
--- a/dom/html/HTMLSelectElement.h +++ b/dom/html/HTMLSelectElement.h @@ -438,16 +438,19 @@ public: bool IsCombobox() const { return !Multiple() && Size() <= 1; } bool OpenInParentProcess(); void SetOpenInParentProcess(bool aVal); + void GetPreviewValue(nsAString& aValue); + void SetPreviewValue(const nsAString& aValue); + protected: virtual ~HTMLSelectElement(); friend class SafeOptionListMutation; // Helper Methods /** * Check whether the option specified by the index is selected
--- a/dom/webidl/HTMLSelectElement.webidl +++ b/dom/webidl/HTMLSelectElement.webidl @@ -62,9 +62,11 @@ interface HTMLSelectElement : HTMLElemen // Chrome only interface partial interface HTMLSelectElement { [ChromeOnly] attribute boolean openInParentProcess; [ChromeOnly] AutocompleteInfo getAutocompleteInfo(); + [ChromeOnly] + attribute DOMString previewValue; };
--- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -827,32 +827,22 @@ nsComboboxControlFrame::Reflow(nsPresCon // mListControlFrame. if (!mDisplayFrame || !mButtonFrame || !mDropdownFrame) { NS_ERROR("Why did the frame constructor allow this to happen? Fix it!!"); return; } // Make sure the displayed text is the same as the selected option, bug 297389. - int32_t selectedIndex; - nsAutoString selectedOptionText; if (!mDroppedDown) { - selectedIndex = mListControlFrame->GetSelectedIndex(); + mDisplayedIndex = mListControlFrame->GetSelectedIndex(); } - else { - // In dropped down mode the "selected index" is the hovered menu item, - // we want the last selected item which is |mDisplayedIndex| in this case. - selectedIndex = mDisplayedIndex; - } - if (selectedIndex != -1) { - mListControlFrame->GetOptionText(selectedIndex, selectedOptionText); - } - if (mDisplayedOptionText != selectedOptionText) { - RedisplayText(selectedIndex); - } + // In dropped down mode the "selected index" is the hovered menu item, + // we want the last selected item which is |mDisplayedIndex| in this case. + RedisplayText(); // First reflow our dropdown so that we know how tall we should be. ReflowDropdown(aPresContext, aReflowInput); RefPtr<nsResizeDropdownAtFinalPosition> resize = new nsResizeDropdownAtFinalPosition(this); if (NS_SUCCEEDED(aPresContext->PresShell()->PostReflowCallback(resize))) { // The reflow callback queue doesn't AddRef so we keep it alive until // it's released in its ReflowFinished / ReflowCallbackCanceled. @@ -964,40 +954,55 @@ nsComboboxControlFrame::SetDropDown(nsIF nsIFrame* nsComboboxControlFrame::GetDropDown() { return mDropdownFrame; } /////////////////////////////////////////////////////////////// +void +nsComboboxControlFrame::SetPreviewText(const nsAString& aValue) +{ + nsAutoString previewValue(aValue); + nsContentUtils::RemoveNewlines(previewValue); + + mPreviewText = previewValue; + RedisplayText(); +} + NS_IMETHODIMP nsComboboxControlFrame::RedisplaySelectedText() { nsAutoScriptBlocker scriptBlocker; - return RedisplayText(mListControlFrame->GetSelectedIndex()); + mDisplayedIndex = mListControlFrame->GetSelectedIndex(); + return RedisplayText(); } + nsresult -nsComboboxControlFrame::RedisplayText(int32_t aIndex) +nsComboboxControlFrame::RedisplayText() { + nsString previousText(mDisplayedOptionTextOrPreview); // Get the text to display - if (aIndex != -1) { - mListControlFrame->GetOptionText(aIndex, mDisplayedOptionText); + if (!mPreviewText.IsEmpty()) { + mDisplayedOptionTextOrPreview = mPreviewText; + } else if (mDisplayedIndex != -1) { + mListControlFrame->GetOptionText(mDisplayedIndex, mDisplayedOptionTextOrPreview); } else { - mDisplayedOptionText.Truncate(); + mDisplayedOptionTextOrPreview.Truncate(); } - mDisplayedIndex = aIndex; REFLOW_DEBUG_MSG2("RedisplayText \"%s\"\n", - NS_LossyConvertUTF16toASCII(mDisplayedOptionText).get()); + NS_LossyConvertUTF16toASCII(mDisplayedOptionTextOrPreview).get()); // Send reflow command because the new text maybe larger nsresult rv = NS_OK; - if (mDisplayContent) { + if (mDisplayContent && + !previousText.Equals(mDisplayedOptionTextOrPreview)) { // Don't call ActuallyDisplayText(true) directly here since that // could cause recursive frame construction. See bug 283117 and the comment in // HandleRedisplayTextEvent() below. // Revoke outstanding events to avoid out-of-order events which could mean // displaying the wrong text. mRedisplayTextEvent.Revoke(); @@ -1041,23 +1046,23 @@ nsComboboxControlFrame::HandleRedisplayT NS_FRAME_IS_DIRTY); mInRedisplayText = false; } void nsComboboxControlFrame::ActuallyDisplayText(bool aNotify) { - if (mDisplayedOptionText.IsEmpty()) { + if (mDisplayedOptionTextOrPreview.IsEmpty()) { // Have to use a non-breaking space for line-block-size calculations // to be right static const char16_t space = 0xA0; mDisplayContent->SetText(&space, 1, aNotify); } else { - mDisplayContent->SetText(mDisplayedOptionText, aNotify); + mDisplayContent->SetText(mDisplayedOptionTextOrPreview, aNotify); } } int32_t nsComboboxControlFrame::GetIndexOfDisplayArea() { return mDisplayedIndex; } @@ -1091,36 +1096,38 @@ NS_IMETHODIMP nsComboboxControlFrame::RemoveOption(int32_t aIndex) { AutoWeakFrame weakThis(this); if (mListControlFrame->GetNumberOfOptions() > 0) { if (aIndex < mDisplayedIndex) { --mDisplayedIndex; } else if (aIndex == mDisplayedIndex) { mDisplayedIndex = 0; // IE6 compat - RedisplayText(mDisplayedIndex); + RedisplayText(); } } else { // If we removed the last option, we need to blank things out - RedisplayText(-1); + mDisplayedIndex = -1; + RedisplayText(); } if (!weakThis.IsAlive()) return NS_OK; nsListControlFrame* lcf = static_cast<nsListControlFrame*>(mDropdownFrame); return lcf->RemoveOption(aIndex); } NS_IMETHODIMP nsComboboxControlFrame::OnSetSelectedIndex(int32_t aOldIndex, int32_t aNewIndex) { nsAutoScriptBlocker scriptBlocker; - RedisplayText(aNewIndex); + mDisplayedIndex = aNewIndex; + RedisplayText(); NS_ASSERTION(mDropdownFrame, "No dropdown frame!"); nsISelectControlFrame* listFrame = do_QueryFrame(mDropdownFrame); NS_ASSERTION(listFrame, "No list frame!"); return listFrame->OnSetSelectedIndex(aOldIndex, aNewIndex); } @@ -1216,17 +1223,17 @@ nsComboboxControlFrame::CreateAnonymousC nsNodeInfoManager *nimgr = mContent->NodeInfo()->NodeInfoManager(); mDisplayContent = new nsTextNode(nimgr); // set the value of the text node mDisplayedIndex = mListControlFrame->GetSelectedIndex(); if (mDisplayedIndex != -1) { - mListControlFrame->GetOptionText(mDisplayedIndex, mDisplayedOptionText); + mListControlFrame->GetOptionText(mDisplayedIndex, mDisplayedOptionTextOrPreview); } ActuallyDisplayText(false); if (!aElements.AppendElement(mDisplayContent)) return NS_ERROR_OUT_OF_MEMORY; mButtonContent = mContent->OwnerDoc()->CreateHTMLElement(nsGkAtoms::button); if (!mButtonContent) @@ -1625,17 +1632,18 @@ nsComboboxControlFrame::OnOptionSelected if (mDroppedDown) { nsISelectControlFrame *selectFrame = do_QueryFrame(mListControlFrame); if (selectFrame) { selectFrame->OnOptionSelected(aIndex, aSelected); } } else { if (aSelected) { nsAutoScriptBlocker blocker; - RedisplayText(aIndex); + mDisplayedIndex = aIndex; + RedisplayText(); } else { AutoWeakFrame weakFrame(this); RedisplaySelectedText(); if (weakFrame.IsAlive()) { FireValueChangeEvent(); // Fire after old option is unselected } } }
--- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -266,19 +266,24 @@ protected: * Show or hide the dropdown list. * @param aShowList true to show, false to hide the dropdown. * @note This method might destroy |this|. * @return false if this frame is destroyed, true if still alive. */ bool ShowList(bool aShowList); void CheckFireOnChange(); void FireValueChangeEvent(); - nsresult RedisplayText(int32_t aIndex); + nsresult RedisplayText(); void HandleRedisplayTextEvent(); void ActuallyDisplayText(bool aNotify); + void GetPreviewText(nsAString& aValue) + { + aValue = mPreviewText; + } + void SetPreviewText(const nsAString& aValue); private: // If our total transform to the root frame of the root document is only a 2d // translation then return that translation, otherwise returns (0,0). nsPoint GetCSSTransformTranslation(); protected: nsFrameList mPopupFrames; // additional named child list @@ -292,17 +297,18 @@ protected: // The inline size of our display area. Used by that frame's reflow // to size to the full inline size except the drop-marker. nscoord mDisplayISize; nsRevocableEventPtr<RedisplayTextEvent> mRedisplayTextEvent; int32_t mRecentSelectedIndex; int32_t mDisplayedIndex; - nsString mDisplayedOptionText; + nsString mDisplayedOptionTextOrPreview; + nsString mPreviewText; // make someone to listen to the button. If its programmatically pressed by someone like Accessibility // then open or close the combo box. nsCOMPtr<nsIDOMEventListener> mButtonListener; // The last y-positions used for estimating available space before and // after for the dropdown list in GetAvailableDropdownSpace. These are // reset to nscoord_MIN in AbsolutelyPositionDropDown when placing the
--- a/layout/forms/nsIComboboxControlFrame.h +++ b/layout/forms/nsIComboboxControlFrame.h @@ -48,16 +48,26 @@ public: /** * Redisplay the selected text (will do nothing if text has not changed). * This method might destroy this frame or any others that happen to be * around. It might even run script. */ NS_IMETHOD RedisplaySelectedText() = 0; + /* + * Update preview text for the select control. + */ + virtual void SetPreviewText(const nsAString& aValue) = 0; + + /** + * Get the current preview text for select control. + */ + virtual void GetPreviewText(nsAString& aValue) = 0; + /** * Method for the listbox to set and get the recent index */ virtual int32_t UpdateRecentIndex(int32_t aIndex) = 0; /** * Notification that the content has been reset */