Пример #1
0
FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicString& family)
{
// NB: The Windows wxFont constructor has two forms, one taking a wxSize (with pixels)
// and one taking an int (points). When points are used, Windows calculates
// a pixel size using an algorithm which causes the size to be way off. However,
// this is a moot issue on Linux and Mac as they only accept the point argument. So,
// we use the pixel size constructor on Windows, but we use point size on Linux and Mac.
#if __WXMSW__
    m_font = new FontHolder(new wxFont(   wxSize(0, -desc.computedPixelSize()),
                                          fontFamilyToWxFontFamily(desc.genericFamily()),
                                          italicToWxFontStyle(desc.italic()),
                                          fontWeightToWxFontWeight(desc.weight()),
                                          false,
                                          family.string()
                                      )
                           );
#else
    m_font = new FontHolder(new wxFont(   desc.computedPixelSize(),
                                          fontFamilyToWxFontFamily(desc.genericFamily()),
                                          italicToWxFontStyle(desc.italic()),
                                          fontWeightToWxFontWeight(desc.weight()),
                                          false,
                                          family.string()
                                      )
                           );
#endif
    m_fontState = VALID;

}
Пример #2
0
PassRefPtr<Element> HTMLDocument::createElement(const AtomicString& name, ExceptionCode& ec)
{
    if (!isValidName(name)) {
        ec = INVALID_CHARACTER_ERR;
        return 0;
    }
    AtomicString lowerName = name.string().impl()->isLower() ? name : AtomicString(name.string().lower());
    return HTMLElementFactory::createHTMLElement(lowerName, this, 0, false);
}
static Variant<TextBreakIteratorICU, TextBreakIteratorPlatform> mapModeToBackingIterator(StringView string, TextBreakIterator::Mode mode, const AtomicString& locale)
{
    switch (mode) {
    case TextBreakIterator::Mode::Line:
        return TextBreakIteratorICU(string, TextBreakIteratorICU::Mode::Line, locale.string().utf8().data());
    case TextBreakIterator::Mode::Caret:
        return TextBreakIteratorICU(string, TextBreakIteratorICU::Mode::Character, locale.string().utf8().data());
    case TextBreakIterator::Mode::Delete:
        return TextBreakIteratorICU(string, TextBreakIteratorICU::Mode::Character, locale.string().utf8().data());
    default:
        ASSERT_NOT_REACHED();
        return TextBreakIteratorICU(string, TextBreakIteratorICU::Mode::Character, locale.string().utf8().data());
    }
}
Пример #4
0
void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& relStr, bool& styleSheet, bool& alternate, bool& icon)
{
    styleSheet = false;
    icon = false; 
    alternate = false;
    String rel = relStr.string().lower();
    if (rel == "stylesheet")
        styleSheet = true;
    else if (rel == "icon" || rel == "shortcut icon")
        icon = true;
    else if (rel == "alternate stylesheet" || rel == "stylesheet alternate") {
        styleSheet = true;
        alternate = true;
    } else {
        // Tokenize the rel attribute and set bits based on specific keywords that we find.
        rel.replace('\n', ' ');
        Vector<String> list;
        rel.split(' ', list);
        Vector<String>::const_iterator end = list.end();
        for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
            if (*it == "stylesheet")
                styleSheet = true;
            else if (*it == "alternate")
                alternate = true;
            else if (*it == "icon")
                icon = true;
        }
    }
}
void SVGAnimationElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (!isSupportedAttribute(name)) {
        SVGSMILElement::parseAttribute(name, value);
        return;
    }

    if (name == SVGNames::valuesAttr) {
        // Per the SMIL specification, leading and trailing white space,
        // and white space before and after semicolon separators, is allowed and will be ignored.
        // http://www.w3.org/TR/SVG11/animate.html#ValuesAttribute
        value.string().split(';', m_values);
        for (unsigned i = 0; i < m_values.size(); ++i)
            m_values[i] = m_values[i].stripWhiteSpace();

        updateAnimationMode();
        return;
    }

    if (name == SVGNames::keyTimesAttr) {
        parseKeyTimes(value, m_keyTimes, true);
        return;
    }

    if (name == SVGNames::keyPointsAttr) {
        if (hasTagName(SVGNames::animateMotionTag)) {
            // This is specified to be an animateMotion attribute only but it is simpler to put it here 
            // where the other timing calculatations are.
            parseKeyTimes(value, m_keyPoints, false);
        }
        return;
    }

    if (name == SVGNames::keySplinesAttr) {
        parseKeySplines(value, m_keySplines);
        return;
    }

    if (name == SVGNames::attributeTypeAttr) {
        setAttributeType(value);
        return;
    }

    if (name == SVGNames::calcModeAttr) {
        setCalcMode(value);
        return;
    }

    if (name == SVGNames::fromAttr || name == SVGNames::toAttr || name == SVGNames::byAttr) {
        updateAnimationMode();
        return;
    }

    if (SVGTests::parseAttribute(name, value))
        return;
    if (SVGExternalResourcesRequired::parseAttribute(name, value))
        return;

    ASSERT_NOT_REACHED();
}
Пример #6
0
void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == relAttr) {
        m_relAttribute = LinkRelAttribute(value);
        process();
    } else if (name == hrefAttr) {
        String url = stripLeadingAndTrailingHTMLSpaces(value);
        m_url = url.isEmpty() ? KURL() : document()->completeURL(url);
        process();
    } else if (name == typeAttr) {
        m_type = value;
        process();
    } else if (name == sizesAttr) {
        setSizes(value);
        process();
    } else if (name == mediaAttr) {
        m_media = value.string().lower();
        process();
    } else if (name == disabledAttr)
        setDisabledState(!value.isNull());
    else if (name == onbeforeloadAttr)
        setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, name, value));
    else if (name == onloadAttr)
        setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, name, value));
    else if (name == onerrorAttr)
        setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, name, value));
    else {
        if (name == titleAttr && m_sheet)
            m_sheet->setTitle(value);
        HTMLElement::parseAttribute(name, value);
    }
}
Пример #7
0
bool CustomElementRegistry::isValidName(const AtomicString& name)
{
    if (!nameIncludesHyphen(name))
        return false;

    DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
    if (reservedNames.isEmpty()) {
#if ENABLE(MATHML)
        reservedNames.append(MathMLNames::annotation_xmlTag.localName());
#endif

#if ENABLE(SVG)
        reservedNames.append(SVGNames::color_profileTag.localName());
        reservedNames.append(SVGNames::font_faceTag.localName());
        reservedNames.append(SVGNames::font_face_srcTag.localName());
        reservedNames.append(SVGNames::font_face_uriTag.localName());
        reservedNames.append(SVGNames::font_face_formatTag.localName());
        reservedNames.append(SVGNames::font_face_nameTag.localName());
        reservedNames.append(SVGNames::missing_glyphTag.localName());
#endif
    }

    if (notFound != reservedNames.find(name))
        return false;

    return Document::isValidName(name.string());
}
void HTMLObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    bool invalidateRenderer = false;

    if (name == formAttr)
        formAttributeChanged();
    else if (name == typeAttr) {
        m_serviceType = value.string().left(value.find(';')).convertToASCIILowercase();
        invalidateRenderer = !fastHasAttribute(classidAttr);
        setNeedsWidgetUpdate(true);
    } else if (name == dataAttr) {
        m_url = stripLeadingAndTrailingHTMLSpaces(value);
        document().updateStyleIfNeeded();
        if (isImageType() && renderer()) {
            if (!m_imageLoader)
                m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
            m_imageLoader->updateFromElementIgnoringPreviousError();
        }
        invalidateRenderer = !fastHasAttribute(classidAttr);
        setNeedsWidgetUpdate(true);
    } else if (name == classidAttr) {
        invalidateRenderer = true;
        setNeedsWidgetUpdate(true);
    } else
        HTMLPlugInImageElement::parseAttribute(name, value);

    if (!invalidateRenderer || !inDocument() || !renderer())
        return;

    clearUseFallbackContent();
    setNeedsStyleRecalc(ReconstructRenderTree);
}
Пример #9
0
void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == relAttr) {
        m_relAttribute = LinkRelAttribute(value);
        process();
    } else if (name == hrefAttr) {
        process();
    } else if (name == typeAttr) {
        m_type = value;
        process();
    } else if (name == sizesAttr) {
        setSizes(value);
        process();
    } else if (name == mediaAttr) {
        m_media = value.string().lower();
        process();
    } else if (name == disabledAttr)
        setDisabledState(!value.isNull());
    else if (name == onbeforeloadAttr)
        setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, name, value));
    else {
        if (name == titleAttr && m_sheet)
            m_sheet->setTitle(value);
        HTMLElement::parseAttribute(name, value);
    }
}
Пример #10
0
void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == relAttr) {
        m_relAttribute = LinkRelAttribute(value);
        process();
    } else if (name == hrefAttr) {
        process();
    } else if (name == typeAttr) {
        m_type = value;
        process();
    } else if (name == sizesAttr) {
        m_sizes->setValue(value);
        process();
    } else if (name == mediaAttr) {
        m_media = value.string().lower();
        process();
    } else if (name == disabledAttr) {
        if (LinkStyle* link = linkStyle())
            link->setDisabledState(!value.isNull());
    } else if (name == onbeforeloadAttr)
        setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
    else {
        if (name == titleAttr) {
            if (LinkStyle* link = linkStyle())
                link->setSheetTitle(value);
        }

        HTMLElement::parseAttribute(name, value);
    }
}
void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
{
    if (!Document::isValidName(name)) {
        ec = INVALID_CHARACTER_ERR;
        return;
    }

    const AtomicString& localName = (shouldIgnoreAttributeCase(this) && !name.string().impl()->isLower()) ? AtomicString(name.string().lower()) : name;

    // allocate attributemap if necessary
    Attribute* old = attributes(false)->getAttributeItem(localName, false);

    document()->incDOMTreeVersion();

    if (localName == idAttr.localName())
        updateId(old ? old->value() : nullAtom, value);
    
    if (old && value.isNull())
        namedAttrMap->removeAttribute(old->name());
    else if (!old && !value.isNull())
        namedAttrMap->addAttribute(createAttribute(QualifiedName(nullAtom, localName, nullAtom), value));
    else if (old && !value.isNull()) {
        old->setValue(value);
        attributeChanged(old);
    }
}
Пример #12
0
void HTMLObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == formAttr)
        formAttributeChanged();
    else if (name == typeAttr) {
        m_serviceType = value.string().left(value.find(';')).lower();
        setNeedsWidgetUpdate(true);
    } else if (name == dataAttr) {
        m_url = stripLeadingAndTrailingHTMLSpaces(value);
        setNeedsWidgetUpdate(true);
        document().updateStyleIfNeeded();
        if (renderer()) {
            if (isImageType()) {
                if (!m_imageLoader)
                    m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
                m_imageLoader->updateFromElementIgnoringPreviousError();
            }
        }
    } else if (name == classidAttr)
        setNeedsWidgetUpdate(true);
    else if (name == onbeforeloadAttr)
        setAttributeEventListener(eventNames().beforeloadEvent, name, value);
    else
        HTMLPlugInImageElement::parseAttribute(name, value);
}
Пример #13
0
HRESULT STDMETHODCALLTYPE DOMElement::font(WebFontDescription* webFontDescription)
{
    if (!webFontDescription) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    ASSERT(m_element);

    WebCore::RenderElement* renderer = m_element->renderer();
    if (!renderer)
        return E_FAIL;

    FontDescription fontDescription = renderer->style().fontCascade().fontDescription();
    AtomicString family = fontDescription.firstFamily();

    // FIXME: This leaks. Delete this whole function to get rid of the leak.
    UChar* familyCharactersBuffer = new UChar[family.length()];
    StringView(family.string()).getCharactersWithUpconvert(familyCharactersBuffer);

    webFontDescription->family = familyCharactersBuffer;
    webFontDescription->familyLength = family.length();
    webFontDescription->size = fontDescription.computedSize();
    webFontDescription->bold = fontDescription.weight() >= WebCore::FontWeight600;
    webFontDescription->italic = fontDescription.italic();

    return S_OK;
}
Пример #14
0
void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, bool& styleSheet, bool& alternate, bool& icon, bool& dnsPrefetch)
{
    styleSheet = false;
    icon = false; 
    alternate = false;
    dnsPrefetch = false;
    if (equalIgnoringCase(rel, "stylesheet"))
        styleSheet = true;
    else if (equalIgnoringCase(rel, "icon") || equalIgnoringCase(rel, "shortcut icon"))
        icon = true;
    else if (equalIgnoringCase(rel, "dns-prefetch"))
        dnsPrefetch = true;
    else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
        styleSheet = true;
        alternate = true;
    } else {
        // Tokenize the rel attribute and set bits based on specific keywords that we find.
        String relString = rel.string();
        relString.replace('\n', ' ');
        Vector<String> list;
        relString.split(' ', list);
        Vector<String>::const_iterator end = list.end();
        for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
            if (equalIgnoringCase(*it, "stylesheet"))
                styleSheet = true;
            else if (equalIgnoringCase(*it, "alternate"))
                alternate = true;
            else if (equalIgnoringCase(*it, "icon"))
                icon = true;
        }
    }
}
Пример #15
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);
    }
}
Пример #16
0
bool elementPatternIndicatesHexadecimal(const HTMLInputElement* inputElement)
{
    if (!inputElement)
        return false;

    if (inputElement->fastHasAttribute(HTMLNames::patternAttr)) {
        AtomicString patternAttribute = inputElement->fastGetAttribute(HTMLNames::patternAttr);
        if (patternAttribute.startsWith("[0-9a-fA-F]")) {
            // The pattern is for hexadecimal, make sure nothing else is permitted.

            // Check if it was an exact match.
            if (patternAttribute.length() == 11)
                return true;

            // Is the regex specifying a character count?
            if (patternAttribute[11] != '{' || !patternAttribute.endsWith("}"))
                return false;

            int count = 0;
            // Make sure the number in the regex is actually a number.
            if ((sscanf(patternAttribute.string().latin1().data(), "[0-9a-fA-F]{%d}\0", &count) == 1) && count > 0)
                return true;
        }
    }

    return false;
}
Пример #17
0
void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == relAttr) {
        m_relAttribute = LinkRelAttribute(value);
        process();
    } else if (name == hrefAttr) {
        process();
    } else if (name == typeAttr) {
        m_type = value;
        process();
    } else if (name == sizesAttr) {
        m_sizes->setValue(value);
        parseSizesAttribute(value, m_iconSizes);
        process();
    } else if (name == mediaAttr) {
        m_media = value.string().lower();
        process();
    } else if (name == disabledAttr) {
        if (LinkStyle* link = linkStyle())
            link->setDisabledState(!value.isNull());
    } else {
        if (name == titleAttr) {
            if (LinkStyle* link = linkStyle())
                link->setSheetTitle(value);
        }

        HTMLElement::parseAttribute(name, value);
    }
}
Пример #18
0
bool canHyphenate(const AtomicString& localeIdentifier)
{
    if (localeIdentifier.isNull())
        return false;
    if (availableLocales().contains(localeIdentifier))
        return true;
    return availableLocales().contains(AtomicString(localeIdentifier.string().convertToASCIILowercase()));
}
Пример #19
0
PassOwnPtr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    // wx will ALWAYS create a valid font, even if the font family we're looking for is not available.
    // So we check to make sure the font is the one we're looking for before creating the font.
    if (!wxFontEnumerator::IsValidFacename(family.string()))
        return nullptr;

    return adoptPtr(new FontPlatformData(fontDescription, family));
}
Пример #20
0
LinkHash visitedLinkHash(const KURL& base, const AtomicString& relative)
{
    if (relative.isNull())
        return 0;
    url_canon::RawCanonOutput<2048> buffer;
    if (!resolveRelative(base, relative.string(), &buffer))
        return 0;
    return WebKit::Platform::current()->visitedLinkHash(buffer.data(), buffer.length());
}
Пример #21
0
size_t lastHyphenLocation(StringView string, size_t beforeIndex, const AtomicString& localeIdentifier)
{
    // libhyphen accepts strings in UTF-8 format, but WebCore can only provide StringView
    // which stores either UTF-16 or Latin1 data. This is unfortunate for performance
    // reasons and we should consider switching to a more flexible hyphenation library
    // if it is available.
    CString utf8StringCopy = string.toStringWithoutCopying().utf8();

    // WebCore often passes strings like " wordtohyphenate" to the platform layer. Since
    // libhyphen isn't advanced enough to deal with leading spaces (presumably CoreFoundation
    // can), we should find the appropriate indexes into the string to skip them.
    int32_t leadingSpaceBytes;
    int32_t leadingSpaceCharacters;
    countLeadingSpaces(utf8StringCopy, leadingSpaceBytes, leadingSpaceCharacters);

    // The libhyphen documentation specifies that this array should be 5 bytes longer than
    // the byte length of the input string.
    Vector<char> hyphenArray(utf8StringCopy.length() - leadingSpaceBytes + 5);
    char* hyphenArrayData = hyphenArray.data();

    String lowercaseLocaleIdentifier = AtomicString(localeIdentifier.string().convertToASCIILowercase());
    ASSERT(availableLocales().contains(lowercaseLocaleIdentifier));
    for (const auto& dictionaryPath : availableLocales().get(lowercaseLocaleIdentifier)) {
        RefPtr<HyphenationDictionary> dictionary = TinyLRUCachePolicy<AtomicString, RefPtr<HyphenationDictionary>>::cache().get(AtomicString(dictionaryPath));

        char** replacements = nullptr;
        int* positions = nullptr;
        int* removedCharacterCounts = nullptr;
        hnj_hyphen_hyphenate2(dictionary->libhyphenDictionary(),
            utf8StringCopy.data() + leadingSpaceBytes,
            utf8StringCopy.length() - leadingSpaceBytes,
            hyphenArrayData,
            nullptr, /* output parameter for hyphenated word */
            &replacements,
            &positions,
            &removedCharacterCounts);

        if (replacements) {
            for (unsigned i = 0; i < utf8StringCopy.length() - leadingSpaceBytes - 1; i++)
                free(replacements[i]);
            free(replacements);
        }

        free(positions);
        free(removedCharacterCounts);

        for (int i = beforeIndex - leadingSpaceCharacters - 2; i >= 0; i--) {
            // libhyphen will put an odd number in hyphenArrayData at all
            // hyphenation points. A number & 1 will be true for odd numbers.
            if (hyphenArrayData[i] & 1)
                return i + 1 + leadingSpaceCharacters;
        }
    }

    return 0;
}
Пример #22
0
String HTMLImageLoader::sourceURI(const AtomicString& attr) const
{
#if ENABLE(DASHBOARD_SUPPORT)
    Settings* settings = client()->sourceElement()->document()->settings();
    if (settings && settings->usesDashboardBackwardCompatibilityMode() && attr.length() > 7 && attr.startsWith("url(\"") && attr.endsWith("\")"))
        return attr.string().substring(5, attr.length() - 7);
#endif

    return stripLeadingAndTrailingHTMLSpaces(attr);
}
Пример #23
0
void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == altAttr) {
        if (renderer() && renderer()->isRenderImage())
            toRenderImage(renderer())->updateAltText();
    } else if (name == srcAttr || name == srcsetAttr) {
        ImageWithScale candidate = bestFitSourceForImageAttributes(document().deviceScaleFactor(), fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr));
        m_bestFitImageURL = candidate.imageURL(fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr));
        float candidateScaleFactor = candidate.scaleFactor();
        if (candidateScaleFactor > 0)
            m_imageDevicePixelRatio = 1 / candidateScaleFactor;
        if (renderer() && renderer()->isImage())
            toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRatio);
        m_imageLoader.updateFromElementIgnoringPreviousError();
    } else if (name == usemapAttr) {
        setIsLink(!value.isNull() && !shouldProhibitLinks(this));

        if (inDocument() && !m_lowercasedUsemap.isNull())
            document().removeImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);

        // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning, which has to be stripped off.
        // FIXME: We should check that the first character is '#'.
        // FIXME: HTML5 specification says we should strip any leading string before '#'.
        // FIXME: HTML5 specification says we should ignore usemap attributes without #.
        if (value.length() > 1)
            m_lowercasedUsemap = value.string().substring(1).lower();
        else
            m_lowercasedUsemap = nullAtom;

        if (inDocument() && !m_lowercasedUsemap.isNull())
            document().addImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
    } else if (name == onbeforeloadAttr)
        setAttributeEventListener(eventNames().beforeloadEvent, name, value);
    else if (name == compositeAttr) {
        // FIXME: images don't support blend modes in their compositing attribute.
        BlendMode blendOp = BlendModeNormal;
        if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp))
            m_compositeOperator = CompositeSourceOver;
    } else {
        if (name == nameAttr) {
            bool willHaveName = !value.isNull();
            if (hasName() != willHaveName && inDocument() && document().isHTMLDocument()) {
                HTMLDocument* document = toHTMLDocument(&this->document());
                const AtomicString& id = getIdAttribute();
                if (!id.isEmpty() && id != getNameAttribute()) {
                    if (willHaveName)
                        document->addDocumentNamedItem(*id.impl(), *this);
                    else
                        document->removeDocumentNamedItem(*id.impl(), *this);
                }
            }
        }
        HTMLElement::parseAttribute(name, value);
    }
}
Пример #24
0
void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute& relAttribute)
{
    relAttribute.m_isStyleSheet = false;
    relAttribute.m_isIcon = false;
    relAttribute.m_isAlternate = false;
    relAttribute.m_isDNSPrefetch = false;
#if ENABLE(LINK_PREFETCH)
    relAttribute.m_isLinkPrefetch = false;
    relAttribute.m_isLinkPrerender = false;
    relAttribute.m_isLinkSubresource = false;
#endif
#ifdef ANDROID_APPLE_TOUCH_ICON
    relAttribute.m_isTouchIcon = false;
    relAttribute.m_isPrecomposedTouchIcon = false;
#endif
    if (equalIgnoringCase(rel, "stylesheet"))
        relAttribute.m_isStyleSheet = true;
    else if (equalIgnoringCase(rel, "icon") || equalIgnoringCase(rel, "shortcut icon"))
        relAttribute.m_isIcon = true;
#ifdef ANDROID_APPLE_TOUCH_ICON
    else if (equalIgnoringCase(rel, "apple-touch-icon"))
        relAttribute.m_isTouchIcon = true;
    else if (equalIgnoringCase(rel, "apple-touch-icon-precomposed"))
        relAttribute.m_isPrecomposedTouchIcon = true;
#endif
    else if (equalIgnoringCase(rel, "dns-prefetch"))
        relAttribute.m_isDNSPrefetch = true;
    else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
        relAttribute.m_isStyleSheet = true;
        relAttribute.m_isAlternate = true;
    } else {
        // Tokenize the rel attribute and set bits based on specific keywords that we find.
        String relString = rel.string();
        relString.replace('\n', ' ');
        Vector<String> list;
        relString.split(' ', list);
        Vector<String>::const_iterator end = list.end();
        for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
            if (equalIgnoringCase(*it, "stylesheet"))
                relAttribute.m_isStyleSheet = true;
            else if (equalIgnoringCase(*it, "alternate"))
                relAttribute.m_isAlternate = true;
            else if (equalIgnoringCase(*it, "icon"))
                relAttribute.m_isIcon = true;
#if ENABLE(LINK_PREFETCH)
            else if (equalIgnoringCase(*it, "prefetch"))
              relAttribute.m_isLinkPrefetch = true;
            else if (equalIgnoringCase(*it, "prerender"))
              relAttribute.m_isLinkPrerender = true;
            else if (equalIgnoringCase(*it, "subresource"))
              relAttribute.m_isLinkSubresource = true;
#endif
        }
    }
}
Пример #25
0
FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicString& family)
{
// NB: The Windows wxFont constructor has two forms, one taking a wxSize (with pixels)
// and one taking an int (points). When points are used, Windows calculates
// a pixel size using an algorithm which causes the size to be way off. However,
// this is a moot issue on Linux and Mac as they only accept the point argument. So,
// we use the pixel size constructor on Windows, but we use point size on Linux and Mac.
#if __WXMSW__
    m_font = adoptRef(new FontHolder(new wxFont(   wxSize(0, -desc.computedPixelSize()), 
                                fontFamilyToWxFontFamily(desc.genericFamily()), 
                                italicToWxFontStyle(desc.italic()),
                                fontWeightToWxFontWeight(desc.weight()),
                                false,
                                family.string()
                            )
                        )); 
#else
    m_font = adoptRef(new FontHolder(new wxFont(   desc.computedPixelSize(), 
                                fontFamilyToWxFontFamily(desc.genericFamily()), 
                                italicToWxFontStyle(desc.italic()),
                                fontWeightToWxFontWeight(desc.weight()),
                                false,
                                family.string()
                            )
                        )); 
#endif
#if OS(DARWIN)
#if !wxOSX_USE_CORE_TEXT
#if wxCHECK_VERSION(2,9,0)
    m_atsuFontID = m_font->font()->OSXGetATSUFontID();
#else
    m_atsuFontID = m_font->font()->MacGetATSUFontID();
#endif
#endif
    m_nsFont = 0;
    cacheNSFont();
#endif
    m_size = desc.computedPixelSize();
    m_fontState = VALID;
    m_size = desc.computedPixelSize();
}
Пример #26
0
v8::Handle<v8::Function> V8AdaptorFunction::wrap(v8::Handle<v8::Object> object, const AtomicString& name, v8::Isolate* isolate)
{
    if (object.IsEmpty() || !object->IsObject())
        return v8::Handle<v8::Function>();
    v8::Handle<v8::Function> adaptor = v8::Handle<v8::Function>::Cast(getTemplate(isolate)->GetFunction());
    if (adaptor.IsEmpty())
        return v8::Handle<v8::Function>();
    adaptor->SetName(v8String(name.string(), isolate));
    adaptor->SetHiddenValue(V8HiddenPropertyName::adaptorFunctionPeer(), object);
    object->SetHiddenValue(V8HiddenPropertyName::adaptorFunctionPeer(), adaptor);
    return adaptor;
}
Пример #27
0
void SVGFontElement::ensureGlyphCache()
{
    if (m_isGlyphCacheValid)
        return;

    KerningPairVector horizontalKerningPairs;
    KerningPairVector verticalKerningPairs;

    SVGMissingGlyphElement* firstMissingGlyphElement = 0;
    Vector<String> ligatures;
    for (SVGElement* element = Traversal<SVGElement>::firstChild(*this); element; element = Traversal<SVGElement>::nextSibling(*element)) {
        if (isSVGGlyphElement(*element)) {
            SVGGlyphElement& glyph = toSVGGlyphElement(*element);
            AtomicString unicode = glyph.fastGetAttribute(SVGNames::unicodeAttr);
            AtomicString glyphId = glyph.getIdAttribute();
            if (glyphId.isEmpty() && unicode.isEmpty())
                continue;

            m_glyphMap.addGlyph(glyphId, unicode, glyph.buildGlyphIdentifier());

            // Register ligatures, if needed, don't mix up with surrogate pairs though!
            if (unicode.length() > 1 && !U16_IS_SURROGATE(unicode[0]))
                ligatures.append(unicode.string());
        } else if (isSVGHKernElement(*element)) {
            toSVGHKernElement(*element).buildHorizontalKerningPair(horizontalKerningPairs);
        } else if (isSVGVKernElement(*element)) {
            toSVGVKernElement(*element).buildVerticalKerningPair(verticalKerningPairs);
        } else if (isSVGMissingGlyphElement(*element) && !firstMissingGlyphElement) {
            firstMissingGlyphElement = toSVGMissingGlyphElement(element);
        }
    }

    // Build the kerning tables.
    buildKerningTable(horizontalKerningPairs, m_horizontalKerningTable);
    buildKerningTable(verticalKerningPairs, m_verticalKerningTable);

    // The glyph-name->glyph-id map won't be needed/used after having built the kerning table(s).
    m_glyphMap.dropNamedGlyphMap();

    // Register each character of each ligature, if needed.
    if (!ligatures.isEmpty())
        registerLigaturesInGlyphCache(ligatures);

    // Register missing-glyph element, if present.
    if (firstMissingGlyphElement) {
        SVGGlyph svgGlyph = SVGGlyphElement::buildGenericGlyphIdentifier(firstMissingGlyphElement);
        m_glyphMap.appendToGlyphTable(svgGlyph);
        m_missingGlyph = svgGlyph.tableEntry;
        ASSERT(m_missingGlyph > 0);
    }

    m_isGlyphCacheValid = true;
}
Пример #28
0
static CSSSelector::PseudoType nameToPseudoType(const AtomicString& name)
{
    if (name.isNull() || !name.is8Bit())
        return CSSSelector::PseudoUnknown;

    const NameToPseudoStruct* pseudoTypeMapEnd = pseudoTypeMap + WTF_ARRAY_LENGTH(pseudoTypeMap);
    NameToPseudoStruct dummyKey = { 0, CSSSelector::PseudoUnknown };
    const NameToPseudoStruct* match = std::lower_bound(pseudoTypeMap, pseudoTypeMapEnd, dummyKey, NameToPseudoCompare(name));
    if (match == pseudoTypeMapEnd || match->string != name.string())
        return CSSSelector::PseudoUnknown;

    return static_cast<CSSSelector::PseudoType>(match->type);
}
Пример #29
0
void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (name == altAttr) {
        if (is<RenderImage>(renderer()))
            downcast<RenderImage>(*renderer()).updateAltText();
    } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr)
        selectImageSource();
    else if (name == usemapAttr) {
        if (inDocument() && !m_lowercasedUsemap.isNull())
            document().removeImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);

        // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning, which has to be stripped off.
        // FIXME: We should check that the first character is '#'.
        // FIXME: HTML5 specification says we should strip any leading string before '#'.
        // FIXME: HTML5 specification says we should ignore usemap attributes without #.
        if (value.length() > 1)
            m_lowercasedUsemap = value.string().substring(1).lower();
        else
            m_lowercasedUsemap = nullAtom;

        if (inDocument() && !m_lowercasedUsemap.isNull())
            document().addImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
    } else if (name == compositeAttr) {
        // FIXME: images don't support blend modes in their compositing attribute.
        BlendMode blendOp = BlendModeNormal;
        if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp))
            m_compositeOperator = CompositeSourceOver;
