void FirstLetterPseudoElement::updateTextFragments()
{
    String oldText =  m_remainingTextLayoutObject->completeText();
    ASSERT(oldText.impl());

    unsigned length = FirstLetterPseudoElement::firstLetterLength(oldText);
    m_remainingTextLayoutObject->setTextFragment(oldText.impl()->substring(length, oldText.length()), length, oldText.length() - length);
    m_remainingTextLayoutObject->dirtyLineBoxes();

    for (auto child = layoutObject()->slowFirstChild(); child; child = child->nextSibling()) {
        if (!child->isText() || !toLayoutText(child)->isTextFragment())
            continue;
        LayoutTextFragment* childFragment = toLayoutTextFragment(child);
        if (childFragment->firstLetterPseudoElement() != this)
            continue;

        childFragment->setTextFragment(oldText.impl()->substring(0, length), 0, length);
        childFragment->dirtyLineBoxes();

        // Make sure the first-letter layoutObject is set to require a layout as it
        // needs to re-create the line boxes. The remaining text layoutObject
        // will be marked by the LayoutText::setText.
        childFragment->setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::TextChanged);
        break;
    }
}
bool WebPolicyClient::decidePolicyForMIMEType(WebPageProxy* page, const String& MIMEType, const String& url, WebFrameProxy* frame, WebFramePolicyListenerProxy* listener)
{
    if (!m_client.decidePolicyForMIMEType)
        return false;

    m_client.decidePolicyForMIMEType(toAPI(page), toAPI(MIMEType.impl()), toURLRef(url.impl()), toAPI(frame), toAPI(listener), m_client.clientInfo);
    return true;
}
Example #3
0
void OriginUsageRecord::addDatabase(const String& identifier, const String& fullPath)
{
    ASSERT(!m_databaseMap.contains(identifier));
    ASSERT_ARG(identifier, identifier.impl()->hasOneRef() || identifier.isEmpty());
    ASSERT_ARG(fullPath, fullPath.impl()->hasOneRef() || fullPath.isEmpty());

    m_databaseMap.set(identifier, DatabaseEntry(fullPath));
    m_unknownSet.add(identifier);

    m_cachedDiskUsageIsValid = false;
}
Example #4
0
void CharacterData::setData(const String& data, ExceptionCode&)
{
    StringImpl* dataImpl = data.impl() ? data.impl() : StringImpl::empty();
    if (equal(m_data.get(), dataImpl))
        return;

    unsigned oldLength = length();

    setDataAndUpdate(dataImpl, 0, oldLength, dataImpl->length());
    document()->textRemoved(this, 0, oldLength);
}
CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitTypes type)
    : m_type(type)
    , m_hasCachedCSSText(false)
{
    if ((m_value.string = str.impl()))
        m_value.string->ref();
}
Example #6
0
PluginModuleLoadPolicy WebUIClient::pluginLoadPolicy(WebPageProxy* page, const String& identifier, const String& displayName, const String& documentURLString, PluginModuleLoadPolicy currentPluginLoadPolicy)
{
    if (!m_client.pluginLoadPolicy)
        return currentPluginLoadPolicy;

    return toPluginModuleLoadPolicy(m_client.pluginLoadPolicy(toAPI(page), toAPI(identifier.impl()), toAPI(displayName.impl()), toURLRef(documentURLString.impl()), toWKPluginLoadPolicy(currentPluginLoadPolicy), m_client.clientInfo));
}
Example #7
0
void WebUIClient::saveDataToFileInDownloadsFolder(WebPageProxy* page, const String& suggestedFilename, const String& mimeType, const String& originatingURLString, WebData* data)
{
    if (!m_client.saveDataToFileInDownloadsFolder)
        return;

    m_client.saveDataToFileInDownloadsFolder(toAPI(page), toAPI(suggestedFilename.impl()), toAPI(mimeType.impl()), toURLRef(originatingURLString.impl()), toAPI(data), m_client.clientInfo);
}
Example #8
0
bool WebUIClient::runBeforeUnloadConfirmPanel(WebPageProxy* page, const String& message, WebFrameProxy* frame)
{
    if (!m_client.runBeforeUnloadConfirmPanel)
        return true;

    return m_client.runBeforeUnloadConfirmPanel(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.clientInfo);
}
Example #9
0
void WebUIClient::setStatusText(WebPageProxy* page, const String& text)
{
    if (!m_client.setStatusText)
        return;

    m_client.setStatusText(toAPI(page), toAPI(text.impl()), m_client.clientInfo);
}
Example #10
0
bool WebUIClient::runJavaScriptConfirm(WebPageProxy* page, const String& message, WebFrameProxy* frame)
{
    if (!m_client.runJavaScriptConfirm)
        return false;

    return m_client.runJavaScriptConfirm(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.clientInfo);
}
Example #11
0
void WebUIClient::runJavaScriptAlert(WebPageProxy* page, const String& message, WebFrameProxy* frame)
{
    if (!m_client.runJavaScriptAlert)
        return;
    
    m_client.runJavaScriptAlert(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.clientInfo);
}
PassRefPtr<StringImpl> RenderCounter::originalText() const
{
    if (!parent())
        return 0;

    if (!m_counterNode)
        m_counterNode = makeCounterNode(parent(), m_counter.identifier(), true);

    CounterNode* child = m_counterNode;
    int value = child->actsAsReset() ? child->value() : child->countInParent();

    String text = listMarkerText(m_counter.listStyle(), value);

    if (!m_counter.separator().isNull()) {
        if (!child->actsAsReset())
            child = child->parent();
        while (CounterNode* parent = child->parent()) {
            text = listMarkerText(m_counter.listStyle(), child->countInParent())
                + m_counter.separator() + text;
            child = parent;
        }
    }

    return text.impl();
}
Example #13
0
void WebContextInjectedBundleClient::didRecieveMessageFromInjectedBundle(WebContext* context, const String& message)
{
    if (!m_client.didRecieveMessageFromInjectedBundle)
        return;

    m_client.didRecieveMessageFromInjectedBundle(toRef(context), toRef(message.impl()), m_client.clientInfo);
}
Example #14
0
 void write(const String& str)
 {
     if (str.isEmpty())
         write(m_emptyIdentifier);
     else
         write(Identifier(m_exec, str.impl()));
 }
