⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htmlselectelement.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{    if (renderer())        return isFocusable();    return HTMLFormControlElementWithState::isKeyboardFocusable(event);}bool HTMLSelectElement::isMouseFocusable() const{    if (renderer())        return isFocusable();    return HTMLFormControlElementWithState::isMouseFocusable();}bool HTMLSelectElement::canSelectAll() const{    return !usesMenuList(); }void HTMLSelectElement::selectAll(){    ASSERT(!usesMenuList());    if (!renderer() || !multiple())        return;        // Save the selection so it can be compared to the new selectAll selection when we call onChange    saveLastSelection();        m_activeSelectionState = true;    setActiveSelectionAnchorIndex(nextSelectableListIndex(-1));    setActiveSelectionEndIndex(previousSelectableListIndex(-1));        updateListBoxSelection(false);    listBoxOnChange();}RenderObject* HTMLSelectElement::createRenderer(RenderArena* arena, RenderStyle*){    if (usesMenuList())        return new (arena) RenderMenuList(this);    return new (arena) RenderListBox(this);}bool HTMLSelectElement::appendFormData(FormDataList& list, bool){    if (name().isEmpty())        return false;    bool successful = false;    const Vector<HTMLElement*>& items = listItems();    unsigned i;    for (i = 0; i < items.size(); i++) {        if (items[i]->hasLocalName(optionTag)) {            HTMLOptionElement *option = static_cast<HTMLOptionElement*>(items[i]);            if (option->selected()) {                list.appendData(name(), option->value());                successful = true;            }        }    }    // ### this case should not happen. make sure that we select the first option    // in any case. otherwise we have no consistency with the DOM interface. FIXME!    // we return the first one if it was a combobox select    if (!successful && !m_multiple && m_size <= 1 && items.size() &&        (items[0]->hasLocalName(optionTag))) {        HTMLOptionElement *option = static_cast<HTMLOptionElement*>(items[0]);        if (option->value().isNull())            list.appendData(name(), option->text().stripWhiteSpace());        else            list.appendData(name(), option->value());        successful = true;    }    return successful;}int HTMLSelectElement::optionToListIndex(int optionIndex) const{    const Vector<HTMLElement*>& items = listItems();    int listSize = (int)items.size();    if (optionIndex < 0 || optionIndex >= listSize)        return -1;    int optionIndex2 = -1;    for (int listIndex = 0; listIndex < listSize; listIndex++) {        if (items[listIndex]->hasLocalName(optionTag)) {            optionIndex2++;            if (optionIndex2 == optionIndex)                return listIndex;        }    }    return -1;}int HTMLSelectElement::listToOptionIndex(int listIndex) const{    const Vector<HTMLElement*>& items = listItems();    if (listIndex < 0 || listIndex >= int(items.size()) ||        !items[listIndex]->hasLocalName(optionTag))        return -1;    int optionIndex = 0; // actual index of option not counting OPTGROUP entries that may be in list    for (int i = 0; i < listIndex; i++)        if (items[i]->hasLocalName(optionTag))            optionIndex++;    return optionIndex;}PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options(){    return HTMLOptionsCollection::create(this);}void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const{    m_listItems.clear();    HTMLOptionElement* foundSelected = 0;    for (Node* current = firstChild(); current; current = current->traverseNextSibling(this)) {        if (current->hasTagName(optgroupTag) && current->firstChild()) {            // FIXME: It doesn't make sense to add an optgroup to the list items,            // when it has children, but not to add it if it happens to have,            // children (say some comment nodes or text nodes), yet that's what            // this code does!            m_listItems.append(static_cast<HTMLElement*>(current));            current = current->firstChild();            // FIXME: It doesn't make sense to handle an <optgroup> inside another <optgroup>            // if it's not the first child, but not handle it if it happens to be the first            // child, yet that's what this code does!        }        if (current->hasTagName(optionTag)) {            m_listItems.append(static_cast<HTMLElement*>(current));            if (updateSelectedStates) {                if (!foundSelected && (usesMenuList() || (!m_multiple && static_cast<HTMLOptionElement*>(current)->selected()))) {                    foundSelected = static_cast<HTMLOptionElement*>(current);                    foundSelected->setSelectedState(true);                } else if (foundSelected && !m_multiple && static_cast<HTMLOptionElement*>(current)->selected()) {                    foundSelected->setSelectedState(false);                    foundSelected = static_cast<HTMLOptionElement*>(current);                }            }        }        if (current->hasTagName(hrTag))            m_listItems.append(static_cast<HTMLElement*>(current));    }    m_recalcListItems = false;}void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta){    setRecalcListItems();    HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);        if (AXObjectCache::accessibilityEnabled() && renderer())        renderer()->document()->axObjectCache()->childrenChanged(renderer());}void HTMLSelectElement::setRecalcListItems(){    m_recalcListItems = true;    if (renderer()) {        if (usesMenuList())            static_cast<RenderMenuList*>(renderer())->setOptionsChanged(true);        else            static_cast<RenderListBox*>(renderer())->setOptionsChanged(true);    }    if (!inDocument())        m_collectionInfo.reset();    setChanged();}void HTMLSelectElement::reset(){    bool optionSelected = false;    HTMLOptionElement* firstOption = 0;    const Vector<HTMLElement*>& items = listItems();    unsigned i;    for (i = 0; i < items.size(); i++) {        if (items[i]->hasLocalName(optionTag)) {            HTMLOptionElement *option = static_cast<HTMLOptionElement*>(items[i]);            if (!option->getAttribute(selectedAttr).isNull()) {                option->setSelectedState(true);                optionSelected = true;            } else                option->setSelectedState(false);            if (!firstOption)                firstOption = option;        }    }    if (!optionSelected && firstOption && usesMenuList())        firstOption->setSelectedState(true);        setChanged();}void HTMLSelectElement::dispatchFocusEvent(){    if (usesMenuList())        // Save the selection so it can be compared to the new selection when we call onChange during dispatchBlurEvent.        saveLastSelection();    HTMLFormControlElementWithState::dispatchFocusEvent();}void HTMLSelectElement::dispatchBlurEvent(){    // We only need to fire onChange here for menu lists, because we fire onChange for list boxes whenever the selection change is actually made.    // This matches other browsers' behavior.    if (usesMenuList())        menuListOnChange();    HTMLFormControlElementWithState::dispatchBlurEvent();}void HTMLSelectElement::defaultEventHandler(Event* evt){    if (!renderer())        return;        if (usesMenuList())        menuListDefaultEventHandler(evt);    else         listBoxDefaultEventHandler(evt);        if (evt->defaultHandled())        return;    if (evt->type() == eventNames().keypressEvent && evt->isKeyboardEvent()) {        KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(evt);            if (!keyboardEvent->ctrlKey() && !keyboardEvent->altKey() && !keyboardEvent->metaKey() &&            isPrintableChar(keyboardEvent->charCode())) {            typeAheadFind(keyboardEvent);            evt->setDefaultHandled();            return;        }    }    HTMLFormControlElementWithState::defaultEventHandler(evt);}void HTMLSelectElement::menuListDefaultEventHandler(Event* evt){    if (evt->type() == eventNames().keydownEvent) {        if (!renderer() || !evt->isKeyboardEvent())            return;        String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier();        bool handled = false;#if ARROW_KEYS_POP_MENU        if (keyIdentifier == "Down" || keyIdentifier == "Up") {            focus();            // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,            // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.            saveLastSelection();            if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer()))                menuList->showPopup();            handled = true;        }#else        int listIndex = optionToListIndex(selectedIndex());        if (keyIdentifier == "Down" || keyIdentifier == "Right") {            int size = listItems().size();            for (listIndex += 1;                 listIndex >= 0 && listIndex < size && (listItems()[listIndex]->disabled() || !listItems()[listIndex]->hasTagName(optionTag));                 ++listIndex) { }                        if (listIndex >= 0 && listIndex < size)                setSelectedIndex(listToOptionIndex(listIndex));            handled = true;        } else if (keyIdentifier == "Up" || keyIdentifier == "Left") {            int size = listItems().size();            for (listIndex -= 1;                 listIndex >= 0 && listIndex < size && (listItems()[listIndex]->disabled() || !listItems()[listIndex]->hasTagName(optionTag));                 --listIndex) { }                        if (listIndex >= 0 && listIndex < size)                setSelectedIndex(listToOptionIndex(listIndex));            handled = true;        }#endif        if (handled)            evt->setDefaultHandled();    }    // Use key press event here since sending simulated mouse events    // on key down blocks the proper sending of the key press event.    if (evt->type() == eventNames().keypressEvent) {        if (!renderer() || !evt->isKeyboardEvent())            return;        int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode();        bool handled = false;#if ARROW_KEYS_POP_MENU        if (keyCode == ' ') {            focus();            // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,            // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.            saveLastSelection();            if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer()))                menuList->showPopup();            handled = true;        }        if (keyCode == '\r') {            menuListOnChange();            if (form())                form()->submitClick(evt);            handled = true;        }#else        int listIndex = optionToListIndex(selectedIndex());        if (keyCode == '\r') {            // listIndex should already be selected, but this will fire the onchange handler.            setSelectedIndex(listToOptionIndex(listIndex), true, true);            handled = true;        }#endif        if (handled)            evt->setDefaultHandled();    }    if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {        focus();        if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer())) {            if (menuList->popupIsVisible())                menuList->hidePopup();            else {                // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,                // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.                saveLastSelection();                menuList->showPopup();            }        }        evt->setDefaultHandled();    }}void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt){    if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {        focus();        // Convert to coords relative to the list box if needed.        MouseEvent* mouseEvent = static_cast<MouseEvent*>(evt);        int offsetX = mouseEvent->offsetX();        int offsetY = mouseEvent->offsetY();        Node* target = evt->target()->toNode();        if (target != this) {            FloatPoint absPos = renderer()->absoluteToLocal(FloatPoint(offsetX, offsetY), false, true);            offsetX = absPos.x();            offsetY = absPos.y();        }        int listIndex = static_cast<RenderListBox*>(renderer())->listIndexAtOffset(offsetX, offsetY);        if (listIndex >= 0) {            // Save the selection so it can be compared to the new selection when we call onChange during mouseup, or after autoscroll finishes.            saveLastSelection();            m_activeSelectionState = true;                        bool multiSelectKeyPressed = false;#if PLATFORM(MAC)            multiSelectKeyPressed = mouseEvent->metaKey();#else            multiSelectKeyPressed = mouseEvent->ctrlKey();#endif            bool shiftSelect = multiple() && mouseEvent->shiftKey();            bool multiSelect = multiple() && multiSelectKeyPressed && !mouseEvent->shiftKey();                        HTMLElement* clickedElement = listItems()[listIndex];                        HTMLOptionElement* option = 0;            if (clickedElement->hasLocalName(optionTag)) {                option = static_cast<HTMLOptionElement*>(clickedElement);                                // Keep track of whether an active selection (like during drag selection), should select or deselect                if (option->selected() && multiSelectKeyPressed)                    m_activeSelectionState = false;                if (!m_activeSelectionState)                    option->setSelectedState(false);            }                        // If we're not in any special multiple selection mode, then deselect all other items, excluding the clicked option.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -