String CSSShadowValue::customCSSText() const { StringBuilder text; if (color) text.append(color->cssText()); if (x) { if (!text.isEmpty()) text.append(' '); text.append(x->cssText()); } if (y) { if (!text.isEmpty()) text.append(' '); text.append(y->cssText()); } if (blur) { if (!text.isEmpty()) text.append(' '); text.append(blur->cssText()); } if (spread) { if (!text.isEmpty()) text.append(' '); text.append(spread->cssText()); } if (style) { if (!text.isEmpty()) text.append(' '); text.append(style->cssText()); } return text.toString(); }
String StylePropertySet::borderPropertyValue(CommonValueMode valueMode) const { const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borderStyleShorthand(), borderColorShorthand() }; String commonValue; StringBuilder result; for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) { String value = getCommonValue(properties[i]); if (value.isNull()) { if (valueMode == ReturnNullOnUncommonValues) return String(); ASSERT(valueMode == OmitUncommonValues); continue; } if (!i) commonValue = value; else if (!commonValue.isNull() && commonValue != value) commonValue = String(); if (value == "initial") continue; if (!result.isEmpty()) result.append(' '); result.append(value); } if (isInitialOrInherit(commonValue)) return commonValue; return result.isEmpty() ? String() : result.toString(); }
String CSSLineBoxContainValue::customCssText() const { StringBuilder text; if (m_value & LineBoxContainBlock) text.appendLiteral("block"); if (m_value & LineBoxContainInline) { if (!text.isEmpty()) text.append(' '); text.appendLiteral("inline"); } if (m_value & LineBoxContainFont) { if (!text.isEmpty()) text.append(' '); text.appendLiteral("font"); } if (m_value & LineBoxContainGlyphs) { if (!text.isEmpty()) text.append(' '); text.appendLiteral("glyphs"); } if (m_value & LineBoxContainReplaced) { if (!text.isEmpty()) text.append(' '); text.appendLiteral("replaced"); } if (m_value & LineBoxContainInlineBox) { if (!text.isEmpty()) text.append(' '); text.appendLiteral("inline-box"); } return text.toString(); }
String StylePropertySet::fontValue() const { int fontSizePropertyIndex = findPropertyIndex(CSSPropertyFontSize); int fontFamilyPropertyIndex = findPropertyIndex(CSSPropertyFontFamily); if (fontSizePropertyIndex == -1 || fontFamilyPropertyIndex == -1) return emptyString(); PropertyReference fontSizeProperty = propertyAt(fontSizePropertyIndex); PropertyReference fontFamilyProperty = propertyAt(fontFamilyPropertyIndex); if (fontSizeProperty.isImplicit() || fontFamilyProperty.isImplicit()) return emptyString(); String commonValue = fontSizeProperty.value()->cssText(); StringBuilder result; appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result, commonValue); appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result, commonValue); appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result, commonValue); if (!result.isEmpty()) result.append(' '); result.append(fontSizeProperty.value()->cssText()); appendFontLonghandValueIfExplicit(CSSPropertyLineHeight, result, commonValue); if (!result.isEmpty()) result.append(' '); result.append(fontFamilyProperty.value()->cssText()); if (isInitialOrInherit(commonValue)) return commonValue; return result.toString(); }
String StylePropertySet::getShorthandValue(const StylePropertyShorthand& shorthand) const { String commonValue; StringBuilder result; for (unsigned i = 0; i < shorthand.length(); ++i) { if (!isPropertyImplicit(shorthand.properties()[i])) { RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]); if (!value) return String(); String valueText = value->cssText(); if (!i) commonValue = valueText; else if (!commonValue.isNull() && commonValue != valueText) commonValue = String(); if (value->isInitialValue()) continue; if (!result.isEmpty()) result.append(' '); result.append(valueText); } else commonValue = String(); } if (isInitialOrInherit(commonValue)) return commonValue; if (result.isEmpty()) return String(); return result.toString(); }
String Resource::reasonNotDeletable() const { StringBuilder builder; if (hasClients()) { builder.append("hasClients("); builder.appendNumber(m_clients.size()); if (!m_clientsAwaitingCallback.isEmpty()) { builder.append(", AwaitingCallback="); builder.appendNumber(m_clientsAwaitingCallback.size()); } if (!m_finishedClients.isEmpty()) { builder.append(", Finished="); builder.appendNumber(m_finishedClients.size()); } builder.append(")"); } if (m_loader) { if (!builder.isEmpty()) builder.append(' '); builder.append("m_loader"); } if (m_preloadCount) { if (!builder.isEmpty()) builder.append(' '); builder.append("m_preloadCount("); builder.appendNumber(m_preloadCount); builder.append(")"); } if (!hasRightHandleCountApartFromCache(0)) { if (!builder.isEmpty()) builder.append(' '); builder.append("m_handleCount("); builder.appendNumber(m_handleCount); builder.append(")"); } if (m_protectorCount) { if (!builder.isEmpty()) builder.append(' '); builder.append("m_protectorCount("); builder.appendNumber(m_protectorCount); builder.append(")"); } if (memoryCache()->contains(this)) { if (!builder.isEmpty()) builder.append(' '); builder.append("in_memory_cache"); } return builder.toString(); }
void StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyID, StringBuilder& result, String& commonValue) const { int foundPropertyIndex = findPropertyIndex(propertyID); if (foundPropertyIndex == -1) return; // All longhands must have at least implicit values if "font" is specified. if (propertyAt(foundPropertyIndex).isImplicit()) { commonValue = String(); return; } char prefix = '\0'; switch (propertyID) { case CSSPropertyFontStyle: break; // No prefix. case CSSPropertyFontFamily: case CSSPropertyFontVariant: case CSSPropertyFontWeight: prefix = ' '; break; case CSSPropertyLineHeight: prefix = '/'; break; default: ASSERT_NOT_REACHED(); } if (prefix && !result.isEmpty()) result.append(prefix); String value = propertyAt(foundPropertyIndex).value()->cssText(); result.append(value); if (!commonValue.isNull() && commonValue != value) commonValue = String(); }
String CSSValueList::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const { StringBuilder result; String separator; switch (m_valueListSeparator) { case SpaceSeparator: separator = " "; break; case CommaSeparator: separator = ", "; break; case SlashSeparator: separator = " / "; break; default: ASSERT_NOT_REACHED(); } unsigned size = m_values.size(); for (unsigned i = 0; i < size; i++) { if (!result.isEmpty()) result.append(separator); result.append(m_values[i]->serializeResolvingVariables(variables)); } return result.toString(); }
String WebFrame::contentsAsString() const { if (!m_coreFrame) return String(); if (isFrameSet()) { StringBuilder builder; for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { if (!builder.isEmpty()) builder.append(' '); builder.append(static_cast<WebFrameLoaderClient*>(child->loader()->client())->webFrame()->contentsAsString()); } // FIXME: It may make sense to use toStringPreserveCapacity() here. return builder.toString(); } Document* document = m_coreFrame->document(); if (!document) return String(); RefPtr<Element> documentElement = document->documentElement(); if (!documentElement) return String(); RefPtr<Range> range = document->createRange(); ExceptionCode ec = 0; range->selectNode(documentElement.get(), ec); if (ec) return String(); return plainText(range.get()); }
String CSSValueList::customCSSText() const { StringBuilder result; String separator; switch (m_valueListSeparator) { case SpaceSeparator: separator = ASCIILiteral(" "); break; case CommaSeparator: separator = ASCIILiteral(", "); break; case SlashSeparator: separator = ASCIILiteral(" / "); break; default: ASSERT_NOT_REACHED(); } for (auto& value : m_values) { bool suppressSeparator = false; if (m_valueListSeparator == SpaceSeparator && value->isPrimitiveValue()) { auto* primitiveValue = &downcast<CSSPrimitiveValue>(*value.ptr()); if (primitiveValue->parserOperator() == ',') suppressSeparator = true; } if (!suppressSeparator && !result.isEmpty()) result.append(separator); result.append(value.get().cssText()); } return result.toString(); }
String CSSValueList::customCssText(CssTextFormattingFlags formattingFlag) const { StringBuilder result; String separator; switch (m_valueListSeparator) { case SpaceSeparator: separator = " "; break; case CommaSeparator: separator = ", "; break; case SlashSeparator: separator = " / "; break; default: ASSERT_NOT_REACHED(); } unsigned size = m_values.size(); for (unsigned i = 0; i < size; i++) { if (!result.isEmpty()) result.append(separator); if (formattingFlag == AlwaysQuoteCSSString && m_values[i]->isPrimitiveValue()) result.append(toCSSPrimitiveValue(m_values[i].get())->customCssText(AlwaysQuoteCSSString)); else result.append(m_values[i]->cssText()); } return result.toString(); }
String CSSValueList::customCSSText() const { StringBuilder result; String separator; switch (m_valueListSeparator) { case SpaceSeparator: separator = ASCIILiteral(" "); break; case CommaSeparator: separator = ASCIILiteral(", "); break; case SlashSeparator: separator = ASCIILiteral(" / "); break; default: ASSERT_NOT_REACHED(); } for (auto& value : m_values) { if (!result.isEmpty()) result.append(separator); result.append(value.get().cssText()); } return result.toString(); }
bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyId, StringBuilder& result) const { const CSSProperty* property = findPropertyWithId(propertyId); if (!property) return false; // All longhands must have at least implicit values if "font" is specified. if (property->isImplicit()) return true; char prefix = '\0'; switch (propertyId) { case CSSPropertyFontStyle: break; // No prefix. case CSSPropertyFontFamily: case CSSPropertyFontVariant: case CSSPropertyFontWeight: prefix = ' '; break; case CSSPropertyLineHeight: prefix = '/'; break; default: ASSERT_NOT_REACHED(); } if (prefix && !result.isEmpty()) result.append(prefix); result.append(property->value()->cssText()); return true; }
String CSSValueList::customCssText() const { StringBuilder result; String separator; switch (m_valueListSeparator) { case SpaceSeparator: separator = " "; break; case CommaSeparator: separator = ", "; break; case SlashSeparator: separator = " / "; break; default: ASSERT_NOT_REACHED(); } unsigned size = m_values.size(); for (unsigned i = 0; i < size; i++) { if (!result.isEmpty()) result.append(separator); result.append(m_values[i]->cssText()); } return result.toString(); }
static void fillContainerFromString(ContainerNode* paragraph, const String& string) { Document& document = paragraph->document(); if (string.isEmpty()) { paragraph->appendChild(HTMLBRElement::create(document)); return; } DCHECK_EQ(string.find('\n'), kNotFound) << string; Vector<String> tabList; string.split('\t', true, tabList); StringBuilder tabText; bool first = true; size_t numEntries = tabList.size(); for (size_t i = 0; i < numEntries; ++i) { const String& s = tabList[i]; // append the non-tab textual part if (!s.isEmpty()) { if (!tabText.isEmpty()) { paragraph->appendChild( createTabSpanElement(document, tabText.toString())); tabText.clear(); } Text* textNode = document.createTextNode( stringWithRebalancedWhitespace(s, first, i + 1 == numEntries)); paragraph->appendChild(textNode); } // there is a tab after every entry, except the last entry // (if the last character is a tab, the list gets an extra empty entry) if (i + 1 != numEntries) tabText.append('\t'); else if (!tabText.isEmpty()) paragraph->appendChild( createTabSpanElement(document, tabText.toString())); first = false; } }
String CSSFontValue::customCSSText() const { // font variant weight size / line-height family StringBuilder result; if (style) result.append(style->cssText()); if (variant) { if (!result.isEmpty()) result.append(' '); result.append(variant->cssText()); } if (weight) { if (!result.isEmpty()) result.append(' '); result.append(weight->cssText()); } if (stretch) { if (!result.isEmpty()) result.append(' '); result.append(stretch->cssText()); } if (size) { if (!result.isEmpty()) result.append(' '); result.append(size->cssText()); } if (lineHeight) { if (!size) result.append(' '); result.append('/'); result.append(lineHeight->cssText()); } if (family) { if (!result.isEmpty()) result.append(' '); result.append(family->cssText()); } return result.toString(); }
String UnlinkedFunctionExecutable::paramString() const { FunctionParameters& parameters = *m_parameters; StringBuilder builder; for (size_t pos = 0; pos < parameters.size(); ++pos) { if (!builder.isEmpty()) builder.appendLiteral(", "); parameters.at(pos)->toString(builder); } return builder.toString(); }
UString FunctionExecutable::paramString() const { FunctionParameters& parameters = *m_parameters; StringBuilder builder; for (size_t pos = 0; pos < parameters.size(); ++pos) { if (!builder.isEmpty()) builder.append(", "); builder.append(parameters[pos].ustring()); } return builder.build(); }
JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) { ExecState* exec = toJS(ctx); JSLockHolder lock(exec); unsigned count = 0; StringBuilder builder; CallFrame* callFrame = exec; String functionName; if (exec->callee()) { if (asObject(exec->callee())->inherits(&InternalFunction::s_info)) { functionName = asInternalFunction(exec->callee())->name(exec); builder.appendLiteral("#0 "); builder.append(functionName); builder.appendLiteral("() "); count++; } } while (true) { ASSERT(callFrame); int signedLineNumber; intptr_t sourceID; String urlString; JSValue function; exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function); if (function) functionName = jsCast<JSFunction*>(function)->name(exec); else { // Caller is unknown, but if frame is empty we should still add the frame, because // something called us, and gave us arguments. if (count) break; } unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; if (!builder.isEmpty()) builder.append('\n'); builder.append('#'); builder.appendNumber(count); builder.append(' '); builder.append(functionName); builder.appendLiteral("() at "); builder.append(urlString); builder.append(':'); builder.appendNumber(lineNumber); if (!function || ++count == maxStackSize) break; callFrame = callFrame->callerFrame(); } return OpaqueJSString::create(builder.toString()).leakRef(); }
// This returns an AtomicString because it is always passed as argument to // setValue() and setValue() takes an AtomicString in argument. AtomicString DOMTokenList::removeTokens(const AtomicString& input, const Vector<String>& tokens) { // Algorithm defined at // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string // New spec is at https://dom.spec.whatwg.org/#remove-a-token-from-a-string unsigned inputLength = input.length(); StringBuilder output; // 3 output.reserveCapacity(inputLength); unsigned position = 0; // 4 // Step 5 while (position < inputLength) { if (isHTMLSpace<UChar>(input[position])) { // 6 position++; continue; // 6.3 } // Step 7 StringBuilder tokenBuilder; while (position < inputLength && isNotHTMLSpace<UChar>(input[position])) tokenBuilder.append(input[position++]); // Step 8 String token = tokenBuilder.toString(); if (tokens.contains(token)) { // Step 8.1 while (position < inputLength && isHTMLSpace<UChar>(input[position])) ++position; // Step 8.2 size_t j = output.length(); while (j > 0 && isHTMLSpace<UChar>(output[j - 1])) --j; output.resize(j); } else { output.append(token); // Step 9 } if (position < inputLength && !output.isEmpty()) output.append(' '); } size_t j = output.length(); if (j > 0 && isHTMLSpace<UChar>(output[j - 1])) output.resize(j - 1); return output.toAtomicString(); }
static String resourceName(const KURL& url) { StringBuilder name; name.append(url.path()); if (name.isEmpty()) name.append('/'); if (!url.query().isNull()) { name.append('?'); name.append(url.query()); } String result = name.toString(); ASSERT(!result.isEmpty()); ASSERT(!result.contains(' ')); return result; }
const AtomicString& DOMTokenList::value() const { if (m_cachedValue.isNull()) { // https://dom.spec.whatwg.org/#concept-ordered-set-serializer StringBuilder builder; for (auto& token : m_tokens) { if (!builder.isEmpty()) builder.append(' '); builder.append(token); } m_cachedValue = builder.toAtomicString(); ASSERT(!m_cachedValue.isNull()); } return m_cachedValue; }
String WebMediaSessionManager::toString(ConfigurationTasks tasks) { StringBuilder string; if (tasks & InitialConfigurationTask) string.append("InitialConfigurationTask + "); if (tasks & TargetClientsConfigurationTask) string.append("TargetClientsConfigurationTask + "); if (tasks & TargetMonitoringConfigurationTask) string.append("TargetMonitoringConfigurationTask + "); if (string.isEmpty()) string.append("NoTask"); else string.resize(string.length() - 2); return string.toString(); }
JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } ExecState* exec = toJS(ctx); JSLockHolder lock(exec); StringBuilder builder; Vector<StackFrame> stackTrace; Interpreter::getStackTrace(&exec->vm(), stackTrace, maxStackSize); for (size_t i = 0; i < stackTrace.size(); i++) { String functionName; StackFrame& frame = stackTrace[i]; JSValue function = frame.callee.get(); if (frame.callee) functionName = frame.friendlyFunctionName(exec); else { // Caller is unknown, but if frame is empty we should still add the frame, because // something called us, and gave us arguments. if (i) break; } unsigned lineNumber; unsigned column; frame.computeLineAndColumn(lineNumber, column); if (!builder.isEmpty()) builder.append('\n'); builder.append('#'); builder.appendNumber(i); builder.append(' '); builder.append(functionName); builder.appendLiteral("() at "); builder.append(frame.friendlySourceURL()); if (frame.codeType != StackFrameNativeCode) { builder.append(':'); builder.appendNumber(lineNumber); } if (!function) break; } return OpaqueJSString::create(builder.toString()).leakRef(); }
String DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token) { // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string unsigned inputLength = input.length(); StringBuilder output; // 3 output.reserveCapacity(inputLength); unsigned position = 0; // 4 // Step 5 while (position < inputLength) { if (isHTMLSpace(input[position])) { // 6 output.append(input[position++]); // 6.1, 6.2 continue; // 6.3 } // Step 7 StringBuilder s; while (position < inputLength && isNotHTMLSpace(input[position])) s.append(input[position++]); // Step 8 if (s.toStringPreserveCapacity() == token) { // Step 8.1 while (position < inputLength && isHTMLSpace(input[position])) ++position; // Step 8.2 size_t j = output.length(); while (j > 0 && isHTMLSpace(output[j - 1])) --j; output.resize(j); // Step 8.3 if (position < inputLength && !output.isEmpty()) output.append(' '); } else output.append(s.toStringPreserveCapacity()); // Step 9 } return output.toString(); }
static String mediaProducerStateString(MediaProducer::MediaStateFlags flags) { StringBuilder string; if (flags & MediaProducer::IsPlayingAudio) string.append("IsPlayingAudio + "); if (flags & MediaProducer::IsPlayingVideo) string.append("IsPlayingVideo + "); if (flags & MediaProducer::IsPlayingToExternalDevice) string.append("IsPlayingToExternalDevice + "); if (flags & MediaProducer::RequiresPlaybackTargetMonitoring) string.append("RequiresPlaybackTargetMonitoring + "); if (flags & MediaProducer::ExternalDeviceAutoPlayCandidate) string.append("ExternalDeviceAutoPlayCandidate + "); if (string.isEmpty()) string.append("IsNotPlaying"); else string.resize(string.length() - 2); return string.toString(); }
static void appendMailtoPostFormDataToURL(KURL& url, const EncodedFormData& data, const String& encodingType) { String body = data.flattenToString(); if (equalIgnoringCase(encodingType, "text/plain")) { // Convention seems to be to decode, and s/&/\r\n/. Also, spaces are encoded as %20. body = decodeURLEscapeSequences(body.replaceWithLiteral('&', "\r\n").replace('+', ' ') + "\r\n"); } Vector<char> bodyData; bodyData.append("body=", 5); FormDataEncoder::encodeStringAsFormData(bodyData, body.utf8()); body = String(bodyData.data(), bodyData.size()).replaceWithLiteral('+', "%20"); StringBuilder query; query.append(url.query()); if (!query.isEmpty()) query.append('&'); query.append(body); url.setQuery(query.toString()); }
ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& request, SecurityOrigin* securityOrigin) { ResourceRequest preflightRequest(request.url()); updateRequestForAccessControl(preflightRequest, securityOrigin, DoNotAllowStoredCredentials); preflightRequest.setHTTPMethod("OPTIONS"); preflightRequest.setHTTPHeaderField("Access-Control-Request-Method", request.httpMethod()); preflightRequest.setPriority(request.priority()); preflightRequest.setRequestContext(request.requestContext()); preflightRequest.setSkipServiceWorker(true); const HTTPHeaderMap& requestHeaderFields = request.httpHeaderFields(); if (requestHeaderFields.size() > 0) { // Sort header names lexicographically: https://crbug.com/452391 // Fetch API Spec: // https://fetch.spec.whatwg.org/#cors-preflight-fetch-0 Vector<String> headers; for (const auto& header : requestHeaderFields) { if (equalIgnoringCase(header.key, "referer")) { // When the request is from a Worker, referrer header was added // by WorkerThreadableLoader. But it should not be added to // Access-Control-Request-Headers header. continue; } headers.append(header.key.lower()); } std::sort(headers.begin(), headers.end(), WTF::codePointCompareLessThan); StringBuilder headerBuffer; for (const String& header : headers) { if (!headerBuffer.isEmpty()) headerBuffer.appendLiteral(", "); headerBuffer.append(header); } preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", AtomicString(headerBuffer.toString())); } return preflightRequest; }
String WebFrame::contentsAsString() const { if (!m_coreFrame) return String(); if (isFrameSet()) { StringBuilder builder; for (Frame* child = m_coreFrame->tree().firstChild(); child; child = child->tree().nextSibling()) { if (!builder.isEmpty()) builder.append(' '); WebFrame* webFrame = WebFrame::fromCoreFrame(*child); ASSERT(webFrame); builder.append(webFrame->contentsAsString()); } // FIXME: It may make sense to use toStringPreserveCapacity() here. return builder.toString(); } Document* document = m_coreFrame->document(); if (!document) return String(); RefPtr<Element> documentElement = document->documentElement(); if (!documentElement) return String(); RefPtr<Range> range = document->createRange(); ExceptionCode ec = 0; range->selectNode(*documentElement, ec); if (ec) return String(); return plainText(range.get()); }
String StylePropertySet::fontValue() const { const CSSProperty* fontSizeProperty = findPropertyWithId(CSSPropertyFontSize); if (!fontSizeProperty || fontSizeProperty->isImplicit()) return emptyString(); StringBuilder result; bool success = true; success &= appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result); success &= appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result); success &= appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result); if (!result.isEmpty()) result.append(' '); result.append(fontSizeProperty->value()->cssText()); success &= appendFontLonghandValueIfExplicit(CSSPropertyLineHeight, result); success &= appendFontLonghandValueIfExplicit(CSSPropertyFontFamily, result); if (!success) { // An invalid "font" value has been built (should never happen, as at least implicit values // for mandatory longhands are always found in the style), report empty value instead. ASSERT_NOT_REACHED(); return emptyString(); } return result.toString(); }