📄 html_formimpl.cpp
字号:
// Delayed attachment in order to prevent FOUC can result in an object being
// programmatically focused before it has a render object. If we have been focused
// (i.e., if we are the focusNode) then go ahead and focus our corresponding native widget.
// (Attach/detach can also happen as a result of display type changes, e.g., making a widget
// block instead of inline, and focus should be restored in that case as well.)
if (getDocument()->focusNode() == this && m_render->isWidget() &&
static_cast<RenderWidget*>(renderer())->widget())
static_cast<RenderWidget*>(renderer())->widget()->setFocus();
}
}
void HTMLGenericFormElementImpl::insertedIntoDocument()
{
if (m_form && m_dormant)
m_form->registerFormElement(this);
m_dormant = false;
HTMLElementImpl::insertedIntoDocument();
}
void HTMLGenericFormElementImpl::removedFromDocument()
{
if (m_form)
m_form->makeFormElementDormant(this);
m_dormant = true;
HTMLElementImpl::removedFromDocument();
}
HTMLFormElementImpl *HTMLGenericFormElementImpl::getForm() const
{
NodeImpl *p = parentNode();
while(p)
{
if( p->id() == ID_FORM )
return static_cast<HTMLFormElementImpl *>(p);
p = p->parentNode();
}
#ifdef FORMS_DEBUG
kdDebug( 6030 ) << "couldn't find form!" << endl;
#endif
return 0;
}
DOMString HTMLGenericFormElementImpl::name() const
{
if (m_name) return m_name;
// ###
// DOMString n = getDocument()->htmlMode() != DocumentImpl::XHtml ?
// getAttribute(ATTR_NAME) : getAttribute(ATTR_ID);
DOMString n = getAttribute(ATTR_NAME);
if (n.isNull())
return new DOMStringImpl("");
return n;
}
void HTMLGenericFormElementImpl::setName(const DOMString& name)
{
if (m_name) m_name->deref();
m_name = name.implementation();
if (m_name) m_name->ref();
}
void HTMLGenericFormElementImpl::onSelect()
{
// ### make this work with new form events architecture
dispatchHTMLEvent(EventImpl::SELECT_EVENT,true,false);
}
void HTMLGenericFormElementImpl::onChange()
{
// ### make this work with new form events architecture
dispatchHTMLEvent(EventImpl::CHANGE_EVENT,true,false);
}
bool HTMLGenericFormElementImpl::disabled() const
{
return m_disabled;
}
void HTMLGenericFormElementImpl::setDisabled( bool _disabled )
{
if ( m_disabled != _disabled ) {
m_disabled = _disabled;
setChanged();
}
}
void HTMLGenericFormElementImpl::recalcStyle( StyleChange ch )
{
//bool changed = changed();
HTMLElementImpl::recalcStyle( ch );
if (m_render /*&& changed*/)
m_render->updateFromElement();
}
bool HTMLGenericFormElementImpl::isFocusable() const
{
if (!m_render || (m_render->style() && m_render->style()->visibility() != VISIBLE) || m_render->width() == 0 || m_render->height() == 0)
return false;
return true;
}
bool HTMLGenericFormElementImpl::isKeyboardFocusable() const
{
if (isFocusable()) {
if (m_render->isWidget()) {
return static_cast<RenderWidget*>(m_render)->widget() &&
(static_cast<RenderWidget*>(m_render)->widget()->focusPolicy() & QWidget::TabFocus);
}
if (getDocument()->part())
return getDocument()->part()->tabsToAllControls();
}
return false;
}
bool HTMLGenericFormElementImpl::isMouseFocusable() const
{
if (isFocusable()) {
if (m_render->isWidget()) {
return static_cast<RenderWidget*>(m_render)->widget() &&
(static_cast<RenderWidget*>(m_render)->widget()->focusPolicy() & QWidget::ClickFocus);
}
#if APPLE_CHANGES
// For <input type=image> and <button>, we will assume no mouse focusability. This is
// consistent with OS X behavior for buttons.
return false;
#else
return true;
#endif
}
return false;
}
void HTMLGenericFormElementImpl::defaultEventHandler(EventImpl *evt)
{
if (evt->target()==this)
{
// Report focus in/out changes to the browser extension (editable widgets only)
KHTMLPart *part = getDocument()->part();
if (evt->id()==EventImpl::DOMFOCUSIN_EVENT && isEditable() && part && m_render && m_render->isWidget()) {
KHTMLPartBrowserExtension *ext = static_cast<KHTMLPartBrowserExtension *>(part->browserExtension());
QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
if (ext)
ext->editableWidgetFocused(widget);
}
#if APPLE_CHANGES
// We don't want this default key event handling, we'll count on
// Cocoa event dispatch if the event doesn't get blocked.
#else
if (evt->id()==EventImpl::KEYDOWN_EVENT ||
evt->id()==EventImpl::KEYUP_EVENT)
{
KeyboardEventImpl * k = static_cast<KeyboardEventImpl *>(evt);
if (k->keyVal() == QChar('\n').unicode() && m_render && m_render->isWidget() && k->qKeyEvent)
QApplication::sendEvent(static_cast<RenderWidget *>(m_render)->widget(), k->qKeyEvent);
}
#endif
if (evt->id()==EventImpl::DOMFOCUSOUT_EVENT && isEditable() && part && m_render && m_render->isWidget()) {
KHTMLPartBrowserExtension *ext = static_cast<KHTMLPartBrowserExtension *>(part->browserExtension());
QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
if (ext)
ext->editableWidgetBlurred(widget);
// ### Don't count popup as a valid reason for losing the focus (example: opening the options of a select
// combobox shouldn't emit onblur)
}
}
HTMLElementImpl::defaultEventHandler(evt);
}
bool HTMLGenericFormElementImpl::isEditable()
{
return false;
}
// Special chars used to encode form state strings.
// We pick chars that are unlikely to be used in an HTML attr, so we rarely have to really encode.
const char stateSeparator = '&';
const char stateEscape = '<';
static const char stateSeparatorMarker[] = "<A";
static const char stateEscapeMarker[] = "<<";
// Encode an element name so we can put it in a state string without colliding
// with our separator char.
static QString encodedElementName(QString str)
{
int sepLoc = str.find(stateSeparator);
int escLoc = str.find(stateSeparator);
if (sepLoc >= 0 || escLoc >= 0) {
QString newStr = str;
// replace "<" with "<<"
while (escLoc >= 0) {
newStr.replace(escLoc, 1, stateEscapeMarker);
escLoc = str.find(stateSeparator, escLoc+1);
}
// replace "&" with "<A"
while (sepLoc >= 0) {
newStr.replace(sepLoc, 1, stateSeparatorMarker);
sepLoc = str.find(stateSeparator, sepLoc+1);
}
return newStr;
} else {
return str;
}
}
QString HTMLGenericFormElementImpl::state( )
{
// Build a string that contains ElementName&ElementType&
return encodedElementName(name().string()) + stateSeparator + type().string() + stateSeparator;
}
QString HTMLGenericFormElementImpl::findMatchingState(QStringList &states)
{
QString encName = encodedElementName(name().string());
QString typeStr = type().string();
for (QStringList::Iterator it = states.begin(); it != states.end(); ++it) {
QString state = *it;
int sep1 = state.find(stateSeparator);
int sep2 = state.find(stateSeparator, sep1+1);
assert(sep1 >= 0);
assert(sep2 >= 0);
QString nameAndType = state.left(sep2);
if (encName.length() + typeStr.length() + 1 == (uint)sep2
&& nameAndType.startsWith(encName)
&& nameAndType.endsWith(typeStr))
{
states.remove(it);
return state.mid(sep2+1);
}
}
return QString::null;
}
#if NOKIA_CHANGES
bool HTMLGenericFormElementImpl::rendererIsNeeded(RenderStyle *style)
{
if (getDocument()->fastDisplayMode())
return false;
return HTMLElementImpl::rendererIsNeeded(style);
}
#endif
// -------------------------------------------------------------------------
HTMLButtonElementImpl::HTMLButtonElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLGenericFormElementImpl(doc, f)
{
m_type = SUBMIT;
m_dirty = true;
m_activeSubmit = false;
}
HTMLButtonElementImpl::~HTMLButtonElementImpl()
{
}
NodeImpl::Id HTMLButtonElementImpl::id() const
{
return ID_BUTTON;
}
DOMString HTMLButtonElementImpl::type() const
{
return getAttribute(ATTR_TYPE);
}
void HTMLButtonElementImpl::parseHTMLAttribute(HTMLAttributeImpl *attr)
{
switch(attr->id())
{
case ATTR_TYPE:
if ( strcasecmp( attr->value(), "submit" ) == 0 )
m_type = SUBMIT;
else if ( strcasecmp( attr->value(), "reset" ) == 0 )
m_type = RESET;
else if ( strcasecmp( attr->value(), "button" ) == 0 )
m_type = BUTTON;
break;
case ATTR_VALUE:
m_value = attr->value();
m_currValue = m_value;
break;
case ATTR_ACCESSKEY:
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;
default:
HTMLGenericFormElementImpl::parseHTMLAttribute(attr);
}
}
void HTMLButtonElementImpl::defaultEventHandler(EventImpl *evt)
{
if (m_type != BUTTON && (evt->id() == EventImpl::DOMACTIVATE_EVENT)) {
if(m_form && m_type == SUBMIT) {
m_activeSubmit = true;
m_form->prepareSubmit();
m_activeSubmit = false; // in case we were canceled
}
if(m_form && m_type == RESET) m_form->reset();
}
HTMLGenericFormElementImpl::defaultEventHandler(evt);
}
bool HTMLButtonElementImpl::isSuccessfulSubmitButton() const
{
// HTML spec says that buttons must have names
// to be considered successful. However, other browsers
// do not impose this constraint. Therefore, we behave
// differently and can use different buttons than the
// author intended.
// Remove the name constraint for now.
// Was: m_type == SUBMIT && !m_disabled && !name().isEmpty()
return m_type == SUBMIT && !m_disabled;
}
bool HTMLButtonElementImpl::isActivatedSubmit() const
{
return m_activeSubmit;
}
void HTMLButtonElementImpl::setActivatedSubmit(bool flag)
{
m_activeSubmit = flag;
}
bool HTMLButtonElementImpl::appendFormData(FormDataList& encoding, bool /*multipart*/)
{
if (m_type != SUBMIT || name().isEmpty() || !m_activeSubmit)
return false;
encoding.appendData(name(), m_currValue);
return true;
}
void HTMLButtonElementImpl::click(bool sendMouseEvents)
{
#if APPLE_CHANGES
QWidget *widget;
if (renderer() && renderer()->isWidget() && (widget = static_cast<RenderWidget *>(renderer())->widget())) {
// using this method gives us nice Cocoa user interface feedback
static_cast<QButton *>(widget)->click(sendMouseEvents);
}
else
#endif
HTMLGenericFormElementImpl::click(sendMouseEvents);
}
void HTMLButtonElementImpl::accessKeyAction(bool sendToAnyElement)
{
// send the mouse button events iff the
// caller specified sendToAnyElement
click(sendToAnyElement);
}
// -------------------------------------------------------------------------
HTMLFieldSetElementImpl::HTMLFieldSetElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLGenericFormElementImpl(doc, f)
{
}
HTMLFieldSetElementImpl::~HTMLFieldSetElementImpl()
{
}
bool HTMLFieldSetElementImpl::isFocusable() const
{
return false;
}
NodeImpl::Id HTMLFieldSetElementImpl::id() const
{
return ID_FIELDSET;
}
DOMString HTMLFieldSetElementImpl::type() const
{
return "fieldset";
}
RenderObject* HTMLFieldSetElementImpl::createRenderer(RenderArena* arena, RenderStyle* style)
{
return new (arena) RenderFieldset(this);
}
// -------------------------------------------------------------------------
HTMLInputElementImpl::HTMLInputElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLGenericFormElementImpl(doc, f), m_imageLoader(0), m_valueMatchesRenderer(false)
{
m_type = TEXT;
m_maxLen = -1;
m_size = 20;
m_checked = false;
m_defaultChecked = false;
m_useDefaultChecked = true;
m_haveType = false;
m_activeSubmit = false;
m_autocomplete = true;
m_inited = false;
xPos = 0;
yPos = 0;
#if APPLE_CHANGES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -