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", AtomicString::ConstructFromLiteral)); 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 == notFound && 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) return SMILTime::unresolved(); return result; }
bool ScriptElementData::shouldExecuteAsJavaScript() const { /* Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts only javascript1.1 - javascript1.3. Mozilla 1.8 and WinIE 7 both accept javascript and livescript. WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't. Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace. We want to accept all the values that either of these browsers accept, but not other values. */ String type = m_scriptElement->typeAttributeValue(); if (!type.isEmpty()) { if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower())) return false; } else { String language = m_scriptElement->languageAttributeValue(); if (!language.isEmpty() && !isSupportedJavaScriptLanguage(language)) return false; } // No type or language is specified, so we assume the script to be JavaScript. // We don't yet support setting event listeners via the 'for' attribute for scripts. // If there is such an attribute it's likely better to not execute the script than to do so // immediately and unconditionally. // FIXME: After <rdar://problem/4471751> / https://bugs.webkit.org/show_bug.cgi?id=16915 are resolved // and we support the for syntax in script tags, this check can be removed and we should just // return 'true' here. String forAttribute = m_scriptElement->forAttributeValue(); return forAttribute.isEmpty(); }
static String normalizeType(const String& type) { String cleanType = type.stripWhiteSpace().lower(); if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc)) return mimeTypeTextPlain; return cleanType; }
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; } }
bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const { if (!directive) return true; if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type) return false; return directive->allows(type); }
String FetchUtils::normalizeHeaderValue(const String& value) { // https://fetch.spec.whatwg.org/#concept-header-value-normalize // Strip leading and trailing whitespace from header value. // HTTP whitespace bytes are 0x09, 0x0A, 0x0D, and 0x20. return value.stripWhiteSpace(isHTTPWhitespace); }
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(); }
StyleColor CSSParser::colorFromRGBColorString(const String& string) { // FIXME: Rework css parser so it is more SVG aware. RGBA32 color; if (parseColor(color, string.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(); }
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(); }
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; }
bool DOMWindowCSS::supports(const String& property, const String& value) const { CSSPropertyID propertyID = cssPropertyID(property.stripWhiteSpace()); if (propertyID == CSSPropertyInvalid) return false; ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID)); // 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; RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create(); return CSSParser::parseValue(dummyStyle.get(), propertyID, normalizedValue, false, HTMLStandardMode, 0); }
bool SVGColor::colorFromRGBColorString(const String& colorString, Color& color) { // FIXME: Rework css parser so it is more SVG aware. RGBA32 rgba; if (CSSParser::parseColor(rgba, colorString.stripWhiteSpace())) { color = rgba; return true; } return false; }
String Path::debugString() const { String result; SkPath::Iter iter(*m_path, false); SkPoint pts[4]; int numPoints = m_path->getPoints(0, 0); SkPath::Verb verb; do { verb = iter.next(pts); switch (verb) { case SkPath::kMove_Verb: result += String::format("M%.2f,%.2f ", pts[0].fX, pts[0].fY); numPoints -= 1; break; case SkPath::kLine_Verb: if (!iter.isCloseLine()) { result += String::format("L%.2f,%.2f ", pts[1].fX, pts[1].fY); numPoints -= 1; } break; case SkPath::kQuad_Verb: result += String::format("Q%.2f,%.2f,%.2f,%.2f ", pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); numPoints -= 2; break; case SkPath::kCubic_Verb: result += String::format("C%.2f,%.2f,%.2f,%.2f,%.2f,%.2f ", pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY); numPoints -= 3; break; case SkPath::kClose_Verb: result += "Z "; break; case SkPath::kDone_Verb: break; } } while (verb != SkPath::kDone_Verb); // If you have a path that ends with an M, Skia will not iterate the // trailing M. That's nice of it, but Apple's paths output the trailing M // and we want out layout dumps to look like theirs if (numPoints) { ASSERT(numPoints==1); m_path->getLastPt(pts); result += String::format("M%.2f,%.2f ", pts[0].fX, pts[0].fY); } return result.stripWhiteSpace(); }
bool ResourceResponseBase::isAttachment() const { lazyInit(); 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"); }
UChar MathMLOperatorElement::parseOperatorText(const String& string) { // We collapse the whitespace and replace the hyphens by minus signs. AtomicString textContent = string.stripWhiteSpace().simplifyWhiteSpace().replace(hyphenMinus, minusSign).impl(); // We verify whether the operator text can be represented by a single UChar. // FIXME: This is a really inefficient way to extract a character from a string (https://webkit.org/b/160241#c7). // FIXME: This does not handle surrogate pairs (https://webkit.org/b/122296). // FIXME: This does not handle <mo> operators with multiple characters (https://webkit.org/b/124828). return textContent.length() == 1 ? textContent[0] : 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(); }
String WMLOptGroupElement::groupLabelText() const { String itemText = document()->displayStringModifiedByEncoding(m_title); // 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; }
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(); }
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; }
String HTMLOptGroupElement::groupLabelText() const { String itemText = 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; }
// We provide the IE clipboard types (URL and Text), and the clipboard types // specified in the WHATWG Web Applications 1.0 draft see // http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3 static String normalizeType(const String& type, bool* convertToURL = 0) { String cleanType = type.stripWhiteSpace().lower(); if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc)) return mimeTypeTextPlain; if (cleanType == mimeTypeURL) { if (convertToURL) *convertToURL = true; return mimeTypeTextURIList; } return cleanType; }
static ClipboardDataType clipboardTypeFromMIMEType(const String& type) { String cleanType = type.stripWhiteSpace().lower(); // two special cases for IE compatibility if (cleanType == "text" || cleanType == "text/plain" || cleanType.startsWith("text/plain;")) return ClipboardDataTypeText; if (cleanType == "url" || cleanType == "text/uri-list") return ClipboardDataTypeURL; return ClipboardDataTypeNone; }
bool ResourceResponseBase::isAttachment() const { lazyInit(AllFields); String value = m_httpHeaderFields.get(HTTPHeaderName::ContentDisposition); size_t loc = value.find(';'); if (loc != notFound) value = value.left(loc); value = value.stripWhiteSpace(); return equalIgnoringCase(value, "attachment"); }
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); }
bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url) { int len = refresh.length(); int 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); int urlStartPos = pos; if (refresh.find("url", urlStartPos, false) == urlStartPos) { urlStartPos += 3; skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta); if (refresh[urlStartPos] == '=') { ++urlStartPos; skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta); } else urlStartPos = pos; // e.g. "Refresh: 0; url.html" } int urlEndPos = len; if (refresh[urlStartPos] == '"' || refresh[urlStartPos] == '\'') { UChar quotationMark = refresh[urlStartPos]; urlStartPos++; while (urlEndPos > urlStartPos) { urlEndPos--; if (refresh[urlEndPos] == quotationMark) break; } } url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhiteSpace(); return true; } }
static String findMagicComment(const String& content, const String& name, MagicCommentType commentType, bool* deprecated = 0) { ASSERT(name.find("=") == notFound); if (deprecated) *deprecated = false; String pattern; String deprecatedPattern; switch (commentType) { case JavaScriptMagicComment: pattern = "//#[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s\'\"]*)[\040\t]*$"; deprecatedPattern = "//@[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s\'\"]*)[\040\t]*$"; break; case CSSMagicComment: pattern = "/\\*#[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s]*)[\040\t]*\\*/[\040\t]*$"; deprecatedPattern = "/\\*@[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s]*)[\040\t]*\\*/[\040\t]*$"; break; default: ASSERT_NOT_REACHED(); return String(); } RegularExpression regex(pattern, TextCaseSensitive, MultilineEnabled); RegularExpression deprecatedRegex(deprecatedPattern, TextCaseSensitive, MultilineEnabled); int matchLength; int offset = regex.match(content, 0, &matchLength); if (offset == -1) { offset = deprecatedRegex.match(content, 0, &matchLength); if (offset != -1 && deprecated) *deprecated = true; } if (offset == -1) return String(); String match = content.substring(offset, matchLength); size_t separator = match.find("="); ASSERT(separator != notFound); match = match.substring(separator + 1); switch (commentType) { case JavaScriptMagicComment: return match.stripWhiteSpace(); case CSSMagicComment: { size_t lastStarIndex = match.reverseFind('*'); ASSERT(lastStarIndex != notFound); return match.substring(0, lastStarIndex).stripWhiteSpace(); } default: ASSERT_NOT_REACHED(); return String(); } }
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(DefinitelyProcessingNewUserGesture); page->mainFrame()->loader()->urlSelected(KURL(ParsedURLString, url), String(), 0, false, false, MaybeSendReferrer); } }