TEST_F(HTMLSelectElementTest, SaveRestoreSelectSingleFormControlState) { document().documentElement()->setInnerHTML( String("<!DOCTYPE HTML><select id='sel'>" "<option value='111' id='0'>111</option>" "<option value='222'>222</option>" "<option value='111' selected id='2'>!666</option>" "<option value='999'>999</option></select>"), ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); Element* element = document().getElementById("sel"); HTMLFormControlElementWithState* select = toHTMLSelectElement(element); HTMLOptionElement* opt0 = toHTMLOptionElement(document().getElementById("0")); HTMLOptionElement* opt2 = toHTMLOptionElement(document().getElementById("2")); // Save the select element state, and then restore again. // Test passes if the restored state is not changed. EXPECT_EQ(2, toHTMLSelectElement(element)->selectedIndex()); EXPECT_FALSE(opt0->selected()); EXPECT_TRUE(opt2->selected()); FormControlState selectState = select->saveFormControlState(); EXPECT_EQ(2U, selectState.valueSize()); // Clear the selected state, to be restored by restoreFormControlState. toHTMLSelectElement(select)->setSelectedIndex(-1); ASSERT_FALSE(opt2->selected()); // Restore select->restoreFormControlState(selectState); EXPECT_EQ(2, toHTMLSelectElement(element)->selectedIndex()); EXPECT_FALSE(opt0->selected()); EXPECT_TRUE(opt2->selected()); }
TEST_F(HTMLSelectElementTest, RestoreUnmatchedFormControlState) { // We had a bug that selectedOption() and m_lastOnChangeOption were // mismatched in optionToBeShown(). It happened when // restoreFormControlState() couldn't find matched OPTIONs. // crbug.com/627833. document().documentElement()->setInnerHTML( "<select id='sel'>" "<option selected>Default</option>" "<option id='2'>222</option>" "</select>", ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); Element* element = document().getElementById("sel"); HTMLFormControlElementWithState* select = toHTMLSelectElement(element); HTMLOptionElement* opt2 = toHTMLOptionElement(document().getElementById("2")); toHTMLSelectElement(element)->setSelectedIndex(1); // Save the current state. FormControlState selectState = select->saveFormControlState(); EXPECT_EQ(2U, selectState.valueSize()); // Reset the status. select->reset(); ASSERT_FALSE(opt2->selected()); element->removeChild(opt2); // Restore select->restoreFormControlState(selectState); EXPECT_EQ(-1, toHTMLSelectElement(element)->selectedIndex()); EXPECT_EQ(nullptr, toHTMLSelectElement(element)->optionToBeShown()); }
static unsigned getNumberFromFormControlState(const FormControlState& state, size_t index) { if (index >= state.valueSize()) return DateTimeFieldsState::emptyValue; bool parsed; unsigned const value = state[index].toUInt(&parsed); return parsed ? value : DateTimeFieldsState::emptyValue; }
unsigned FormController::formElementsCharacterCount() const { unsigned count = 0; for (auto& element : m_formElementsWithState) { FormControlState state = element->saveFormControlState(); if (state.valueSize() && element->isTextFormControl()) count += state[0].length(); } return count; }
Vector<FileChooserFileInfo> FileInputType::filesFromFormControlState(const FormControlState& state) { Vector<FileChooserFileInfo> files; for (size_t i = 0; i < state.valueSize(); i += 2) { if (!state[i + 1].isEmpty()) files.append(FileChooserFileInfo(state[i], state[i + 1])); else files.append(FileChooserFileInfo(state[i])); } return files; }
static DateTimeFieldsState::AMPMValue getAMPMFromFormControlState(const FormControlState& state, size_t index) { if (index >= state.valueSize()) return DateTimeFieldsState::AMPMValueEmpty; const String value = state[index]; if (value == "A") return DateTimeFieldsState::AMPMValueAM; if (value == "P") return DateTimeFieldsState::AMPMValuePM; return DateTimeFieldsState::AMPMValueEmpty; }
void FormController::restoreControlStateFor(HTMLFormControlElementWithState& control) { // We don't save state of a control with shouldSaveAndRestoreFormControlState() // == false. But we need to skip restoring process too because a control in // another form might have the same pair of name and type and saved its state. if (!control.shouldSaveAndRestoreFormControlState()) return; if (ownerFormForState(control)) return; FormControlState state = takeStateForFormElement(control); if (state.valueSize() > 0) control.restoreFormControlState(state); }
void FormController::restoreControlStateIn(HTMLFormElement& form) { for (auto& element : form.associatedElements()) { if (!element->isFormControlElementWithState()) continue; HTMLFormControlElementWithState* control = static_cast<HTMLFormControlElementWithState*>(element); if (!control->shouldSaveAndRestoreFormControlState()) continue; if (ownerFormForState(*control) != &form) continue; FormControlState state = takeStateForFormElement(*control); if (state.valueSize() > 0) control->restoreFormControlState(state); } }
void FormController::restoreControlStateIn(HTMLFormElement& form) { const Vector<FormAssociatedElement*>& elements = form.associatedElements(); for (size_t i = 0; i < elements.size(); ++i) { if (!elements[i]->isFormControlElementWithState()) continue; HTMLFormControlElementWithState* control = static_cast<HTMLFormControlElementWithState*>(elements[i]); if (!control->shouldSaveAndRestoreFormControlState()) continue; if (ownerFormForState(*control) != &form) continue; FormControlState state = takeStateForFormElement(*control); if (state.valueSize() > 0) control->restoreFormControlState(state); } }
void FileInputType::restoreFormControlState(const FormControlState& state) { if (state.valueSize() % 2) return; filesChosen(filesFromFormControlState(state)); }