#if ENABLE(SERVICE_CONTROLS)
    } else if (name == webkitimagemenuAttr) {
        m_experimentalImageMenuEnabled = !value.isNull();
        updateImageControls();
#endif
    } else {
        if (name == nameAttr) {
            bool willHaveName = !value.isNull();
            if (m_hadNameBeforeAttributeChanged != willHaveName && inDocument() && is<HTMLDocument>(document())) {
                HTMLDocument& document = downcast<HTMLDocument>(this->document());
                const AtomicString& id = getIdAttribute();
                if (!id.isEmpty() && id != getNameAttribute()) {
                    if (willHaveName)
                        document.addDocumentNamedItem(*id.impl(), *this);
                    else
                        document.removeDocumentNamedItem(*id.impl(), *this);
                }
            }
            m_hadNameBeforeAttributeChanged = willHaveName;
        }
        HTMLElement::parseAttribute(name, value);
    }
}
Пример #30
0
void SVGFontElement::ensureGlyphCache()
{
    if (m_isGlyphCacheValid)
        return;

    const SVGMissingGlyphElement* firstMissingGlyphElement = nullptr;
    Vector<String> ligatures;
    for (auto& child : childrenOfType<SVGElement>(*this)) {
        if (is<SVGGlyphElement>(child)) {
            SVGGlyphElement& glyph = downcast<SVGGlyphElement>(child);
            AtomicString unicode = glyph.fastGetAttribute(SVGNames::unicodeAttr);
            AtomicString glyphId = glyph.getIdAttribute();
            if (glyphId.isEmpty() && unicode.isEmpty())
                continue;

            m_glyphMap.addGlyph(glyphId, unicode, glyph.buildGlyphIdentifier());

            // Register ligatures, if needed, don't mix up with surrogate pairs though!
            if (unicode.length() > 1 && !U16_IS_SURROGATE(unicode[0]))
                ligatures.append(unicode.string());
        } else if (is<SVGHKernElement>(child)) {
            SVGHKernElement& hkern = downcast<SVGHKernElement>(child);
            SVGKerningPair kerningPair;
            if (hkern.buildHorizontalKerningPair(kerningPair))
                m_horizontalKerningMap.insert(kerningPair);
        } else if (is<SVGVKernElement>(child)) {
            SVGVKernElement& vkern = downcast<SVGVKernElement>(child);
            SVGKerningPair kerningPair;
            if (vkern.buildVerticalKerningPair(kerningPair))
                m_verticalKerningMap.insert(kerningPair);
        } else if (is<SVGMissingGlyphElement>(child) && !firstMissingGlyphElement)
            firstMissingGlyphElement = &downcast<SVGMissingGlyphElement>(child);
    }

    // Register each character of each ligature, if needed.
    if (!ligatures.isEmpty())
        registerLigaturesInGlyphCache(ligatures);

    // Register missing-glyph element, if present.
    if (firstMissingGlyphElement) {
        SVGGlyph svgGlyph = SVGGlyphElement::buildGenericGlyphIdentifier(firstMissingGlyphElement);
        m_glyphMap.appendToGlyphTable(svgGlyph);
        m_missingGlyph = svgGlyph.tableEntry;
        ASSERT(m_missingGlyph > 0);
    }

    m_isGlyphCacheValid = true;
}