Bug 253870 - Make disabled form controls selectable. r=masayuki,MarcoZ
This rejiggers a bit the way selection focus is handled so that focusing a disabled form control with the mouse handles selection properly, and hides the document selection and so on. This matches the behavior of other browsers as far as I can tell. Given now readonly and disabled editors behave the same, we can simplify a bit the surrounding editor code. Differential Revision: https://phabricator.services.mozilla.com/D66464
This commit is contained in:
@@ -174,10 +174,6 @@ class RestoreSelectionState : public Runnable {
|
||||
mFrame->SetSelectionRange(properties.GetStart(), properties.GetEnd(),
|
||||
properties.GetDirection());
|
||||
}
|
||||
if (!mTextControlState->mSelectionRestoreEagerInit) {
|
||||
mTextControlState->HideSelectionIfBlurred();
|
||||
}
|
||||
mTextControlState->mSelectionRestoreEagerInit = false;
|
||||
}
|
||||
|
||||
if (mTextControlState) {
|
||||
@@ -217,7 +213,6 @@ class MOZ_RAII AutoRestoreEditorState final {
|
||||
// appearing the method in profile. So, this class should check if it's
|
||||
// necessary to call.
|
||||
uint32_t flags = mSavedFlags;
|
||||
flags &= ~(nsIEditor::eEditorDisabledMask);
|
||||
flags &= ~(nsIEditor::eEditorReadonlyMask);
|
||||
flags |= nsIEditor::eEditorDontEchoPassword;
|
||||
if (mSavedFlags != flags) {
|
||||
@@ -361,6 +356,8 @@ class TextInputSelectionController final : public nsSupportsWeakReference,
|
||||
int16_t aStartOffset,
|
||||
int16_t aEndOffset,
|
||||
bool* aRetval) override;
|
||||
void SelectionWillTakeFocus() override;
|
||||
void SelectionWillLoseFocus() override;
|
||||
|
||||
private:
|
||||
RefPtr<nsFrameSelection> mFrameSelection;
|
||||
@@ -771,6 +768,22 @@ TextInputSelectionController::SelectAll() {
|
||||
return frameSelection->SelectAll();
|
||||
}
|
||||
|
||||
void TextInputSelectionController::SelectionWillTakeFocus() {
|
||||
if (mFrameSelection) {
|
||||
if (PresShell* shell = mFrameSelection->GetPresShell()) {
|
||||
shell->FrameSelectionWillTakeFocus(*mFrameSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextInputSelectionController::SelectionWillLoseFocus() {
|
||||
if (mFrameSelection) {
|
||||
if (PresShell* shell = mFrameSelection->GetPresShell()) {
|
||||
shell->FrameSelectionWillLoseFocus(*mFrameSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TextInputSelectionController::CheckVisibility(nsINode* node,
|
||||
int16_t startOffset,
|
||||
@@ -1396,7 +1409,6 @@ TextControlState::TextControlState(TextControlElement* aOwningElement)
|
||||
mEditorInitialized(false),
|
||||
mValueTransferInProgress(false),
|
||||
mSelectionCached(true),
|
||||
mSelectionRestoreEagerInit(false),
|
||||
mPlaceholderVisibility(false),
|
||||
mPreviewVisibility(false)
|
||||
// When adding more member variable initializations here, add the same
|
||||
@@ -1419,7 +1431,6 @@ TextControlState* TextControlState::Construct(
|
||||
state->mEditorInitialized = false;
|
||||
state->mValueTransferInProgress = false;
|
||||
state->mSelectionCached = true;
|
||||
state->mSelectionRestoreEagerInit = false;
|
||||
state->mPlaceholderVisibility = false;
|
||||
state->mPreviewVisibility = false;
|
||||
// When adding more member variable initializations here, add the same
|
||||
@@ -1640,7 +1651,9 @@ nsresult TextControlState::BindToFrame(nsTextControlFrame* aFrame) {
|
||||
mTextListener = new TextInputListener(mTextCtrlElement);
|
||||
|
||||
mTextListener->SetFrame(mBoundFrame);
|
||||
mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
||||
|
||||
// Editor will override this as needed from InitializeSelection.
|
||||
mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);
|
||||
|
||||
// Get the caret and make it a selection listener.
|
||||
// FYI: It's safe to use raw pointer for calling
|
||||
@@ -1884,21 +1897,13 @@ nsresult TextControlState::PrepareEditor(const nsAString* aValue) {
|
||||
editorFlags = newTextEditor->Flags();
|
||||
|
||||
// Check if the readonly attribute is set.
|
||||
if (mTextCtrlElement->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly)) {
|
||||
//
|
||||
// TODO: Should probably call IsDisabled(), as it is cheaper.
|
||||
if (mTextCtrlElement->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly) ||
|
||||
mTextCtrlElement->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
|
||||
editorFlags |= nsIEditor::eEditorReadonlyMask;
|
||||
}
|
||||
|
||||
// Check if the disabled attribute is set.
|
||||
// TODO: call IsDisabled() here!
|
||||
if (mTextCtrlElement->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
|
||||
editorFlags |= nsIEditor::eEditorDisabledMask;
|
||||
}
|
||||
|
||||
// Disable the selection if necessary.
|
||||
if (newTextEditor->IsDisabled()) {
|
||||
mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_OFF);
|
||||
}
|
||||
|
||||
SetEditorFlagsIfNecessary(*newTextEditor, editorFlags);
|
||||
|
||||
if (shouldInitializeEditor) {
|
||||
@@ -2385,6 +2390,10 @@ void TextControlState::UnbindFromFrame(nsTextControlFrame* aFrame) {
|
||||
AutoTextControlHandlingState handlingUnbindFromFrame(
|
||||
*this, TextControlAction::UnbindFromFrame);
|
||||
|
||||
if (mSelCon) {
|
||||
mSelCon->SelectionWillLoseFocus();
|
||||
}
|
||||
|
||||
// We need to start storing the value outside of the editor if we're not
|
||||
// going to use it anymore, so retrieve it for now.
|
||||
nsAutoString value;
|
||||
@@ -3087,13 +3096,6 @@ void TextControlState::UpdateOverlayTextVisibility(bool aNotify) {
|
||||
}
|
||||
}
|
||||
|
||||
void TextControlState::HideSelectionIfBlurred() {
|
||||
MOZ_ASSERT(mSelCon, "Should have a selection controller if we have a frame!");
|
||||
if (!nsContentUtils::IsFocusedContent(mTextCtrlElement)) {
|
||||
mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
bool TextControlState::EditorHasComposition() {
|
||||
return mTextEditor && mTextEditor->IsIMEComposing();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user