Example #15
0
TEST(StringBuilderTest, ToString)
{
    StringBuilder builder;
    builder.append("0123456789");
    String string = builder.toString();
    ASSERT_EQ(String("0123456789"), string);
    ASSERT_EQ(string.impl(), builder.toString().impl());

    // Changing the StringBuilder should not affect the original result of toString().
    builder.append("abcdefghijklmnopqrstuvwxyz");
    ASSERT_EQ(String("0123456789"), string);

    // Changing the StringBuilder should not affect the original result of toString() in case the capacity is not changed.
    builder.reserveCapacity(200);
    string = builder.toString();
    ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyz"), string);
    builder.append("ABC");
    ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyz"), string);

    // Changing the original result of toString() should not affect the content of the StringBuilder.
    String string1 = builder.toString();
    ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyzABC"), string1);
    string1.append("DEF");
    ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyzABC"), builder.toString());
    ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyzABCDEF"), string1);

    // Resizing the StringBuilder should not affect the original result of toString().
    string1 = builder.toString();
    builder.resize(10);
    builder.append("###");
    ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyzABC"), string1);
}
void WebContextInjectedBundleClient::didReceiveMessageFromInjectedBundle(WebContext* context, const String& messageName, APIObject* messageBody)
{
    if (!m_client.didReceiveMessageFromInjectedBundle)
        return;

    m_client.didReceiveMessageFromInjectedBundle(toAPI(context), toAPI(messageName.impl()), toAPI(messageBody), m_client.clientInfo);
}
Example #17
0
void StyledElement::addCSSLength(Attribute* attr, int id, const String &value)
{
    // FIXME: This function should not spin up the CSS parser, but should instead just figure out the correct
    // length unit and make the appropriate parsed value.
    if (!attr->decl())
        createMappedDecl(attr);

    // strip attribute garbage..
    StringImpl* v = value.impl();
    if (v) {
        unsigned int l = 0;

        while (l < v->length() && (*v)[l] <= ' ')
            l++;

        for (; l < v->length(); l++) {
            UChar cc = (*v)[l];
            if (cc > '9')
                break;
            if (cc < '0') {
                if (cc == '%' || cc == '*')
                    l++;
                if (cc != '.')
                    break;
            }
        }

        if (l != v->length()) {
            attr->decl()->setLengthProperty(id, v->substring(0, l), false);
            return;
        }
    }

    attr->decl()->setLengthProperty(id, value, false);
}
Example #18
0
void HTMLElement::addHTMLLengthToStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, const String& value)
{
    // FIXME: This function should not spin up the CSS parser, but should instead just figure out the correct
    // length unit and make the appropriate parsed value.

    // strip attribute garbage..
    StringImpl* v = value.impl();
    if (v) {
        unsigned length = 0;

        while (length < v->length() && (*v)[length] <= ' ')
            length++;

        for (; length < v->length(); length++) {
            UChar cc = (*v)[length];
            if (cc > '9')
                break;
            if (cc < '0') {
                if (cc == '%' || cc == '*')
                    length++;
                if (cc != '.')
                    break;
            }
        }

        if (length != v->length()) {
            addPropertyToPresentationAttributeStyle(style, propertyID, v->substring(0, length));
            return;
        }
    }

    addPropertyToPresentationAttributeStyle(style, propertyID, value);
}
Example #19
0
void RenderListBox::updateFromElement()
{
    if (m_optionsChanged) {
        const Vector<Element*>& listItems = toSelectElement(static_cast<Element*>(node()))->listItems();
        int size = numItems();
        
        float width = 0;
        for (int i = 0; i < size; ++i) {
            Element* element = listItems[i];
            String text;
            Font itemFont = style()->font();
            if (OptionElement* optionElement = toOptionElement(element))
                text = optionElement->textIndentedToRespectGroupLabel();
            else if (OptionGroupElement* optionGroupElement = toOptionGroupElement(element)) {
                text = optionGroupElement->groupLabelText();
                FontDescription d = itemFont.fontDescription();
                d.setWeight(d.bolderWeight());
                itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
                itemFont.update(document()->styleSelector()->fontSelector());
            }
                
            if (!text.isEmpty()) {
                float textWidth = itemFont.floatWidth(TextRun(text.impl(), 0, 0, 0, false, false, false, false));
                width = max(width, textWidth);
            }
        }
        m_optionsWidth = static_cast<int>(ceilf(width));
        m_optionsChanged = false;
        
        setHasVerticalScrollbar(true);

        setNeedsLayoutAndPrefWidthsRecalc();
    }
}
Example #20
0
std::unique_ptr<Length[]> newLengthArray(const String& string, int& len)
{
    RefPtr<StringImpl> str = string.impl()->simplifyWhiteSpace();
    if (!str->length()) {
        len = 1;
        return nullptr;
    }

    len = countCharacter(str->deprecatedCharacters(), str->length(), ',') + 1;
    auto r = std::make_unique<Length[]>(len);

    int i = 0;
    unsigned pos = 0;
    size_t pos2;

    while ((pos2 = str->find(',', pos)) != notFound) {
        r[i++] = parseLength(str->deprecatedCharacters() + pos, pos2 - pos);
        pos = pos2+1;
    }

    ASSERT(i == len - 1);

    // IE Quirk: If the last comma is the last char skip it and reduce len by one.
    if (str->length()-pos > 0)
        r[i] = parseLength(str->deprecatedCharacters() + pos, str->length() - pos);
    else
        len--;

    return r;
}
ContentData* RenderStyle::prepareToSetContent(StringImpl* string, bool add)
{
    OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
    ContentData* lastContent = content.get();
    while (lastContent && lastContent->next())
        lastContent = lastContent->next();

    if (string && add && lastContent && lastContent->isText()) {
        // Augment the existing string and share the existing ContentData node.
        String newText = lastContent->text();
        newText.append(string);
        lastContent->setText(newText.impl());
        return 0;
    }

    bool reuseContent = !add;
    OwnPtr<ContentData> newContentData;
    if (reuseContent && content) {
        content->clear();
        newContentData = content.release();
    } else
        newContentData = adoptPtr(new ContentData);

    ContentData* result = newContentData.get();

    if (lastContent && !reuseContent)
        lastContent->setNext(newContentData.release());
    else
        content = newContentData.release();

    return result;
}
Example #22
0
CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitTypes type)
    : CSSValue(PrimitiveClass)
{
    m_primitiveUnitType = type;
    if ((m_value.string = str.impl()))
        m_value.string->ref();
}
Example #23
0
PassRefPtr<StringImpl> RenderCounter::originalText() const
{
    if (!m_counterNode) {
        RenderObject* beforeAfterContainer = parent();
        while (true) {
            if (!beforeAfterContainer)
                return nullptr;
            if (!beforeAfterContainer->isAnonymous() && !beforeAfterContainer->isPseudoElement())
                return nullptr; // RenderCounters are restricted to before and after pseudo elements
            PseudoId containerStyle = beforeAfterContainer->style()->styleType();
            if ((containerStyle == BEFORE) || (containerStyle == AFTER))
                break;
            beforeAfterContainer = beforeAfterContainer->parent();
        }
        makeCounterNode(*beforeAfterContainer, m_counter.identifier(), true)->addRenderer(const_cast<RenderCounter*>(this));
        ASSERT(m_counterNode);
    }
    CounterNode* child = m_counterNode;
    int value = child->actsAsReset() ? child->value() : child->countInParent();

    String text = listMarkerText(m_counter.listStyle(), value);

    if (!m_counter.separator().isNull()) {
        if (!child->actsAsReset())
            child = child->parent();
        while (CounterNode* parent = child->parent()) {
            text = listMarkerText(m_counter.listStyle(), child->countInParent())
                + m_counter.separator() + text;
            child = parent;
        }
    }

    return text.impl();
}
Example #24
0
unsigned CharacterData::parserAppendData(const UChar* data, unsigned dataLength, unsigned lengthLimit)
{
    unsigned oldLength = m_data->length();

    unsigned end = min(dataLength, lengthLimit - oldLength);

    // Check that we are not on an unbreakable boundary.
    // Some text break iterator implementations work best if the passed buffer is as small as possible, 
    // see <https://bugs.webkit.org/show_bug.cgi?id=29092>. 
    // We need at least two characters look-ahead to account for UTF-16 surrogates.
    if (end < dataLength) {
        TextBreakIterator* it = characterBreakIterator(data, (end + 2 > dataLength) ? dataLength : end + 2);
        if (!isTextBreak(it, end))
            end = textBreakPreceding(it, end);
    }
    
    if (!end)
        return 0;

    String newStr = m_data;
    newStr.append(data, end);
    m_data = newStr.impl();

    updateRenderer(oldLength, 0);
    // We don't call dispatchModifiedEvent here because we don't want the
    // parser to dispatch DOM mutation events.
    if (parentNode())
        parentNode()->childrenChanged();
    
    return end;
}
v8::Local<v8::Value> SerializedScriptValueFactory::deserialize(String& data, BlobDataHandleMap& blobDataHandles, ArrayBufferContentsArray* arrayBufferContentsArray, ImageBitmapContentsArray* imageBitmapContentsArray, v8::Isolate* isolate, MessagePortArray* messagePorts, const WebBlobInfoArray* blobInfo)
{
    if (!data.impl())
        return v8::Null(isolate);
    static_assert(sizeof(SerializedScriptValueWriter::BufferValueType) == 2, "BufferValueType should be 2 bytes");
    data.ensure16Bit();
    // FIXME: SerializedScriptValue shouldn't use String for its underlying
    // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The
    // information stored in m_data isn't even encoded in UTF-16. Instead,
    // unicode characters are encoded as UTF-8 with two code units per UChar.
    SerializedScriptValueReader reader(reinterpret_cast<const uint8_t*>(data.impl()->characters16()), 2 * data.length(), blobInfo, blobDataHandles, ScriptState::current(isolate));
    ScriptValueDeserializer deserializer(reader, messagePorts, arrayBufferContentsArray, imageBitmapContentsArray);

    // deserialize() can run arbitrary script (e.g., setters), which could result in |this| being destroyed.
    // Holding a RefPtr ensures we are alive (along with our internal data) throughout the operation.
    return deserializer.deserialize();
}
Example #26
0
bool WebUIClient::showColorPicker(WebPageProxy* page, const String& initialColor, WebColorPickerResultListenerProxy* listener)
{
    if (!m_client.showColorPicker)
        return false;

    m_client.showColorPicker(toAPI(page), toAPI(initialColor.impl()), toAPI(listener), m_client.clientInfo);
    return true;
}
void RenderButton::setText(const String& str)
{
    if (str.isEmpty()) {
        if (m_buttonText) {
            m_buttonText->destroy();
            m_buttonText = 0;
        }
    } else {
        if (m_buttonText)
            m_buttonText->setText(str.impl());
        else {
            m_buttonText = new (renderArena()) RenderTextFragment(document(), str.impl());
            m_buttonText->setStyle(style());
            addChild(m_buttonText);
        }
    }
}
Example #28
0
void OriginUsageRecord::markDatabase(const String& identifier)
{
    ASSERT(m_databaseMap.contains(identifier));
    ASSERT_ARG(identifier, identifier.impl()->hasOneRef() || identifier.isEmpty());

    m_unknownSet.add(identifier);
    m_cachedDiskUsageIsValid = false;
}
Example #29
0
void CharacterData::appendData(const String& data, ExceptionCode&)
{
    String newStr = m_data;
    newStr.append(data);

    setDataAndUpdate(newStr.impl(), m_data->length(), 0, data.length());

    // FIXME: Should we call textInserted here?
}
void WebContextInjectedBundleClient::didReceiveSynchronousMessageFromInjectedBundle(WebContext* context, const String& messageName, APIObject* messageBody, RefPtr<APIObject>& returnData)
{
    if (!m_client.didReceiveSynchronousMessageFromInjectedBundle)
        return;

    WKTypeRef returnDataRef = 0;
    m_client.didReceiveSynchronousMessageFromInjectedBundle(toAPI(context), toAPI(messageName.impl()), toAPI(messageBody), &returnDataRef, m_client.clientInfo);
    returnData = adoptRef(toImpl(returnDataRef));
}