int TypeAhead::handleEvent(KeyboardEvent* event, MatchModeFlags matchMode)
{
    if (event->timeStamp() < m_lastTypeTime)
        return -1;

    int optionCount = m_dataSource->optionCount();
    DOMTimeStamp delta = event->timeStamp() - m_lastTypeTime;
    m_lastTypeTime = event->timeStamp();

    UChar c = event->charCode();

    if (delta > typeAheadTimeout)
        m_buffer.clear();
    m_buffer.append(c);

    if (optionCount < 1)
        return -1;

    int searchStartOffset = 1;
    String prefix;
    if (matchMode & CycleFirstChar && 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);
        m_repeatingChar = c;
    } else if (matchMode & MatchPrefix) {
        prefix = m_buffer.toString();
        if (m_buffer.length() > 1) {
            m_repeatingChar = 0;
            searchStartOffset = 0;
        } else
            m_repeatingChar = c;
    }

    if (!prefix.isEmpty()) {
        int selected = m_dataSource->indexOfSelectedOption();
        int index = (selected < 0 ? 0 : selected) + searchStartOffset;
        index %= optionCount;

        // Compute a case-folded copy of the prefix string before beginning the search for
        // a matching element. This code uses foldCase to work around the fact that
        // String::startWith does not fold non-ASCII characters. This code can be changed
        // to use startWith once that is fixed.
        String prefixWithCaseFolded(prefix.foldCase());
        for (int i = 0; i < optionCount; ++i, index = (index + 1) % optionCount) {
            // Fold the option string and check if its prefix is equal to the folded prefix.
            String text = m_dataSource->optionAtIndex(index);
            if (stripLeadingWhiteSpace(text).foldCase().startsWith(prefixWithCaseFolded))
                return index;
        }
    }

    if (matchMode & MatchIndex) {
        bool ok = false;
        int index = m_buffer.toString().toInt(&ok);
        if (index > 0 && index <= optionCount)
            return index - 1;
    }
    return -1;
}
Пример #2
0
void SelectElement::typeAheadFind(SelectElementData& data, Element* element, KeyboardEvent* event)
{
    if (event->timeStamp() < data.lastCharTime())
        return;

    DOMTimeStamp delta = event->timeStamp() - data.lastCharTime();
    data.setLastCharTime(event->timeStamp());

    UChar c = event->charCode();

    String prefix;
    int searchStartOffset = 1;
    if (delta > typeAheadTimeout) {
        prefix = String(&c, 1);
        data.setTypedString(prefix);
        data.setRepeatingChar(c);
    } else {
        data.typedString().append(c);

        if (c == data.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 {
            data.setRepeatingChar(0);
            prefix = data.typedString();
            searchStartOffset = 0;
        }
    }

    const Vector<Element*>& items = data.listItems(element);
    int itemCount = items.size();
    if (itemCount < 1)
        return;

    int selected = selectedIndex(data, element);
    int index = (optionToListIndex(data, element, selected >= 0 ? selected : 0) + searchStartOffset) % itemCount;
    ASSERT(index >= 0);

    for (int i = 0; i < itemCount; ++i, index = (index + 1) % itemCount) {
        OptionElement* optionElement = toOptionElement(items[index]);
        if (!optionElement || items[index]->disabled())
            continue;

        String text = optionElement->textIndentedToRespectGroupLabel();
        if (stripLeadingWhiteSpace(text).startsWith(prefix, false)) {
            setSelectedIndex(data, element, listToOptionIndex(data, element, index));
            if (!data.usesMenuList())
                listBoxOnChange(data, element);
            element->setNeedsStyleRecalc();
            return;
        }
    }
}
Пример #3
0
    /**
     * Collapses all white space in a string.
     * All occurances of tab, line feed and carriage return are replaced with
     * space, after which all sequences of spaces are collapsed to a single space.
     * 
     * @param value The string to have all white space collapsed
     * @return AxisString The string with all white space collapsed.
     */
    const AxisString& WhiteSpace::collapseWhiteSpace(AxisString& value)
    {
	#ifdef ENABLE_AXISTRACE
		if (axiscpp::AxisTrace::isTraceOn())
			axiscpp::AxisTrace::traceEntry("WhiteSpace", "collapseWhiteSpace", this, 1,
					TRACETYPE_STLSTRING, 0, ((void*)&value));	  /* AUTOINSERTED TRACE */
	#endif

        if (value.empty ())
        {
            	{
		#ifdef ENABLE_AXISTRACE
			const AxisString& traceRet = (value);
			if (axiscpp::AxisTrace::isTraceOn())
				axiscpp::AxisTrace::traceExit("WhiteSpace", "collapseWhiteSpace", this, 1,
					TRACETYPE_STLSTRING, 0, ((void*)&traceRet));	  /* AUTOINSERTED TRACE */
			return traceRet;
		#else
			return value;
		#endif
	}

        }
        AxisString replacedValue = replaceWhiteSpace(value);
        /*
         * Strip leading and trailing space
         */
        AxisString leadingStripped = stripLeadingWhiteSpace(replacedValue);
        replacedValue = stripTrailingWhiteSpace(leadingStripped);
        // Initialize return value to empty string
        m_strReturnVal = "";
        /*
         * Find space character and returns the first any of chars find
         * position
         */ 
        unsigned long nPos = replacedValue.find_first_of (' ');
    
        /* Check for position validity */
        if (AxisString::npos == nPos)
        {
            m_strReturnVal.assign (replacedValue);
            	{
		#ifdef ENABLE_AXISTRACE
			const AxisString& traceRet = (m_strReturnVal);
			if (axiscpp::AxisTrace::isTraceOn())
				axiscpp::AxisTrace::traceExit("WhiteSpace", "collapseWhiteSpace", this, 2,
					TRACETYPE_STLSTRING, 0, ((void*)&traceRet));	  /* AUTOINSERTED TRACE */
			return traceRet;
		#else
			return m_strReturnVal;
		#endif
	}

        }
    
        unsigned long nOldIdx = 0;            // Counter value
        while (AxisString::npos != nPos)
        {
            m_strReturnVal.append (replacedValue.substr (nOldIdx, nPos - nOldIdx));
            /**
             * Only copy space character across if it's NOT followed by             
             * another space character
             */
            if ( replacedValue.at(nPos+1) != ' ')
            {
               m_strReturnVal.append (" ");
            }
            nOldIdx = ++nPos;     // Get old position
            /* 
             * Find the next entity reference characters from previous found 
             * position,
             */ 
            nPos = replacedValue.find_first_of (' ', nPos);
        }
    
        unsigned long nDataLen = replacedValue.length ();    // Get the length of the field value
        unsigned long nLen = nDataLen - nOldIdx;      // Get remaining number of characters   
        if (nLen > 0)
        {
            /*
             * Append the remaining data
             */
            m_strReturnVal += replacedValue.substr (nOldIdx, nLen); 
        }
        	{
		#ifdef ENABLE_AXISTRACE
			const AxisString& traceRet = (m_strReturnVal);
			if (axiscpp::AxisTrace::isTraceOn())
				axiscpp::AxisTrace::traceExit("WhiteSpace", "collapseWhiteSpace", this, 3,
					TRACETYPE_STLSTRING, 0, ((void*)&traceRet));	  /* AUTOINSERTED TRACE */
			return traceRet;
		#else
			return m_strReturnVal;
		#endif
	}

    }