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

📄 htmlselectelement.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            // If no option was clicked, then this will deselect all items in the list.            if (!shiftSelect && !multiSelect)                deselectItems(option);            // If the anchor hasn't been set, and we're doing a single selection or a shift selection, then initialize the anchor to the first selected index.            if (m_activeSelectionAnchorIndex < 0 && !multiSelect)                setActiveSelectionAnchorIndex(selectedIndex());            // Set the selection state of the clicked option            if (option && !option->disabled())                option->setSelectedState(true);                        // If there was no selectedIndex() for the previous initialization, or            // If we're doing a single selection, or a multiple selection (using cmd or ctrl), then initialize the anchor index to the listIndex that just got clicked.            if (listIndex >= 0 && (m_activeSelectionAnchorIndex < 0 || !shiftSelect))                setActiveSelectionAnchorIndex(listIndex);                        setActiveSelectionEndIndex(listIndex);            updateListBoxSelection(!multiSelect);            if (Frame* frame = document()->frame())                frame->eventHandler()->setMouseDownMayStartAutoscroll();            evt->setDefaultHandled();        }    } else if (evt->type() == eventNames().mouseupEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer())        // This makes sure we fire onChange for a single click.  For drag selection, onChange will fire when the autoscroll timer stops.        listBoxOnChange();    else if (evt->type() == eventNames().keydownEvent) {        if (!evt->isKeyboardEvent())            return;        String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier();        int endIndex = 0;                if (m_activeSelectionEndIndex < 0) {            // Initialize the end index            if (keyIdentifier == "Down")                endIndex = nextSelectableListIndex(lastSelectedListIndex());            else if (keyIdentifier == "Up")                endIndex = previousSelectableListIndex(optionToListIndex(selectedIndex()));        } else {            // Set the end index based on the current end index            if (keyIdentifier == "Down")                endIndex = nextSelectableListIndex(m_activeSelectionEndIndex);            else if (keyIdentifier == "Up")                endIndex = previousSelectableListIndex(m_activeSelectionEndIndex);            }                if (keyIdentifier == "Down" || keyIdentifier == "Up") {            // Save the selection so it can be compared to the new selection when we call onChange immediately after making the new selection.            saveLastSelection();            ASSERT(endIndex >= 0 && (unsigned)endIndex < listItems().size());             setActiveSelectionEndIndex(endIndex);                        // If the anchor is unitialized, or if we're going to deselect all other options, then set the anchor index equal to the end index.            bool deselectOthers = !multiple() || !static_cast<KeyboardEvent*>(evt)->shiftKey();            if (m_activeSelectionAnchorIndex < 0 || deselectOthers) {                m_activeSelectionState = true;                if (deselectOthers)                    deselectItems();                setActiveSelectionAnchorIndex(m_activeSelectionEndIndex);            }            static_cast<RenderListBox*>(renderer())->scrollToRevealElementAtListIndex(endIndex);            updateListBoxSelection(deselectOthers);            listBoxOnChange();            evt->setDefaultHandled();        }    } else if (evt->type() == eventNames().keypressEvent) {        if (!evt->isKeyboardEvent())            return;        int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode();        if (keyCode == '\r') {            if (form())                form()->submitClick(evt);            evt->setDefaultHandled();            return;        }    }}void HTMLSelectElement::setActiveSelectionAnchorIndex(int index){    m_activeSelectionAnchorIndex = index;        // Cache the selection state so we can restore the old selection as the new selection pivots around this anchor index    const Vector<HTMLElement*>& items = listItems();    m_cachedStateForActiveSelection.clear();    for (unsigned i = 0; i < items.size(); i++) {        if (items[i]->hasLocalName(optionTag)) {            HTMLOptionElement* option = static_cast<HTMLOptionElement*>(items[i]);            m_cachedStateForActiveSelection.append(option->selected());        } else            m_cachedStateForActiveSelection.append(false);    }}void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions){    ASSERT(renderer() && renderer()->isListBox());        unsigned start;    unsigned end;    ASSERT(m_activeSelectionAnchorIndex >= 0);    start = min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);    end = max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);    const Vector<HTMLElement*>& items = listItems();    for (unsigned i = 0; i < items.size(); i++) {        if (items[i]->hasLocalName(optionTag)) {            HTMLOptionElement* option = static_cast<HTMLOptionElement*>(items[i]);            if (!option->disabled()) {                if (i >= start && i <= end)                    option->setSelectedState(m_activeSelectionState);                else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.size())                    option->setSelectedState(false);                else                    option->setSelectedState(m_cachedStateForActiveSelection[i]);            }        }    }    scrollToSelection();}void HTMLSelectElement::menuListOnChange(){    ASSERT(usesMenuList());    int selected = selectedIndex();    if (m_lastOnChangeIndex != selected) {        m_lastOnChangeIndex = selected;        onChange();    }}void HTMLSelectElement::listBoxOnChange(){    ASSERT(!usesMenuList());    const Vector<HTMLElement*>& items = listItems();        // If the cached selection list is empty, or the size has changed, then fire onChange, and return early.    if (m_lastOnChangeSelection.isEmpty() || m_lastOnChangeSelection.size() != items.size()) {        onChange();        return;    }        // Update m_lastOnChangeSelection and fire onChange    bool fireOnChange = false;    for (unsigned i = 0; i < items.size(); i++) {        bool selected = false;        if (items[i]->hasLocalName(optionTag))            selected = static_cast<HTMLOptionElement*>(items[i])->selected();        if (selected != m_lastOnChangeSelection[i])                  fireOnChange = true;        m_lastOnChangeSelection[i] = selected;    }    if (fireOnChange)        onChange();}void HTMLSelectElement::saveLastSelection(){    const Vector<HTMLElement*>& items = listItems();    if (usesMenuList()) {        m_lastOnChangeIndex = selectedIndex();        return;    }        m_lastOnChangeSelection.clear();    for (unsigned i = 0; i < items.size(); i++) {        if (items[i]->hasLocalName(optionTag)) {            HTMLOptionElement* option = static_cast<HTMLOptionElement*>(items[i]);            m_lastOnChangeSelection.append(option->selected());        } else            m_lastOnChangeSelection.append(false);    }}static String stripLeadingWhiteSpace(const String& string){    int length = string.length();    int i;    for (i = 0; i < length; ++i)        if (string[i] != noBreakSpace &&            (string[i] <= 0x7F ? !isASCIISpace(string[i]) : (direction(string[i]) != WhiteSpaceNeutral)))            break;    return string.substring(i, length - i);}void HTMLSelectElement::typeAheadFind(KeyboardEvent* event){    if (event->timeStamp() < m_lastCharTime)        return;    DOMTimeStamp delta = event->timeStamp() - m_lastCharTime;    m_lastCharTime = event->timeStamp();    UChar c = event->charCode();    String prefix;    int searchStartOffset = 1;    if (delta > typeAheadTimeout) {        m_typedString = prefix = String(&c, 1);        m_repeatingChar = c;    } else {        m_typedString.append(c);        if (c == m_repeatingChar)            // The user is likely trying to cycle through all the items starting with this character, so just search on the character            prefix = String(&c, 1);        else {            m_repeatingChar = 0;            prefix = m_typedString;            searchStartOffset = 0;        }    }    const Vector<HTMLElement*>& items = listItems();    int itemCount = items.size();    if (itemCount < 1)        return;    int selected = selectedIndex();    int index = (optionToListIndex(selected >= 0 ? selected : 0) + searchStartOffset) % itemCount;    ASSERT(index >= 0);    for (int i = 0; i < itemCount; i++, index = (index + 1) % itemCount) {        if (!items[index]->hasTagName(optionTag) || items[index]->disabled())            continue;        String text = static_cast<HTMLOptionElement*>(items[index])->textIndentedToRespectGroupLabel();        if (stripLeadingWhiteSpace(text).startsWith(prefix, false)) {            setSelectedIndex(listToOptionIndex(index));            if(!usesMenuList())                listBoxOnChange();            setChanged();            return;        }    }}int HTMLSelectElement::nextSelectableListIndex(int startIndex){    const Vector<HTMLElement*>& items = listItems();    int index = startIndex + 1;    while (index >= 0 && (unsigned)index < items.size() && (!items[index]->hasLocalName(optionTag) || items[index]->disabled()))        index++;    if ((unsigned) index == items.size())        return startIndex;    return index;}int HTMLSelectElement::previousSelectableListIndex(int startIndex){    const Vector<HTMLElement*>& items = listItems();    if (startIndex == -1)        startIndex = items.size();    int index = startIndex - 1;    while (index >= 0 && (unsigned)index < items.size() && (!items[index]->hasLocalName(optionTag) || items[index]->disabled()))        index--;    if (index == -1)        return startIndex;    return index;}void HTMLSelectElement::accessKeyAction(bool sendToAnyElement){    focus();    dispatchSimulatedClick(0, sendToAnyElement);}void HTMLSelectElement::accessKeySetSelectedIndex(int index){        // first bring into focus the list box    if (!focused())        accessKeyAction(false);        // if this index is already selected, unselect. otherwise update the selected index    Node* listNode = item(index);    if (listNode && listNode->hasTagName(optionTag)) {        HTMLOptionElement* listElement = static_cast<HTMLOptionElement*>(listNode);        if (listElement->selected())            listElement->setSelectedState(false);        else            setSelectedIndex(index, false, true);    }        listBoxOnChange();    scrollToSelection();}    void HTMLSelectElement::setMultiple(bool multiple){    setAttribute(multipleAttr, multiple ? "" : 0);}void HTMLSelectElement::setSize(int size){    setAttribute(sizeAttr, String::number(size));}Node* HTMLSelectElement::namedItem(const AtomicString& name){    return options()->namedItem(name);}Node* HTMLSelectElement::item(unsigned index){    return options()->item(index);}void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, ExceptionCode& ec){    ec = 0;    if (index > INT_MAX)        index = INT_MAX;    int diff = index  - length();    HTMLElement* before = 0;    // out of array bounds ? first insert empty dummies    if (diff > 0) {        setLength(index, ec);        // replace an existing entry ?    } else if (diff < 0) {        before = static_cast<HTMLElement*>(options()->item(index+1));        remove(index);    }    // finally add the new element    if (!ec) {        add(option, before, ec);        if (diff >= 0 && option->selected())            setSelectedIndex(index, !m_multiple);    }}void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec){    ec = 0;    if (newLen > INT_MAX)        newLen = INT_MAX;    int diff = length() - newLen;    if (diff < 0) { // add dummy elements        do {            RefPtr<Element> option = document()->createElement(optionTag, false);            ASSERT(option);            add(static_cast<HTMLElement*>(option.get()), 0, ec);            if (ec)                break;        } while (++diff);    }    else // remove elements        while (diff-- > 0)            remove(newLen);}void HTMLSelectElement::scrollToSelection(){    if (renderer() && !usesMenuList())        static_cast<RenderListBox*>(renderer())->selectionChanged();}#ifndef NDEBUGvoid HTMLSelectElement::checkListItems() const{    Vector<HTMLElement*> items = m_listItems;    recalcListItems(false);    ASSERT(items == m_listItems);}#endif} // namespace

⌨️ 快捷键说明

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