String HTMLFormControlElement::nameForAutofill() const
{
    String fullName = name();
    String trimmedName = fullName.stripWhiteSpace();
    if (!trimmedName.isEmpty())
        return trimmedName;
    fullName = getIdAttribute();
    trimmedName = fullName.stripWhiteSpace();
    return trimmedName;
}
Example #2
0
bool ScriptElement::isScriptForEventSupported() const
{
    String eventAttribute = eventAttributeValue();
    String forAttribute = forAttributeValue();
    if (!eventAttribute.isEmpty() && !forAttribute.isEmpty()) {
        forAttribute = forAttribute.stripWhiteSpace();
        if (!equalIgnoringCase(forAttribute, "window"))
            return false;

        eventAttribute = eventAttribute.stripWhiteSpace();
        if (!equalIgnoringCase(eventAttribute, "onload") && !equalIgnoringCase(eventAttribute, "onload()"))
            return false;
    }
    return true;
}
ContentDispositionType contentDispositionType(const String& contentDisposition)
{
    if (contentDisposition.isEmpty())
        return ContentDispositionNone;

    Vector<String> parameters;
    contentDisposition.split(';', parameters);

    if (parameters.isEmpty())
        return ContentDispositionNone;

    String dispositionType = parameters[0];
    dispositionType.stripWhiteSpace();

    if (equalIgnoringCase(dispositionType, "inline"))
        return ContentDispositionInline;

    // Some broken sites just send bogus headers like
    //
    //   Content-Disposition: ; filename="file"
    //   Content-Disposition: filename="file"
    //   Content-Disposition: name="file"
    //
    // without a disposition token... screen those out.
    if (!isValidHTTPToken(dispositionType))
        return ContentDispositionNone;

    // We have a content-disposition of "attachment" or unknown.
    // RFC 2183, section 2.8 says that an unknown disposition
    // value should be treated as "attachment"
    return ContentDispositionAttachment;
}
SMILTime SVGSMILElement::parseClockValue(const String& data)
{
    if (data.isNull())
        return SMILTime::unresolved();

    String parse = data.stripWhiteSpace();

    DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite"));
    if (parse == indefiniteValue)
        return SMILTime::indefinite();

    double result = 0;
    bool ok;
    size_t doublePointOne = parse.find(':');
    size_t doublePointTwo = parse.find(':', doublePointOne + 1);
    if (doublePointOne == 2 && doublePointTwo == 5 && parse.length() >= 8) {
        result += parse.substring(0, 2).toUIntStrict(&ok) * 60 * 60;
        if (!ok)
            return SMILTime::unresolved();
        result += parse.substring(3, 2).toUIntStrict(&ok) * 60;
        if (!ok)
            return SMILTime::unresolved();
        result += parse.substring(6).toDouble(&ok);
    } else if (doublePointOne == 2 && doublePointTwo == kNotFound && parse.length() >= 5) {
        result += parse.substring(0, 2).toUIntStrict(&ok) * 60;
        if (!ok)
            return SMILTime::unresolved();
        result += parse.substring(3).toDouble(&ok);
    } else
        return parseOffsetValue(parse);

    if (!ok || !SMILTime(result).isFinite())
        return SMILTime::unresolved();
    return result;
}
Example #5
0
String NumberLocalizer::convertFromLocalizedNumber(const String& localized)
{
    initializeNumberLocalizerData();
    String input = localized.stripWhiteSpace();
    if (!m_hasNumberLocalizerData || input.isEmpty())
        return input;

    bool isNegative;
    unsigned startIndex;
    unsigned endIndex;
    if (!detectSignAndGetDigitRange(input, isNegative, startIndex, endIndex)) {
        // Input is broken. Returning an invalid number string.
        return "*";
    }

    StringBuilder builder;
    builder.reserveCapacity(input.length());
    if (isNegative)
        builder.append("-");
    for (unsigned i = startIndex; i < endIndex;) {
        unsigned symbolIndex = matchedDecimalSymbolIndex(input, i);
        if (symbolIndex >= DecimalSymbolsSize)
            return "*";
        if (symbolIndex == DecimalSeparatorIndex)
            builder.append('.');
        else if (symbolIndex == GroupSeparatorIndex) {
            // Ignore group separators.

        } else
            builder.append(static_cast<UChar>('0' + symbolIndex));
    }
    return builder.toString();
}
Example #6
0
void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, const Element& element, const Attribute& attribute)
{
    ASSERT(element.isURLAttribute(attribute));
    const String resolvedURLString = resolveURLIfNeeded(element, attribute.value());
    UChar quoteChar = '"';
    String strippedURLString = resolvedURLString.stripWhiteSpace();
    if (protocolIsJavaScript(strippedURLString)) {
        // minimal escaping for javascript urls
        if (strippedURLString.contains('"')) {
            if (strippedURLString.contains('\''))
                strippedURLString.replaceWithLiteral('"', "&quot;");
            else
                quoteChar = '\'';
        }
        result.append(quoteChar);
        result.append(strippedURLString);
        result.append(quoteChar);
        return;
    }

    // FIXME: This does not fully match other browsers. Firefox percent-escapes non-ASCII characters for innerHTML.
    result.append(quoteChar);
    appendAttributeValue(result, resolvedURLString, false);
    result.append(quoteChar);
}
Example #7
0
String HTMLOptionElement::label() const
{
    String label = attributeWithoutSynchronization(labelAttr);
    if (!label.isNull())
        return label.stripWhiteSpace(isHTMLSpace);
    return collectOptionInnerText().stripWhiteSpace(isHTMLSpace).simplifyWhiteSpace(isHTMLSpace);
}
Example #8
0
Optional<ScriptElement::ScriptType> ScriptElement::determineScriptType(LegacyTypeSupport supportLegacyTypes) const
{
    // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used here to maintain backwards compatibility with existing layout tests. The specific violations are:
    // - Allowing type=javascript. type= should only support MIME types, such as text/javascript.
    // - Allowing a different set of languages for language= and type=. language= supports Javascript 1.1 and 1.4-1.6, but type= does not.
    String type = typeAttributeValue();
    String language = languageAttributeValue();
    if (type.isEmpty()) {
        if (language.isEmpty())
            return ScriptType::Classic; // Assume text/javascript.
        if (MIMETypeRegistry::isSupportedJavaScriptMIMEType("text/" + language))
            return ScriptType::Classic;
        if (isLegacySupportedJavaScriptLanguage(language))
            return ScriptType::Classic;
        return Nullopt;
    }
    if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace()))
        return ScriptType::Classic;
    if (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))
        return ScriptType::Classic;
