📄 html_formimpl.cpp
字号:
m_maxResults = -1;
#endif
if ( m_form )
m_autocomplete = f->autoComplete();
}
HTMLInputElementImpl::~HTMLInputElementImpl()
{
if (getDocument()) getDocument()->deregisterMaintainsState(this);
delete m_imageLoader;
}
NodeImpl::Id HTMLInputElementImpl::id() const
{
return ID_INPUT;
}
void HTMLInputElementImpl::setType(const DOMString& t)
{
typeEnum newType;
if ( strcasecmp( t, "password" ) == 0 )
newType = PASSWORD;
else if ( strcasecmp( t, "checkbox" ) == 0 )
newType = CHECKBOX;
else if ( strcasecmp( t, "radio" ) == 0 )
newType = RADIO;
else if ( strcasecmp( t, "submit" ) == 0 )
newType = SUBMIT;
else if ( strcasecmp( t, "reset" ) == 0 )
newType = RESET;
else if ( strcasecmp( t, "file" ) == 0 )
newType = FILE;
else if ( strcasecmp( t, "hidden" ) == 0 )
newType = HIDDEN;
else if ( strcasecmp( t, "image" ) == 0 )
newType = IMAGE;
else if ( strcasecmp( t, "button" ) == 0 )
newType = BUTTON;
else if ( strcasecmp( t, "khtml_isindex" ) == 0 )
newType = ISINDEX;
#if APPLE_CHANGES && !NOKIA_CHANGES
else if ( strcasecmp( t, "search" ) == 0 )
newType = SEARCH;
else if ( strcasecmp( t, "range" ) == 0 )
newType = RANGE;
#endif
else
newType = TEXT;
// ### IMPORTANT: Don't allow the type to be changed to FILE after the first
// type change, otherwise a JavaScript programmer would be able to set a text
// field's value to something like /etc/passwd and then change it to a file field.
if (m_type != newType) {
if (newType == FILE && m_haveType) {
// Set the attribute back to the old value.
// Useful in case we were called from inside parseHTMLAttribute.
setAttribute(ATTR_TYPE, type());
} else {
bool wasAttached = m_attached;
if (wasAttached)
detach();
bool didStoreValue = storesValueSeparateFromAttribute();
m_type = newType;
bool willStoreValue = storesValueSeparateFromAttribute();
if (didStoreValue && !willStoreValue && !m_value.isNull()) {
setAttribute(ATTR_VALUE, m_value);
m_value = DOMString();
}
if (!didStoreValue && willStoreValue) {
m_value = getAttribute(ATTR_VALUE);
}
if (wasAttached)
attach();
}
}
m_haveType = true;
}
DOMString HTMLInputElementImpl::type() const
{
// needs to be lowercase according to DOM spec
switch (m_type) {
case TEXT: return "text";
case PASSWORD: return "password";
case CHECKBOX: return "checkbox";
case RADIO: return "radio";
case SUBMIT: return "submit";
case RESET: return "reset";
case FILE: return "file";
case HIDDEN: return "hidden";
case IMAGE: return "image";
case BUTTON: return "button";
#if APPLE_CHANGES
case SEARCH: return "search";
case RANGE: return "range";
#endif
case ISINDEX: return "";
}
return "";
}
QString HTMLInputElementImpl::state( )
{
assert(m_type != PASSWORD); // should never save/restore password fields
QString state = HTMLGenericFormElementImpl::state();
switch (m_type) {
case CHECKBOX:
case RADIO:
return state + (checked() ? "on" : "off");
default:
return state + value().string()+'.'; // Make sure the string is not empty!
}
}
void HTMLInputElementImpl::restoreState(QStringList &states)
{
assert(m_type != PASSWORD); // should never save/restore password fields
QString state = HTMLGenericFormElementImpl::findMatchingState(states);
if (state.isNull()) return;
switch (m_type) {
case CHECKBOX:
case RADIO:
setChecked((state == "on"));
break;
default:
setValue(DOMString(state.left(state.length()-1)));
break;
}
}
void HTMLInputElementImpl::select( )
{
if(!m_render) return;
switch (m_type) {
case FILE:
static_cast<RenderFileButton*>(m_render)->select();
break;
case PASSWORD:
#if APPLE_CHANGES
case SEARCH:
#endif
case TEXT:
static_cast<RenderLineEdit*>(m_render)->select();
break;
case BUTTON:
case CHECKBOX:
case HIDDEN:
case IMAGE:
case ISINDEX:
case RADIO:
#if APPLE_CHANGES
case RANGE:
#endif
case RESET:
case SUBMIT:
break;
}
}
void HTMLInputElementImpl::click(bool sendMouseEvents)
{
switch (inputType()) {
case HIDDEN:
// a no-op for this type
break;
case CHECKBOX:
case RADIO:
case SUBMIT:
case RESET:
case BUTTON:
#if APPLE_CHANGES
{
QWidget *widget;
if (renderer() && (widget = static_cast<RenderWidget *>(renderer())->widget())) {
// using this method gives us nice Cocoa user interface feedback
static_cast<QButton *>(widget)->click(sendMouseEvents);
break;
}
}
#endif
HTMLGenericFormElementImpl::click(sendMouseEvents);
break;
case FILE:
#if APPLE_CHANGES
if (renderer()) {
static_cast<RenderFileButton *>(renderer())->click(sendMouseEvents);
break;
}
#endif
HTMLGenericFormElementImpl::click(sendMouseEvents);
break;
case IMAGE:
case ISINDEX:
case PASSWORD:
#if APPLE_CHANGES
case SEARCH:
case RANGE:
#endif
case TEXT:
HTMLGenericFormElementImpl::click(sendMouseEvents);
break;
}
}
void HTMLInputElementImpl::accessKeyAction(bool sendToAnyElement)
{
switch (inputType()) {
case HIDDEN:
// a no-op for this type
break;
case TEXT:
case PASSWORD:
#if APPLE_CHANGES
case SEARCH:
#endif
case ISINDEX:
focus();
break;
case CHECKBOX:
case RADIO:
case SUBMIT:
case RESET:
case IMAGE:
case BUTTON:
case FILE:
#if APPLE_CHANGES
case RANGE:
#endif
// focus
focus();
// send the mouse button events iff the
// caller specified sendToAnyElement
click(sendToAnyElement);
break;
}
}
bool HTMLInputElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
{
switch (attr) {
case ATTR_WIDTH:
case ATTR_HEIGHT:
case ATTR_VSPACE:
case ATTR_HSPACE:
result = eUniversal;
return false;
case ATTR_ALIGN:
result = eReplaced; // Share with <img> since the alignment behavior is the same.
return false;
default:
break;
}
return HTMLElementImpl::mapToEntry(attr, result);
}
void HTMLInputElementImpl::parseHTMLAttribute(HTMLAttributeImpl *attr)
{
switch(attr->id())
{
case ATTR_AUTOCOMPLETE:
m_autocomplete = strcasecmp( attr->value(), "off" );
break;
case ATTR_TYPE:
setType(attr->value());
if (m_type != IMAGE && m_imageLoader) {
delete m_imageLoader;
m_imageLoader = 0;
}
break;
case ATTR_VALUE:
// We only need to setChanged if the form is looking at the default value right now.
if (m_value.isNull())
setChanged();
m_valueMatchesRenderer = false;
break;
case ATTR_CHECKED:
m_defaultChecked = !attr->isNull();
if (m_useDefaultChecked) {
setChecked(m_defaultChecked);
m_useDefaultChecked = true;
}
break;
case ATTR_MAXLENGTH:
m_maxLen = !attr->isNull() ? attr->value().toInt() : -1;
setChanged();
break;
case ATTR_SIZE:
m_size = !attr->isNull() ? attr->value().toInt() : 20;
#ifdef NOKIA_CHANGES
if (renderer())
renderer()->setNeedsLayoutAndMinMaxRecalc();
#endif
break;
case ATTR_ALT:
if (m_render && m_type == IMAGE)
static_cast<RenderImage*>(m_render)->updateAltText();
break;
case ATTR_SRC:
if (m_render && m_type == IMAGE) {
if (!m_imageLoader)
m_imageLoader = new HTMLImageLoader(this);
m_imageLoader->updateFromElement();
}
break;
case ATTR_USEMAP:
case ATTR_ACCESSKEY:
// ### ignore for the moment
break;
case ATTR_VSPACE:
addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
break;
case ATTR_HSPACE:
addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
break;
case ATTR_ALIGN:
addHTMLAlignment(attr);
break;
case ATTR_WIDTH:
addCSSLength(attr, CSS_PROP_WIDTH, attr->value() );
break;
case ATTR_HEIGHT:
addCSSLength(attr, CSS_PROP_HEIGHT, attr->value() );
break;
case ATTR_ONFOCUS:
setHTMLEventListener(EventImpl::FOCUS_EVENT,
getDocument()->createHTMLEventListener(attr->value().string(), this));
break;
case ATTR_ONBLUR:
setHTMLEventListener(EventImpl::BLUR_EVENT,
getDocument()->createHTMLEventListener(attr->value().string(), this));
break;
case ATTR_ONSELECT:
setHTMLEventListener(EventImpl::SELECT_EVENT,
getDocument()->createHTMLEventListener(attr->value().string(), this));
break;
case ATTR_ONCHANGE:
setHTMLEventListener(EventImpl::CHANGE_EVENT,
getDocument()->createHTMLEventListener(attr->value().string(), this));
break;
case ATTR_ONINPUT:
setHTMLEventListener(EventImpl::INPUT_EVENT,
getDocument()->createHTMLEventListener(attr->value().string(), this));
break;
#if APPLE_CHANGES
// Search field and slider attributes all just cause updateFromElement to be called through style
// recalcing.
case ATTR_ONSEARCH:
setHTMLEventListener(EventImpl::SEARCH_EVENT,
getDocument()->createHTMLEventListener(attr->value().string(), this));
break;
case ATTR_RESULTS:
m_maxResults = !attr->isNull() ? attr->value().toInt() : -1;
/* Fall through */
case ATTR_AUTOSAVE:
case ATTR_INCREMENTAL:
case ATTR_PLACEHOLDER:
case ATTR_MIN:
case ATTR_MAX:
case ATTR_PRECISION:
setChanged();
break;
#endif
default:
HTMLGenericFormElementImpl::parseHTMLAttribute(attr);
}
}
bool HTMLInputElementImpl::rendererIsNeeded(RenderStyle *style)
{
switch(m_type)
{
case TEXT:
case PASSWORD:
#if APPLE_CHANGES
case SEARCH:
case RANGE:
#endif
case ISINDEX:
case CHECKBOX:
case RADIO:
case SUBMIT:
case IMAGE:
case RESET:
case FILE:
case BUTTON: return HTMLGenericFormElementImpl::rendererIsNeeded(style);
case HIDDEN: return false;
}
assert(false);
return false;
}
RenderObject *HTMLInputElementImpl::createRenderer(RenderArena *arena, RenderStyle *style)
{
switch(m_type)
{
case TEXT:
case PASSWORD:
#if APPLE_CHANGES
case SEARCH:
#endif
case ISINDEX: return new (arena) RenderLineEdit(this);
case CHECKBOX: return new (arena) RenderCheckBox(this);
case RADIO: return new (arena) RenderRadioButton(this);
case SUBMIT: return new (arena) RenderSubmitButton(this);
case IMAGE: return new (arena) RenderImageButton(this);
case RESET: return new (arena) RenderResetButton(this);
case FILE: return new (arena) RenderFileButton(this);
case BUTTON: return new (arena) RenderPushButton(this);
#if APPLE_CHANGES
case RANGE: return new (arena) RenderSlider(this);
#endif
case HIDDEN: break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -