Example #1
0
void HTMLElement::mapLanguageAttributeToLocale(const AtomicString& value, MutableStylePropertySet* style)
{
    if (!value.isEmpty()) {
        // Have to quote so the locale id is treated as a string instead of as a CSS keyword.
        addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitLocale, quoteCSSString(value));

        // FIXME: Remove the following UseCounter code when we collect enough
        // data.
        UseCounter::count(document(), UseCounter::LangAttribute);
        if (isHTMLHtmlElement(*this))
            UseCounter::count(document(), UseCounter::LangAttributeOnHTML);
        else if (isHTMLBodyElement(*this))
            UseCounter::count(document(), UseCounter::LangAttributeOnBody);
        String htmlLanguage = value.string();
        size_t firstSeparator = htmlLanguage.find('-');
        if (firstSeparator != kNotFound)
            htmlLanguage = htmlLanguage.left(firstSeparator);
        String uiLanguage = defaultLanguage();
        firstSeparator = uiLanguage.find('-');
        if (firstSeparator != kNotFound)
            uiLanguage = uiLanguage.left(firstSeparator);
        firstSeparator = uiLanguage.find('_');
        if (firstSeparator != kNotFound)
            uiLanguage = uiLanguage.left(firstSeparator);
        if (!equalIgnoringCase(htmlLanguage, uiLanguage))
            UseCounter::count(document(), UseCounter::LangAttributeDoesNotMatchToUILocale);
    } else {
        // The empty string means the language is explicitly unknown.
        addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitLocale, CSSValueAuto);
    }
}
Example #2
0
String directoryName(const String& path)
{
    size_t pos = reverseFindPathSeparator(path);
    if (pos == notFound)
        return String();
    return path.left(pos);
}
Example #3
0
bool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginInfoStore::Plugin& plugin)
{
        String pathCopy = pluginPath;
    DWORD versionInfoSize = ::GetFileVersionInfoSizeW(pathCopy.charactersWithNullTermination(), 0);
    if (!versionInfoSize)
        return false;

    OwnArrayPtr<char> versionInfoData = adoptArrayPtr(new char[versionInfoSize]);
    if (!::GetFileVersionInfoW(pathCopy.charactersWithNullTermination(), 0, versionInfoSize, versionInfoData.get()))
        return false;

    String name = getVersionInfo(versionInfoData.get(), "ProductName");
    String description = getVersionInfo(versionInfoData.get(), "FileDescription");
    if (name.isNull() || description.isNull())
        return false;

    VS_FIXEDFILEINFO* info;
    UINT infoSize;
    if (!::VerQueryValueW(versionInfoData.get(), L"\\", reinterpret_cast<void**>(&info), &infoSize) || infoSize < sizeof(VS_FIXEDFILEINFO))
        return false;

    Vector<String> types;
    getVersionInfo(versionInfoData.get(), "MIMEType").split('|', types);
    Vector<String> extensionLists;
    getVersionInfo(versionInfoData.get(), "FileExtents").split('|', extensionLists);
    Vector<String> descriptions;
    getVersionInfo(versionInfoData.get(), "FileOpenName").split('|', descriptions);

    Vector<MimeClassInfo> mimes(types.size());
    for (size_t i = 0; i < types.size(); i++) {
        String type = types[i].lower();
        String description = i < descriptions.size() ? descriptions[i] : "";
        String extensionList = i < extensionLists.size() ? extensionLists[i] : "";

        Vector<String> extensionsVector;
        extensionList.split(',', extensionsVector);

        // Get rid of the extension list that may be at the end of the description string.
        int pos = description.find("(*");
        if (pos != -1) {
            // There might be a space that we need to get rid of.
            if (pos > 1 && description[pos - 1] == ' ')
                pos--;
            description = description.left(pos);
        }

        mimes[i].type = type;
        mimes[i].desc = description;
        mimes[i].extensions.swap(extensionsVector);
    }

    plugin.path = pluginPath;
    plugin.info.desc = description;
    plugin.info.name = name;
    plugin.info.file = pathGetFileName(pluginPath);
    plugin.info.mimes.swap(mimes);
    plugin.fileVersion = fileVersion(info->dwFileVersionLS, info->dwFileVersionMS);

    return true;
}
Example #4
0
void WindowFeatures::parseDialogFeatures(const String& string, DialogFeaturesMap& map)
{
    Vector<String> vector;
    string.split(';', vector);
    size_t size = vector.size();
    for (size_t i = 0; i < size; ++i) {
        const String& featureString = vector[i];

        size_t separatorPosition = featureString.find('=');
        size_t colonPosition = featureString.find(':');
        if (separatorPosition != notFound && colonPosition != notFound)
            continue; // ignore strings that have both = and :
        if (separatorPosition == notFound)
            separatorPosition = colonPosition;

        String key = featureString.left(separatorPosition).stripWhiteSpace().lower();

        // Null string for value indicates key without value.
        String value;
        if (separatorPosition != notFound) {
            value = featureString.substring(separatorPosition + 1).stripWhiteSpace().lower();
            value = value.left(value.find(' '));
        }

        map.set(key, value);
    }
}
Example #5
0
StringName ConnectDialog::get_dst_method_name() const {

	String txt = dst_method->get_text();
	if (txt.find("(") != -1)
		txt = txt.left(txt.find("(")).strip_edges();
	return txt;
}
Example #6
0
static String extractLanguageCode(const String& locale)
{
    size_t dashPosition = locale.find('-');
    if (dashPosition == notFound)
        return locale;
    return locale.left(dashPosition);
}
Example #7
0
void SessionRep::extract(
    const String& arg, const OptionDesc& o, int& i, int argc, char** argv,
    String& name, String& value
) {
    int colon;
    switch (o.style) {
    case OptionPropertyNext:
	value = next_arg(i, argc, argv, "missing property after '%s'", arg);
	colon = value.index(':');
	if (colon < 0) {
	    bad_arg("missing ':' in '%s'", value);
	} else {
	    name = value.left(colon);
	    value = value.right(colon+1);
	}
	break;
    case OptionValueNext:
	name = o.path;
	value = next_arg(i, argc, argv, "missing value after '%s'", arg);
	break;
    case OptionValueImplicit:
	name = o.path;
	value = o.value;
	break;
    case OptionValueIsArg:
	name = o.path;
	value = arg;
	break;
    case OptionValueAfter:
	bad_arg("missing value in '%s'", arg);
	break;
    }
}
Example #8
0
Value FunLang::evaluate() const
{
    String lang = arg(0)->evaluate().toString();

    Attribute* languageAttribute = 0;
    Node* node = evaluationContext().node.get();
    while (node) {
        NamedNodeMap* attrs = node->attributes();
        if (attrs)
            languageAttribute = attrs->getAttributeItem(XMLNames::langAttr);
        if (languageAttribute)
            break;
        node = node->parentNode();
    }

    if (!languageAttribute)
        return false;

    String langValue = languageAttribute->value();
    while (true) {
        if (equalIgnoringCase(langValue, lang))
            return true;

        // Remove suffixes one by one.
        int index = langValue.reverseFind('-');
        if (index == -1)
            break;
        langValue = langValue.left(index);
    }

    return false;
}
v8::Handle<v8::Value> V8CSSStyleDeclaration::namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.CSSStyleDeclaration.NamedPropertySetter");
    CSSStyleDeclaration* imp = V8CSSStyleDeclaration::toNative(info.Holder());
    CSSPropertyInfo* propInfo = cssPropertyInfo(name);
    if (!propInfo)
        return notHandledByInterceptor();

    String propertyValue = toWebCoreStringWithNullCheck(value);
    if (propInfo->hadPixelOrPosPrefix)
        propertyValue.append("px");

    ExceptionCode ec = 0;
    int importantIndex = propertyValue.find("!important", 0, false);
    bool important = false;
    if (importantIndex != -1) {
        important = true;
        propertyValue = propertyValue.left(importantIndex - 1);
    }
    imp->setProperty(propInfo->propID, propertyValue, important, ec);

    if (ec)
        throwError(ec);

    return value;
}
Example #10
0
bool NetworkJob::handleFTPHeader(const String& header)
{
    size_t spacePos = header.find(' ');
    if (spacePos == notFound)
        return false;
    String statusCode = header.left(spacePos);
    switch (statusCode.toInt()) {
    case 213:
        m_isFTPDir = false;
        break;
    case 530:
        purgeCredentials();
        sendRequestWithCredentials(ProtectionSpaceServerFTP, ProtectionSpaceAuthenticationSchemeDefault, "ftp");
        break;
    case 230:
        storeCredentials();
        break;
    case 550:
        // The user might have entered an URL which point to a directory but forgot type '/',
        // e.g., ftp://ftp.trolltech.com/qt/source where 'source' is a directory. We need to
        // added '/' and try again.
        if (m_handle && !m_handle->firstRequest().url().path().endsWith("/"))
            m_needsRetryAsFTPDirectory = true;
        break;
    }

    return true;
}
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 #12
0
SMILTime SVGSMILElement::parseOffsetValue(const String& data) {
  bool ok;
  double result = 0;
  String parse = data.stripWhiteSpace();
  if (parse.endsWith('h'))
    result = parse.left(parse.length() - 1).toDouble(&ok) * 60 * 60;
  else if (parse.endsWith("min"))
    result = parse.left(parse.length() - 3).toDouble(&ok) * 60;
  else if (parse.endsWith("ms"))
    result = parse.left(parse.length() - 2).toDouble(&ok) / 1000;
  else if (parse.endsWith('s'))
    result = parse.left(parse.length() - 1).toDouble(&ok);
  else
    result = parse.toDouble(&ok);
  if (!ok || !SMILTime(result).isFinite())
    return SMILTime::unresolved();
  return result;
}
static String limitLength(const String& string, unsigned maxLength)
{
    unsigned newLength = std::min(maxLength, string.length());
    if (newLength == string.length())
        return string;
    if (newLength > 0 && U16_IS_LEAD(string[newLength - 1]))
        --newLength;
    return string.left(newLength);
}
String ContentType::type() const
{
    String strippedType = m_type.stripWhiteSpace();

    // "type" can have parameters after a semi-colon, strip them
    size_t semi = strippedType.find(';');
    if (semi != notFound)
        strippedType = strippedType.left(semi).stripWhiteSpace();

    return strippedType;
}
Example #15
0
void handleDataURL(ResourceHandle* handle)
{
    ASSERT(handle->firstRequest().url().protocolIs("data"));
    String url = handle->firstRequest().url().string();

    int index = url.find(',');
    if (index == -1) {
        handle->client()->cannotShowURL(handle);
        return;
    }

    String mediaType = url.substring(5, index - 5);
    String data = url.substring(index + 1);

    bool base64 = mediaType.endsWith(";base64", false);
    if (base64)
        mediaType = mediaType.left(mediaType.length() - 7);

    if (mediaType.isEmpty())
        mediaType = "text/plain";

    String mimeType = extractMIMETypeFromMediaType(mediaType);
    String charset = extractCharsetFromMediaType(mediaType);

    if (charset.isEmpty())
        charset = "US-ASCII";

    ResourceResponse response;
    response.setMimeType(mimeType);
    response.setTextEncodingName(charset);
    response.setURL(handle->firstRequest().url());

    if (base64) {
        data = decodeURLEscapeSequences(data);
        handle->client()->didReceiveResponse(handle, response);

        Vector<char> out;
        if (base64Decode(data, out, IgnoreWhitespace) && out.size() > 0) {
            response.setExpectedContentLength(out.size());
            handle->client()->didReceiveData(handle, out.data(), out.size(), 0);
        }
    } else {
        TextEncoding encoding(charset);
        data = decodeURLEscapeSequences(data, encoding);
        handle->client()->didReceiveResponse(handle, response);

        CString encodedData = encoding.encode(data.characters(), data.length(), URLEncodedEntitiesForUnencodables);
        response.setExpectedContentLength(encodedData.length());
        if (encodedData.length())
            handle->client()->didReceiveData(handle, encodedData.data(), encodedData.length(), 0);
    }

    handle->client()->didFinishLoading(handle, 0);
}
Example #16
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 #17
0
static inline bool isCompatibleGlyph(const SVGGlyphIdentifier& identifier, bool isVerticalText, const String& language,
                                     const Vector<SVGGlyphIdentifier::ArabicForm>& chars, unsigned startPosition, unsigned endPosition)
{
    bool valid = true;

    // Check wheter orientation if glyph fits within the request
    switch (identifier.orientation) {
    case SVGGlyphIdentifier::Vertical:
        valid = isVerticalText;
        break;
    case SVGGlyphIdentifier::Horizontal:
        valid = !isVerticalText;
        break;
    case SVGGlyphIdentifier::Both:
        break;
    }

    if (!valid)
        return false;

    // Check wheter languages are compatible
    if (!identifier.languages.isEmpty()) {
        // This glyph exists only in certain languages, if we're not specifying a
        // language on the referencing element we're unable to use this glyph.
        if (language.isEmpty())
            return false;

        // Split subcode from language, if existant.
        String languagePrefix;

        int subCodeSeparator = language.find('-');
        if (subCodeSeparator != -1)
            languagePrefix = language.left(subCodeSeparator);

        Vector<String>::const_iterator it = identifier.languages.begin();
        Vector<String>::const_iterator end = identifier.languages.end();

        bool found = false;
        for (; it != end; ++it) {
            const String& cur = *it;
            if (cur == language || cur == languagePrefix) {
                found = true;
                break;
            }
        }

        if (!found)
            return false;
    }

    // Check wheter arabic form is compatible
    return isCompatibleArabicForm(identifier, chars, startPosition, endPosition);
}
Example #18
0
static String limitLength(const String& string, int maxLength)
{
    unsigned newLength = numCharactersInGraphemeClusters(string, maxLength);
    for (unsigned i = 0; i < newLength; ++i) {
        const UChar current = string[i];
        if (current < ' ' && current != '\t') {
            newLength = i;
            break;
        }
    }
    return string.left(newLength);
}
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;
}
Example #20
0
static String valueWithoutImportant(const String& value)
{
    if (!value.endsWith("important", false))
        return value;

    String newValue = value;
    int bangIndex = newValue.length() - 9 - 1;
    if (newValue[bangIndex] == ' ')
        bangIndex--;
    newValue = newValue.left(bangIndex);

    return newValue;
}
Example #21
0
void FindInFilesPanel::apply_replaces_in_file(String fpath, PoolIntArray locations, String text) {

	ERR_FAIL_COND(locations.size() % 3 != 0);

	//print_line(String("Replacing {0} occurrences in {1}").format(varray(fpath, locations.size() / 3)));

	// If the file is already open, I assume the editor will reload it.
	// If there are unsaved changes, the user will be asked on focus,
	// however that means either loosing changes or loosing replaces.

	FileAccess *f = FileAccess::open(fpath, FileAccess::READ);
	ERR_FAIL_COND(f == NULL);

	String buffer;
	int current_line = 1;

	ConservativeGetLine conservative;

	String line = conservative.get_line(f);

	PoolIntArray::Read locations_read = locations.read();
	for (int i = 0; i < locations.size(); i += 3) {

		int repl_line_number = locations_read[i];
		int repl_begin = locations_read[i + 1];
		int repl_end = locations_read[i + 2];

		while (current_line < repl_line_number) {
			buffer += line;
			line = conservative.get_line(f);
			++current_line;
		}

		line = line.left(repl_begin) + text + line.right(repl_end);
	}

	buffer += line;

	while (!f->eof_reached()) {
		buffer += conservative.get_line(f);
	}

	// Now the modified contents are in the buffer, rewrite the file with our changes

	Error err = f->reopen(fpath, FileAccess::WRITE);
	ERR_FAIL_COND(err != OK);

	f->store_string(buffer);

	f->close();
}
Example #22
0
static String platformLanguage()
{
    char* localeDefault = setlocale(LC_CTYPE, 0);

    if (!localeDefault)
        return String("c");

    String locale = String(localeDefault);
    locale.replace('_', '-');
    size_t position = locale.find('.');
    if (position != notFound)
        locale = locale.left(position);

    return locale;
}
Example #23
0
static String functionCallBase(const String& sourceText)
{ 
    // This function retrieves the 'foo.bar' substring from 'foo.bar(baz)'.
    // FIXME: This function has simple processing of /* */ style comments.
    // It doesn't properly handle embedded comments of string literals that contain
    // parenthesis or comment constructs, e.g. foo.bar("/abc\)*/").
    // https://bugs.webkit.org/show_bug.cgi?id=146304

    unsigned sourceLength = sourceText.length();
    unsigned idx = sourceLength - 1;
    if (sourceLength < 2 || sourceText[idx] != ')') {
        // For function calls that have many new lines in between their open parenthesis
        // and their closing parenthesis, the text range passed into the message appender 
        // will not inlcude the text in between these parentheses, it will just be the desired
        // text that precedes the parentheses.
        return sourceText;
    }

    unsigned parenStack = 1;
    bool isInMultiLineComment = false;
    idx -= 1;
    // Note that we're scanning text right to left instead of the more common left to right, 
    // so syntax detection is backwards.
    while (parenStack > 0) {
        UChar curChar = sourceText[idx];
        if (isInMultiLineComment)  {
            if (idx > 0 && curChar == '*' && sourceText[idx - 1] == '/') {
                isInMultiLineComment = false;
                idx -= 1;
            }
        } else if (curChar == '(')
            parenStack -= 1;
        else if (curChar == ')')
            parenStack += 1;
        else if (idx > 0 && curChar == '/' && sourceText[idx - 1] == '*') {
            isInMultiLineComment = true;
            idx -= 1;
        }

        if (!idx)
            break;

        idx -= 1;
    }

    return sourceText.left(idx + 1);
}
bool UserContentURLPattern::parse(const String& pattern)
{
    static NeverDestroyed<const String> schemeSeparator(ASCIILiteral("://"));

    size_t schemeEndPos = pattern.find(schemeSeparator);
    if (schemeEndPos == notFound)
        return false;

    m_scheme = pattern.left(schemeEndPos);

    unsigned hostStartPos = schemeEndPos + schemeSeparator.get().length();
    if (hostStartPos >= pattern.length())
        return false;

    int pathStartPos = 0;

    if (equalLettersIgnoringASCIICase(m_scheme, "file"))
        pathStartPos = hostStartPos;
    else {
        size_t hostEndPos = pattern.find('/', hostStartPos);
        if (hostEndPos == notFound)
            return false;

        m_host = pattern.substring(hostStartPos, hostEndPos - hostStartPos);
        m_matchSubdomains = false;

        if (m_host == "*") {
            // The pattern can be just '*', which means match all domains.
            m_host = emptyString();
            m_matchSubdomains = true;
        } else if (m_host.startsWith("*.")) {
            // The first component can be '*', which means to match all subdomains.
            m_host = m_host.substring(2); // Length of "*."
            m_matchSubdomains = true;
        }

        // No other '*' can occur in the host.
        if (m_host.find('*') != notFound)
            return false;

        pathStartPos = hostEndPos;
    }

    m_path = pattern.right(pattern.length() - pathStartPos);

    return true;
}
Example #25
0
YETI_Result HttpHeaders::parse(BufferedInputStream & stream)
{
    String header_name;
    String header_value;
    bool   header_pending = false;
    String line;

    while (YETI_SUCCEEDED(stream.read_line(line, YETI_HTTP_PROTOCOL_MAX_LINE_LENGTH))) {
        if (line.get_length() == 0) {
            // end of headers
            break;
        }
        if (header_pending && (line[0] == ' ' || line[0] == '\t')) {
            header_value.append(line.get_chars() + 1, line.get_length() - 1);
        } else {
            if (header_pending) {
                header_value.trim();
                add_header(header_name, header_value);
                header_pending = false;
                YETI_LOG_FINEST_2("header - %s: %s", header_name.get_chars(), header_value.get_chars());
            }

            int colon_index = line.find(':');
            if (colon_index < 1) {
                // invalid syntax, ignore
                continue;
            }
            header_name = line.left(colon_index);
            const char * value = line.get_chars() + colon_index + 1;
            while (*value == ' ' || *value == '\t') {
                value++;
            }
            header_value =  value;
            header_pending = true;
        }
    }

    if (header_pending) {
        header_value.trim();
        add_header(header_name, header_value);
        YETI_LOG_FINEST_2("header - %s: %s", header_name.get_chars(), header_value.get_chars());
    }

    return YETI_SUCCESS;
}
Example #26
0
boolean SessionRep::match(
    const String& arg, const OptionDesc& o, int& i, int argc, char** argv
) {
    String opt(o.name);
    if (arg != opt) {
	if (o.style == OptionValueAfter) {
	    int n = opt.length();
	    if (opt == arg.left(n)) {
		style_->attribute(String(o.path), arg.right(n));
		return true;
	    }
	}
	return false;
    }
    String name, value;
    extract(arg, o, i, argc, argv, name, value);
    style_->attribute(name, value);
    return true;
}
void V8Location::hostAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.Location.host._set");
    v8::Handle<v8::Object> holder = info.Holder();
    Location* imp = V8Location::toNative(holder);
    String host = toWebCoreString(value);

    Frame* frame = imp->frame();
    if (!frame)
        return;

    KURL url = frame->loader()->url();
    String newHost = host.left(host.find(":"));
    String newPort = host.substring(host.find(":") + 1);
    url.setHost(newHost);
    url.setPort(newPort.toUInt());

    navigateIfAllowed(frame, url, false, false);
}
Example #28
0
PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document* document, const String& markup, unsigned fragmentStart, unsigned fragmentEnd,
    const String& baseURL, ParserContentPolicy parserContentPolicy)
{
    // FIXME: Need to handle the case where the markup already contains these markers.

    StringBuilder taggedMarkup;
    taggedMarkup.append(markup.left(fragmentStart));
    MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag);
    taggedMarkup.append(markup.substring(fragmentStart, fragmentEnd - fragmentStart));
    MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag);
    taggedMarkup.append(markup.substring(fragmentEnd));

    RefPtr<DocumentFragment> taggedFragment = createFragmentFromMarkup(document, taggedMarkup.toString(), baseURL, parserContentPolicy);
    RefPtr<Document> taggedDocument = Document::create(0, KURL());
    taggedDocument->setContextFeatures(document->contextFeatures());
    taggedDocument->takeAllChildrenFrom(taggedFragment.get());

    RefPtr<Node> nodeBeforeContext;
    RefPtr<Node> nodeAfterContext;
    if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, nodeAfterContext))
        return 0;

    RefPtr<Range> range = Range::create(taggedDocument.get(),
        positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(),
        positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent());

    Node* commonAncestor = range->commonAncestorContainer(ASSERT_NO_EXCEPTION);
    Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRenderer(commonAncestor);

    // When there's a special common ancestor outside of the fragment, we must include it as well to
    // preserve the structure and appearance of the fragment. For example, if the fragment contains
    // TD, we need to include the enclosing TABLE tag as well.
    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
    if (specialCommonAncestor)
        fragment->appendChild(specialCommonAncestor, ASSERT_NO_EXCEPTION);
    else
        fragment->takeAllChildrenFrom(toContainerNode(commonAncestor));

    trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get());

    return fragment;
}
Example #29
0
static String parseMediaDescriptor(const String& s)
{
    int len = s.length();

    // http://www.w3.org/TR/REC-html40/types.html#type-media-descriptors
    // "Each entry is truncated just before the first character that isn't a
    // US ASCII letter [a-zA-Z] (ISO 10646 hex 41-5a, 61-7a), digit [0-9] (hex 30-39),
    // or hyphen (hex 2d)."
    int i;
    unsigned short c;
    for (i = 0; i < len; ++i) {
        c = s[i];
        if (! ((c >= 'a' && c <= 'z')
            || (c >= 'A' && c <= 'Z')
            || (c >= '1' && c <= '9')
            || (c == '-')))
            break;
    }
    return s.left(i);
}
String EmailInputType::typeMismatchText() const
{
    String invalidAddress = findInvalidAddress(element().value());
    ASSERT(!invalidAddress.isNull());
    if (invalidAddress.isEmpty())
        return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailEmpty);
    String atSign = String("@");
    size_t atIndex = invalidAddress.find('@');
    if (atIndex == kNotFound)
        return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailNoAtSign, atSign, invalidAddress);
    // We check validity against an ASCII value because of difficulty to check
    // invalid characters. However we should show Unicode value.
    String unicodeAddress = convertEmailAddressToUnicode(invalidAddress);
    String localPart = invalidAddress.left(atIndex);
    String domain = invalidAddress.substring(atIndex + 1);
    if (localPart.isEmpty())
        return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailEmptyLocal, atSign, unicodeAddress);
    if (domain.isEmpty())
        return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailEmptyDomain, atSign, unicodeAddress);
    size_t invalidCharIndex = localPart.find(isInvalidLocalPartCharacter);
    if (invalidCharIndex != kNotFound) {
        unsigned charLength = U_IS_LEAD(localPart[invalidCharIndex]) ? 2 : 1;
        return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailInvalidLocal, atSign, localPart.substring(invalidCharIndex, charLength));
    }
    invalidCharIndex = domain.find(isInvalidDomainCharacter);
    if (invalidCharIndex != kNotFound) {
        unsigned charLength = U_IS_LEAD(domain[invalidCharIndex]) ? 2 : 1;
        return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailInvalidDomain, atSign, domain.substring(invalidCharIndex, charLength));
    }
    if (!checkValidDotUsage(domain)) {
        size_t atIndexInUnicode = unicodeAddress.find('@');
        ASSERT(atIndexInUnicode != kNotFound);
        return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmailInvalidDots, String("."), unicodeAddress.substring(atIndexInUnicode + 1));
    }
    if (element().multiple())
        return locale().queryString(WebLocalizedString::ValidationTypeMismatchForMultipleEmail);
    return locale().queryString(WebLocalizedString::ValidationTypeMismatchForEmail);
}