#if ENABLE(ES6_MODULES)
    // https://html.spec.whatwg.org/multipage/scripting.html#attr-script-type
    // Setting the attribute to an ASCII case-insensitive match for the string "module" means that the script is a module script.
    if (equalLettersIgnoringASCIICase(type, "module"))
        return ScriptType::Module;
#endif
    return Nullopt;
}
Example #9
0
String HTMLOptionElement::label() const
{
    String label = fastGetAttribute(labelAttr);
    if (!label.isNull())
        return label.stripWhiteSpace(isHTMLSpace);
    return collectOptionInnerText().stripWhiteSpace(isHTMLSpace).simplifyWhiteSpace(isHTMLSpace);
}
bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url)
{
    unsigned len = refresh.length();
    unsigned pos = 0;

    if (!skipWhiteSpace(refresh, pos, fromHttpEquivMeta))
        return false;

    while (pos != len && refresh[pos] != ',' && refresh[pos] != ';')
        ++pos;

    if (pos == len) { // no URL
        url = String();
        bool ok;
        delay = refresh.stripWhiteSpace().toDouble(&ok);
        return ok;
    } else {
        bool ok;
        delay = refresh.left(pos).stripWhiteSpace().toDouble(&ok);
        if (!ok)
            return false;

        ++pos;
        skipWhiteSpace(refresh, pos, fromHttpEquivMeta);
        unsigned urlStartPos = pos;
        if (refresh.find("url", urlStartPos, TextCaseInsensitive) == urlStartPos) {
            urlStartPos += 3;
            skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
            if (refresh[urlStartPos] == '=') {
                ++urlStartPos;
                skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
            } else {
                urlStartPos = pos; // e.g. "Refresh: 0; url.html"
            }
        }

        unsigned urlEndPos = len;

        if (refresh[urlStartPos] == '"' || refresh[urlStartPos] == '\'') {
            UChar quotationMark = refresh[urlStartPos];
            urlStartPos++;
            while (urlEndPos > urlStartPos) {
                urlEndPos--;
                if (refresh[urlEndPos] == quotationMark)
                    break;
            }

            // https://bugs.webkit.org/show_bug.cgi?id=27868
            // Sometimes there is no closing quote for the end of the URL even though there was an opening quote.
            // If we looped over the entire alleged URL string back to the opening quote, just go ahead and use everything
            // after the opening quote instead.
            if (urlEndPos == urlStartPos)
                urlEndPos = len;
        }

        url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhiteSpace();
        return true;
    }
}
Example #11
0
Color SVGColor::colorFromRGBColorString(const String& colorString)
{
    // FIXME: Rework css parser so it is more SVG aware.
    RGBA32 color;
    if (CSSParser::parseColor(color, colorString.stripWhiteSpace()))
        return color;
    return Color();
}
Example #12
0
StyleColor BisonCSSParser::colorFromRGBColorString(const String& colorString)
{
    // FIXME: Rework css parser so it is more SVG aware.
    RGBA32 color;
    if (parseColor(color, colorString.stripWhiteSpace()))
        return StyleColor(color);
    // FIXME: This branch catches the string currentColor, but we should error if we have an illegal color value.
    return StyleColor::currentColor();
}
Example #13
0
Color SVGColor::colorFromRGBColorString(const String& colorString)
{
    String s = colorString.stripWhiteSpace();
    // FIXME: rework css parser so it is more svg aware
    RGBA32 color;
    if (CSSParser::parseColor(color, s))
        return color;
    return Color();
}
Example #14
0
bool DOMCSSNamespace::supports(const String& property, const String& value)
{
    CSSPropertyID propertyID = cssPropertyID(property.stripWhiteSpace());

    if (propertyID == CSSPropertyInvalid)
        return false;

    // CSSParser::parseValue() won't work correctly if !important is present,
    // so just get rid of it. It doesn't matter to supports() if it's actually
    // there or not, provided how it's specified in the value is correct.
    String normalizedValue = value.stripWhiteSpace().simplifyWhiteSpace();
    normalizedValue = valueWithoutImportant(normalizedValue);

    if (normalizedValue.isEmpty())
        return false;

    auto dummyStyle = MutableStyleProperties::create();
    return CSSParser::parseValue(dummyStyle, propertyID, normalizedValue, false, CSSStrictMode, nullptr) != CSSParser::ParseResult::Error;
}
Example #15
0
String OptionElement::collectOptionLabelOrText(const OptionElementData& data, const Element* element)
{
    Document& document = element->document();
    String text;
    // WinIE does not use the label attribute, so as a quirk, we ignore it.
    if (document.inQuirksMode())
        text = data.label();
    if (text.isEmpty())
        text = collectOptionInnerText(element);
    return text.stripWhiteSpace().simplifyWhiteSpace();
}
Example #16
0
String OptionElement::normalizeText(const Document* document, const String& src)
{
    String text = document->displayStringModifiedByEncoding(src);

    // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
    text = text.stripWhiteSpace();

    // We want to collapse our whitespace too.  This will match other browsers.
    text = text.simplifyWhiteSpace();
    return text;
}
Example #17
0
bool ResourceResponse::isAttachment() const
{
    updateResourceResponse();

    String value = m_httpHeaderFields.get("Content-Disposition");
    int loc = value.find(';');
    if (loc != -1)
        value = value.left(loc);
    value = value.stripWhiteSpace();
    return equalIgnoringCase(value, "attachment");
}
Example #18
0
String HTMLOptGroupElement::groupLabelText() const
{
    String itemText = document()->displayStringModifiedByEncoding(getAttribute(labelAttr));
    
    // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
    itemText = itemText.stripWhiteSpace();
    // We want to collapse our whitespace too.  This will match other browsers.
    itemText = itemText.simplifyWhiteSpace();
        
    return itemText;
}
Example #19
0
Color SVGColor::colorFromRGBColorString(const String& colorString)
{
    // FIXME: Rename to parseSVGColor? There's already a parseSVGColor in the CSS parser. How is it different?
    // FIXME: Rework CSS parser so it exactly matches what the SVG specification requires?
    // FIXME: Move this out of the SVGColor class?
    // FIXME: Is it really OK to do stripWhitespace here instead of stripLeadingAndTrailingHTMLSpaces?
    RGBA32 color;
    if (CSSParser::parseColor(color, colorString.stripWhiteSpace()))
        return color;
    return Color();
}
Example #20
0
String HTMLOptGroupElement::groupLabelText() const
{
    String itemText = getAttribute(labelAttr);
    
    itemText.replace('\\', document()->backslashAsCurrencySymbol());
    // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
    itemText = itemText.stripWhiteSpace();
    // We want to collapse our whitespace too.  This will match other browsers.
    itemText = itemText.simplifyWhiteSpace();
        
    return itemText;
}
Example #21
0
bool DOMWindowCSS::supports(const String& property, const String& value) const
{
    CSSPropertyID propertyID = cssPropertyID(property.stripWhiteSpace());
    if (propertyID == CSSPropertyInvalid)
        return false;

    if (!RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID))
        return false;

    // CSSParser::parseValue() won't work correctly if !important is present,
    // so just get rid of it. It doesn't matter to supports() if it's actually
    // there or not, provided how it's specified in the value is correct.
    String normalizedValue = value.stripWhiteSpace().simplifyWhiteSpace();
    normalizedValue = valueWithoutImportant(normalizedValue);

    if (normalizedValue.isEmpty())
        return false;

    RefPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
    return CSSParser::parseValue(dummyStyle.get(), propertyID, normalizedValue, false, CSSStrictMode, 0);
}
static String truncatedStringForLookupMenuItem(const String& original)
{
    if (original.isEmpty())
        return original;
    
    // Truncate the string if it's too long. This is in consistency with AppKit.
    unsigned maxNumberOfGraphemeClustersInLookupMenuItem = 24;
    DEFINE_STATIC_LOCAL(String, ellipsis, (&horizontalEllipsis, 1));
    
    String trimmed = original.stripWhiteSpace();
    unsigned numberOfCharacters = numCharactersInGraphemeClusters(trimmed, maxNumberOfGraphemeClustersInLookupMenuItem);
    return numberOfCharacters == trimmed.length() ? trimmed : trimmed.left(numberOfCharacters) + ellipsis;
}
void LayoutMenuList::setTextFromOption(int optionIndex)
{
    HTMLSelectElement* select = selectElement();
    const HeapVector<Member<HTMLElement>>& listItems = select->listItems();
    const int size = listItems.size();

    String text = emptyString();
    m_optionStyle.clear();

    if (selectElement()->multiple()) {
        unsigned selectedCount = 0;
        int firstSelectedIndex = -1;
        for (int i = 0; i < size; ++i) {
            Element* element = listItems[i];
            if (!isHTMLOptionElement(*element))
                continue;

            if (toHTMLOptionElement(element)->selected()) {
                if (++selectedCount == 1)
                    firstSelectedIndex = i;
            }
        }

        if (selectedCount == 1) {
            ASSERT(0 <= firstSelectedIndex);
            ASSERT(firstSelectedIndex < size);
            HTMLOptionElement* selectedOptionElement = toHTMLOptionElement(listItems[firstSelectedIndex]);
            ASSERT(selectedOptionElement->selected());
            text = selectedOptionElement->textIndentedToRespectGroupLabel();
            m_optionStyle = selectedOptionElement->mutableComputedStyle();
        } else {
            Locale& locale = select->locale();
            String localizedNumberString = locale.convertToLocalizedNumber(String::number(selectedCount));
            text = locale.queryString(WebLocalizedString::SelectMenuListText, localizedNumberString);
            ASSERT(!m_optionStyle);
        }
    } else {
        const int i = select->optionToListIndex(optionIndex);
        if (i >= 0 && i < size) {
            Element* element = listItems[i];
            if (isHTMLOptionElement(*element)) {
                text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
                m_optionStyle = element->mutableComputedStyle();
            }
        }
    }

    setText(text.stripWhiteSpace());

    didUpdateActiveOption(optionIndex);
}
Example #24
0
MIMEHeader::Encoding MIMEHeader::parseContentTransferEncoding(const String& text)
{
    String encoding = text.stripWhiteSpace().lower();
    if (encoding == "base64")
        return Base64;
    if (encoding == "quoted-printable")
        return QuotedPrintable;
    if (encoding == "7bit")
        return SevenBit;
    if (encoding == "binary")
        return Binary;
    LOG_ERROR("Unknown encoding '%s' found in MIME header.", text.ascii().data());
    return Unknown;
}
void WebContextMenuClient::searchWithGoogle(const Frame* frame)
{
    String searchString = frame->editor().selectedText();
    searchString.stripWhiteSpace();
    String encoded = encodeWithURLEscapeSequences(searchString);
    encoded.replace("%20", "+");

    String url = "http://www.google.com/search?q=" + encoded + "&ie=UTF-8&oe=UTF-8";

    if (Page* page = frame->page()) {
        UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
        page->mainFrame().loader().urlSelected(URL(ParsedURLString, url), String(), 0, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
    }
}
Example #26
0
static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
{
    String qType = type.stripWhiteSpace().lower();

    // two special cases for IE compatibility
    if (qType == "text" || qType == "text/plain" || qType.startsWith("text/plain;"))
        return ClipboardDataTypeText;
    if (qType == "url" || qType == "text/uri-list")
        return ClipboardDataTypeURL;
    if (qType == "text/html")
        return ClipboardDataTypeTextHTML;

    return ClipboardDataTypeNone;
}
void WebContextMenuClient::searchWithGoogle(const Frame* frame)
{
    String searchString = frame->selectedText();
    searchString.stripWhiteSpace();
    String encoded = encodeWithURLEscapeSequences(searchString);
    encoded.replace("%20", "+");

    String url("http://www.google.com/search?q=");
    url.append(encoded);
    url.append("&ie=UTF-8&oe=UTF-8");

    ResourceRequest request = ResourceRequest(url);
    if (Page* page = frame->page())
        page->mainFrame()->loader()->urlSelected(request, String(), 0, false, false, true);
}
void WebContextMenuClient::searchWithGoogle(const Frame* frame)
{
    String searchString = frame->editor().selectedText();
    searchString.stripWhiteSpace();
    String encoded = encodeWithURLEscapeSequences(searchString);
    encoded.replace("%20", "+");

    String url("http://www.google.com/search?q=");
    url.append(encoded);
    url.append("&ie=UTF-8&oe=UTF-8");

    if (Page* page = frame->page()) {
        UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
        page->mainFrame()->loader()->urlSelected(KURL(ParsedURLString, url), String(), 0, false, false, MaybeSendReferrer);
    }
}
String HTMLOptionElement::text() const
{
    Document& document = this->document();
    String text;

    // WinIE does not use the label attribute, so as a quirk, we ignore it.
    if (!document.inQuirksMode())
        text = fastGetAttribute(labelAttr);

    // FIXME: The following treats an element with the label attribute set to
    // the empty string the same as an element with no label attribute at all.
    // Is that correct? If it is, then should the label function work the same way?
    if (text.isEmpty())
        text = collectOptionInnerText();

    return text.stripWhiteSpace(isHTMLSpace<UChar>).simplifyWhiteSpace(isHTMLSpace<UChar>);
}
Example #30
0
bool ScriptElement::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) const
{
    // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used here to maintain backwards compatibility with existing layout tests. The specific violations are:
    // - Allowing type=javascript. type= should only support MIME types, such as text/javascript.
    // - Allowing a different set of languages for language= and type=. language= supports Javascript 1.1 and 1.4-1.6, but type= does not.

    String type = typeAttributeValue();
    String language = languageAttributeValue();
    if (type.isEmpty() && language.isEmpty())
        return true; // Assume text/javascript.
    if (type.isEmpty()) {
        type = "text/" + language.lower();
        if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySupportedJavaScriptLanguage(language))
            return true;
    } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type)))
        return true;
    return false;
}