Bug 1446830 - Alternate implementation that uses HTML label with end crop instead of center
MozReview-Commit-ID: 8Ya6L4xFVkx
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -64,18 +64,17 @@ nsFileControlFrame::DestroyFrom(nsIFrame
// Remove the events.
if (mContent) {
mContent->RemoveSystemEventListener(NS_LITERAL_STRING("drop"),
mMouseListener, false);
mContent->RemoveSystemEventListener(NS_LITERAL_STRING("dragover"),
mMouseListener, false);
}
- aPostDestroyData.AddAnonymousContent(mTextContent.forget());
- aPostDestroyData.AddAnonymousContent(mBrowseFilesOrDirs.forget());
+ aPostDestroyData.AddAnonymousContent(mContentContainer.forget());
mMouseListener->ForgetFrame();
nsBlockFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
}
static already_AddRefed<Element>
MakeAnonButton(nsIDocument* aDoc, const char* labelKey,
HTMLInputElement* aInputElement,
@@ -130,39 +129,32 @@ nsFileControlFrame::CreateAnonymousConte
RefPtr<HTMLInputElement> fileContent = HTMLInputElement::FromNodeOrNull(mContent);
// The access key is transferred to the "Choose files..." button only. In
// effect that access key allows access to the control via that button, then
// the user can tab between the two buttons.
nsAutoString accessKey;
fileContent->GetAccessKey(accessKey);
- mBrowseFilesOrDirs = MakeAnonButton(doc, "Browse", fileContent, accessKey);
- if (!mBrowseFilesOrDirs || !aElements.AppendElement(mBrowseFilesOrDirs)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
+ mContentContainer = doc->CreateHTMLElement(nsGkAtoms::div);
+ mContentContainer->SetIsNativeAnonymousRoot();
- // Create and setup the text showing the selected files.
- RefPtr<NodeInfo> nodeInfo;
- nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::label, nullptr,
- kNameSpaceID_XUL,
- nsINode::ELEMENT_NODE);
- NS_TrustedNewXULElement(getter_AddRefs(mTextContent), nodeInfo.forget());
- // NOTE: SetIsNativeAnonymousRoot() has to be called before setting any
- // attribute.
- mTextContent->SetIsNativeAnonymousRoot();
- mTextContent->SetAttr(kNameSpaceID_None, nsGkAtoms::crop,
- NS_LITERAL_STRING("center"), false);
+ mBrowseFilesOrDirs = MakeAnonButton(doc, "Browse", fileContent, accessKey);
+ mContentContainer->AppendChildTo(mBrowseFilesOrDirs, false);
+
+ RefPtr<Element> textLabel = doc->CreateHTMLElement(nsGkAtoms::label);
+ textLabel->AppendChildTo(new nsTextNode(doc->NodeInfoManager()), false);
+ mContentContainer->AppendChildTo(textLabel, false);
// Update the displayed text to reflect the current element's value.
nsAutoString value;
HTMLInputElement::FromNode(mContent)->GetDisplayFileName(value);
UpdateDisplayedValue(value, false);
- if (!aElements.AppendElement(mTextContent)) {
+ if (!mContentContainer || !aElements.AppendElement(mContentContainer)) {
return NS_ERROR_OUT_OF_MEMORY;
}
// We should be able to interact with the element by doing drag and drop.
mContent->AddSystemEventListener(NS_LITERAL_STRING("drop"),
mMouseListener, false);
mContent->AddSystemEventListener(NS_LITERAL_STRING("dragover"),
mMouseListener, false);
@@ -171,22 +163,18 @@ nsFileControlFrame::CreateAnonymousConte
return NS_OK;
}
void
nsFileControlFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
uint32_t aFilter)
{
- if (mBrowseFilesOrDirs) {
- aElements.AppendElement(mBrowseFilesOrDirs);
- }
-
- if (mTextContent) {
- aElements.AppendElement(mTextContent);
+ if (mContentContainer) {
+ aElements.AppendElement(mContentContainer);
}
}
NS_QUERYFRAME_HEAD(nsFileControlFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame)
@@ -464,17 +452,17 @@ nsFileControlFrame::GetFrameName(nsAStri
{
return MakeFrameName(NS_LITERAL_STRING("FileControl"), aResult);
}
#endif
void
nsFileControlFrame::UpdateDisplayedValue(const nsAString& aValue, bool aNotify)
{
- mTextContent->SetAttr(kNameSpaceID_None, nsGkAtoms::value, aValue, aNotify);
+ mContentContainer->GetLastChild()->GetFirstChild()->AsText()->SetText(aValue, aNotify);
}
nsresult
nsFileControlFrame::SetFormProperty(nsAtom* aName,
const nsAString& aValue)
{
if (nsGkAtoms::value == aName) {
UpdateDisplayedValue(aValue, true);
--- a/layout/forms/nsFileControlFrame.h
+++ b/layout/forms/nsFileControlFrame.h
@@ -129,20 +129,20 @@ protected:
virtual bool IsFrameOfType(uint32_t aFlags) const override
{
return nsBlockFrame::IsFrameOfType(aFlags &
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
}
/**
- * The text box input.
+ * The container for the button and label.
* @see nsFileControlFrame::CreateAnonymousContent
*/
- RefPtr<Element> mTextContent;
+ RefPtr<Element> mContentContainer;
/**
* The button to open a file or directory picker.
* @see nsFileControlFrame::CreateAnonymousContent
*/
RefPtr<Element> mBrowseFilesOrDirs;
/**
* Drag and drop mouse listener.
--- a/layout/style/res/forms.css
+++ b/layout/style/res/forms.css
@@ -3,17 +3,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
Styles for old GFX form widgets
**/
@namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
-@namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
*|*::-moz-fieldset-content {
display: block; /* nsRuleNode::ComputeDisplayData overrules this in some cases */
unicode-bidi: inherit;
text-overflow: inherit;
overflow: inherit;
overflow-clip-box: inherit;
/* Need to inherit border-radius too, so when the fieldset has rounded
@@ -474,49 +473,60 @@ input[type="image"]:disabled {
input[type="image"]:-moz-focusring {
/* Don't specify the outline-color, we should always use initial value. */
outline: 1px dotted;
}
/* file selector */
input[type="file"] {
display: inline-block;
- white-space: nowrap;
+ white-space: -moz-pre-space;
overflow: hidden;
overflow-clip-box: padding-box;
color: inherit;
/* Revert rules which apply on all inputs. */
-moz-appearance: none;
-moz-binding: none;
cursor: default;
border: none;
background-color: transparent;
padding: 0;
}
-input[type="file"] > xul|label {
+input[type="file"] > div {
+ display: inline-flex;
+ width: 100%;
+ -moz-user-select: none;
+ align-items: center;
+}
+
+input[type="file"] > div > label {
min-inline-size: 12em;
padding-inline-start: 5px;
text-align: match-parent;
color: inherit;
font-size: inherit;
letter-spacing: inherit;
+ flex: 1;
+ text-overflow: ellipsis;
+ overflow: hidden;
+
/*
* Force the text to have LTR directionality. Otherwise filenames containing
* RTL characters will be reordered with chaotic results.
*/
direction: ltr !important;
}
/* button part of file selector */
-input[type="file"] > button[type="button"] {
+input[type="file"] > div > button {
block-size: inherit;
font-size: inherit;
letter-spacing: inherit;
cursor: inherit;
}
/* colored part of the color selector button */
input[type="color"]::-moz-color-swatch {
@@ -529,17 +539,17 @@ input[type="color"]::-moz-color-swatch {
box-sizing: border-box;
border: 1px solid grey;
display: block;
}
/* Try to make RTL <input type='file'> look nicer. */
/* TODO: find a better solution than forcing direction: ltr on all file
input labels and remove this override -- bug 1161482 */
-input[type="file"]:dir(rtl) > xul|label {
+input[type="file"]:dir(rtl) > div > label {
padding-inline-start: 0px;
padding-inline-end: 5px;
}
/* radio buttons */
input[type="radio"] {
display: inline-block;
-moz-appearance: radio;
@@ -724,32 +734,30 @@ input[type="button"]:active:hover,
input[type="submit"]:active:hover {
color: ButtonText;
}
button::-moz-focus-inner,
input[type="color"]::-moz-focus-inner,
input[type="reset"]::-moz-focus-inner,
input[type="button"]::-moz-focus-inner,
-input[type="submit"]::-moz-focus-inner,
-input[type="file"] > button[type="button"]::-moz-focus-inner {
+input[type="submit"]::-moz-focus-inner {
/* Note this padding only affects the -moz-focus-inner ring, not the button itself */
padding-block-start: 0px;
padding-inline-end: 2px;
padding-block-end: 0px;
padding-inline-start: 2px;
border: 1px dotted transparent;
}
button:-moz-focusring::-moz-focus-inner,
input[type="color"]:-moz-focusring::-moz-focus-inner,
input[type="reset"]:-moz-focusring::-moz-focus-inner,
input[type="button"]:-moz-focusring::-moz-focus-inner,
-input[type="submit"]:-moz-focusring::-moz-focus-inner,
-input[type="file"] > button[type="button"]:-moz-focusring::-moz-focus-inner {
+input[type="submit"]:-moz-focusring::-moz-focus-inner {
border-color: ButtonText;
}
button:disabled:active, button:disabled,
input[type="color"]:disabled:active,
input[type="color"]:disabled,
input[type="reset"]:disabled:active,
input[type="reset"]:disabled,