void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (!nearestViewportElement()) {
        // For these events, the outermost <svg> element works like a <body> element does,
        // setting certain event handlers directly on the window object.
        if (name == HTMLNames::onunloadAttr) {
            document().setWindowAttributeEventListener(eventNames().unloadEvent, name, value);
            return;
        }
        if (name == HTMLNames::onresizeAttr) {
            document().setWindowAttributeEventListener(eventNames().resizeEvent, name, value);
            return;
        }
        if (name == HTMLNames::onscrollAttr) {
            document().setWindowAttributeEventListener(eventNames().scrollEvent, name, value);
            return;
        }
        if (name == SVGNames::onzoomAttr) {
            document().setWindowAttributeEventListener(eventNames().zoomEvent, name, value);
            return;
        }
    }

    // For these events, any <svg> element works like a <body> element does,
    // setting certain event handlers directly on the window object.
    // FIXME: Why different from the events above that work only on the outermost <svg> element?
    if (name == HTMLNames::onabortAttr) {
        document().setWindowAttributeEventListener(eventNames().abortEvent, name, value);
        return;
    }
    if (name == HTMLNames::onerrorAttr) {
        document().setWindowAttributeEventListener(eventNames().errorEvent, name, value);
        return;
    }

    SVGParsingError parseError = NoError;

    if (name == SVGNames::xAttr)
        setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
    else if (name == SVGNames::yAttr)
        setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
    else if (name == SVGNames::widthAttr) {
        SVGLength length = SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths);
        if (parseError != NoError || value.isEmpty()) {
            // FIXME: This is definitely the correct behavior for a missing/removed attribute.
            // Not sure it's correct for the empty string or for something that can't be parsed.
            length = SVGLength(LengthModeWidth, ASCIILiteral("100%"));
        }
        setWidthBaseValue(length);
    } else if (name == SVGNames::heightAttr) {
        SVGLength length = SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths);
        if (parseError != NoError || value.isEmpty()) {
            // FIXME: This is definitely the correct behavior for a removed attribute.
            // Not sure it's correct for the empty string or for something that can't be parsed.
            length = SVGLength(LengthModeHeight, ASCIILiteral("100%"));
        }
        setHeightBaseValue(length);
    }

    reportAttributeParsingError(parseError, name, value);

    SVGExternalResourcesRequired::parseAttribute(name, value);
    SVGFitToViewBox::parseAttribute(this, name, value);
    SVGZoomAndPan::parseAttribute(*this, name, value);
    SVGGraphicsElement::parseAttribute(name, value);
}
InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorPageAgent* pageAgent)
    : InspectorBaseAgent<InspectorApplicationCacheAgent>(ASCIILiteral("ApplicationCache"), instrumentingAgents, state)
    , m_pageAgent(pageAgent)
    , m_frontend(0)
{
}
Exemplo n.º 3
0
void WebSocket::send(const String& message, ExceptionCode& ec)
{
    LOG(Network, "WebSocket %p send() Sending String '%s'", this, message.utf8().data());
    if (m_state == CONNECTING) {
        ec = INVALID_STATE_ERR;
        return;
    }
    // No exception is raised if the connection was once established but has subsequently been closed.
    if (m_state == CLOSING || m_state == CLOSED) {
        size_t payloadSize = message.utf8().length();
        m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payloadSize);
        m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize));
        return;
    }
    ASSERT(m_channel);
    ThreadableWebSocketChannel::SendResult result = m_channel->send(message);
    if (result == ThreadableWebSocketChannel::InvalidMessage) {
        scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Websocket message contains invalid character(s)."));
        ec = SYNTAX_ERR;
        return;
    }
}
Exemplo n.º 4
0
RefPtr<IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, InlineKeyCheck inlineKeyCheck, ExceptionCodeWithMessage& ec)
{
    LOG(IndexedDB, "IDBObjectStore::putOrAdd");

    if (!m_transaction->isActive()) {
        ec.code = IDBDatabaseException::TransactionInactiveError;
        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is inactive or finished.");
        return nullptr;
    }

    if (m_transaction->isReadOnly()) {
        ec.code = IDBDatabaseException::ReadOnlyError;
        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is read-only.");
        return nullptr;
    }

    if (m_deleted) {
        ec.code = IDBDatabaseException::InvalidStateError;
        return nullptr;
    }

    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value, nullptr, nullptr);
    if (state.hadException()) {
        ec.code = IDBDatabaseException::DataCloneError;
        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: An object could not be cloned.");
        return nullptr;
    }

    if (serializedValue->hasBlobURLs()) {
        // FIXME: Add Blob/File/FileList support
        ec.code = IDBDatabaseException::DataCloneError;
        ec.message = ASCIILiteral("Failed to store record in an IDBObjectStore: BlobURLs are not yet supported.");
        return nullptr;
    }

    if (key && key->type() == KeyType::Invalid) {
        ec.code = IDBDatabaseException::DataError;
        return nullptr;
    }

    bool usesInlineKeys = !m_info.keyPath().isNull();
    bool usesKeyGenerator = autoIncrement();
    if (usesInlineKeys && inlineKeyCheck == InlineKeyCheck::Perform) {
        if (key) {
            ec.code = IDBDatabaseException::DataError;
            return nullptr;
        }

        RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, m_info.keyPath());
        if (keyPathKey && !keyPathKey->isValid()) {
            ec.code = IDBDatabaseException::DataError;
            return nullptr;
        }

        if (!keyPathKey) {
            if (usesKeyGenerator) {
                if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath())) {
                    ec.code = IDBDatabaseException::DataError;
                    return nullptr;
                }
            } else {
                ec.code = IDBDatabaseException::DataError;
                return nullptr;
            }
        }

        if (keyPathKey) {
            ASSERT(!key);
            key = keyPathKey;
        }
    } else if (!usesKeyGenerator && !key) {
        ec.code = IDBDatabaseException::DataError;
        return nullptr;
    }

    auto context = scriptExecutionContextFromExecState(&state);
    if (!context) {
        ec.code = IDBDatabaseException::UnknownError;
        return nullptr;
    }

    Ref<IDBRequest> request = m_transaction->requestPutOrAdd(*context, *this, key.get(), *serializedValue, overwriteMode);
    return adoptRef(request.leakRef());
}
Exemplo n.º 5
0
// ES5 8.10.5 ToPropertyDescriptor
static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
{
    if (!in.isObject()) {
        exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Property description must be an object.")));
        return false;
    }
    JSObject* description = asObject(in);

    PropertySlot enumerableSlot(description);
    if (description->getPropertySlot(exec, exec->propertyNames().enumerable, enumerableSlot)) {
        desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean(exec));
        if (exec->hadException())
            return false;
    }

    PropertySlot configurableSlot(description);
    if (description->getPropertySlot(exec, exec->propertyNames().configurable, configurableSlot)) {
        desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean(exec));
        if (exec->hadException())
            return false;
    }

    JSValue value;
    PropertySlot valueSlot(description);
    if (description->getPropertySlot(exec, exec->propertyNames().value, valueSlot)) {
        desc.setValue(valueSlot.getValue(exec, exec->propertyNames().value));
        if (exec->hadException())
            return false;
    }

    PropertySlot writableSlot(description);
    if (description->getPropertySlot(exec, exec->propertyNames().writable, writableSlot)) {
        desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean(exec));
        if (exec->hadException())
            return false;
    }

    PropertySlot getSlot(description);
    if (description->getPropertySlot(exec, exec->propertyNames().get, getSlot)) {
        JSValue get = getSlot.getValue(exec, exec->propertyNames().get);
        if (exec->hadException())
            return false;
        if (!get.isUndefined()) {
            CallData callData;
            if (getCallData(get, callData) == CallTypeNone) {
                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Getter must be a function.")));
                return false;
            }
        }
        desc.setGetter(get);
    }

    PropertySlot setSlot(description);
    if (description->getPropertySlot(exec, exec->propertyNames().set, setSlot)) {
        JSValue set = setSlot.getValue(exec, exec->propertyNames().set);
        if (exec->hadException())
            return false;
        if (!set.isUndefined()) {
            CallData callData;
            if (getCallData(set, callData) == CallTypeNone) {
                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Setter must be a function.")));
                return false;
            }
        }
        desc.setSetter(set);
    }

    if (!desc.isAccessorDescriptor())
        return true;

    if (desc.value()) {
        exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Invalid property.  'value' present on property with getter or setter.")));
        return false;
    }

    if (desc.writablePresent()) {
        exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Invalid property.  'writable' present on property with getter or setter.")));
        return false;
    }
    return true;
}
Exemplo n.º 6
0
void WebEditorClient::didEndEditing()
{
    static NeverDestroyed<String> WebViewDidEndEditingNotification(ASCIILiteral("WebViewDidEndEditingNotification"));
    m_page->injectedBundleEditorClient().didEndEditing(m_page, WebViewDidEndEditingNotification.get().impl());
    notImplemented();
}
EncodedJSValue JSC_HOST_CALL constructJSReadableStreamController(ExecState* exec)
{
    return throwVMError(exec, createTypeError(exec, ASCIILiteral("ReadableStreamController constructor should not be called directly")));
}
Exemplo n.º 8
0
void WebInspectorUI::showMainResourceForFrame(const String& frameIdentifier)
{
    m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showMainResourceForFrame"), frameIdentifier);
}
Exemplo n.º 9
0
void WebInspectorUI::stopPageProfiling()
{
    m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setTimelineProfilingEnabled"), false);
}
Exemplo n.º 10
0
void WebInspectorUI::showConsole()
{
    m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showConsole"));
}
Exemplo n.º 11
0
void WebInspectorUI::showResources()
{
    m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showResources"));
}
Exemplo n.º 12
0
void WebInspectorUI::setDockingUnavailable(bool unavailable)
{
    m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setDockingUnavailable"), unavailable);
    m_dockingUnavailable = unavailable;
}
Exemplo n.º 13
0
void IntlCollator::initializeCollator(ExecState& state, JSValue locales, JSValue optionsValue)
{
    // 10.1.1 InitializeCollator (collator, locales, options) (ECMA-402 2.0)
    // 1. If collator has an [[initializedIntlObject]] internal slot with value true, throw a TypeError exception.
    // 2. Set collator.[[initializedIntlObject]] to true.

    // 3. Let requestedLocales be CanonicalizeLocaleList(locales).
    auto requestedLocales = canonicalizeLocaleList(state, locales);
    // 4. ReturnIfAbrupt(requestedLocales).
    if (state.hadException())
        return;

    // 5. If options is undefined, then
    JSObject* options;
    if (optionsValue.isUndefined()) {
        // a. Let options be ObjectCreate(%ObjectPrototype%).
        options = constructEmptyObject(&state);
    } else { // 6. Else
        // a. Let options be ToObject(options).
        options = optionsValue.toObject(&state);
        // b. ReturnIfAbrupt(options).
        if (state.hadException())
            return;
    }

    // 7. Let u be GetOption(options, "usage", "string", «"sort", "search"», "sort").
    String usageString = intlStringOption(state, options, state.vm().propertyNames->usage, { "sort", "search" }, "usage must be either \"sort\" or \"search\"", "sort");
    // 8. ReturnIfAbrupt(u).
    if (state.hadException())
        return;
    // 9. Set collator.[[usage]] to u.
    if (usageString == "sort")
        m_usage = Usage::Sort;
    else if (usageString == "search")
        m_usage = Usage::Search;
    else
        ASSERT_NOT_REACHED();

    // 10. If u is "sort", then
    // a. Let localeData be the value of %Collator%.[[sortLocaleData]];
    // 11. Else
    // a. Let localeData be the value of %Collator%.[[searchLocaleData]].
    Vector<String> (*localeData)(const String&, size_t);
    if (m_usage == Usage::Sort)
        localeData = sortLocaleData;
    else
        localeData = searchLocaleData;

    // 12. Let opt be a new Record.
    HashMap<String, String> opt;

    // 13. Let matcher be GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit").
    String matcher = intlStringOption(state, options, state.vm().propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit");
    // 14. ReturnIfAbrupt(matcher).
    if (state.hadException())
        return;
    // 15. Set opt.[[localeMatcher]] to matcher.
    opt.add(ASCIILiteral("localeMatcher"), matcher);

    // 16. For each row in Table 1, except the header row, do:
    // a. Let key be the name given in the Key column of the row.
    // b. Let prop be the name given in the Property column of the row.
    // c. Let type be the string given in the Type column of the row.
    // d. Let list be a List containing the Strings given in the Values column of the row, or undefined if no strings are given.
    // e. Let value be GetOption(options, prop, type, list, undefined).
    // f. ReturnIfAbrupt(value).
    // g. If the string given in the Type column of the row is "boolean" and value is not undefined, then
    //    i. Let value be ToString(value).
    //    ii. ReturnIfAbrupt(value).
    // h. Set opt.[[<key>]] to value.
    {
        String numericString;
        bool usesFallback;
        bool numeric = intlBooleanOption(state, options, state.vm().propertyNames->numeric, usesFallback);
        if (state.hadException())
            return;
        if (!usesFallback)
            numericString = ASCIILiteral(numeric ? "true" : "false");
        opt.add(ASCIILiteral("kn"), numericString);
    }
    {
        String caseFirst = intlStringOption(state, options, state.vm().propertyNames->caseFirst, { "upper", "lower", "false" }, "caseFirst must be either \"upper\", \"lower\", or \"false\"", nullptr);
        if (state.hadException())
            return;
        opt.add(ASCIILiteral("kf"), caseFirst);
    }

    // 17. Let relevantExtensionKeys be the value of %Collator%.[[relevantExtensionKeys]].
    // 18. Let r be ResolveLocale(%Collator%.[[availableLocales]], requestedLocales, opt, relevantExtensionKeys, localeData).
    auto& availableLocales = state.callee()->globalObject()->intlCollatorAvailableLocales();
    auto result = resolveLocale(state, availableLocales, requestedLocales, opt, relevantExtensionKeys, WTF_ARRAY_LENGTH(relevantExtensionKeys), localeData);

    // 19. Set collator.[[locale]] to the value of r.[[locale]].
    m_locale = result.get(ASCIILiteral("locale"));

    // 20. Let k be 0.
    // 21. Let lenValue be Get(relevantExtensionKeys, "length").
    // 22. Let len be ToLength(lenValue).
    // 23. Repeat while k < len:
    // a. Let Pk be ToString(k).
    // b. Let key be Get(relevantExtensionKeys, Pk).
    // c. ReturnIfAbrupt(key).
    // d. If key is "co", then
    //    i. Let property be "collation".
    //    ii. Let value be the value of r.[[co]].
    //    iii. If value is null, let value be "default".
    // e. Else use the row of Table 1 that contains the value of key in the Key column:
    //    i. Let property be the name given in the Property column of the row.
    //    ii. Let value be the value of r.[[<key>]].
    //    iii. If the name given in the Type column of the row is "boolean", let value be the result of comparing value with "true".
    // f. Set collator.[[<property>]] to value.
    // g. Increase k by 1.
    const String& collation = result.get(ASCIILiteral("co"));
    m_collation = collation.isNull() ? ASCIILiteral("default") : collation;
    m_numeric = (result.get(ASCIILiteral("kn")) == "true");

    // 24. Let s be GetOption(options, "sensitivity", "string", «"base", "accent", "case", "variant"», undefined).
    String sensitivityString = intlStringOption(state, options, state.vm().propertyNames->sensitivity, { "base", "accent", "case", "variant" }, "sensitivity must be either \"base\", \"accent\", \"case\", or \"variant\"", nullptr);
    // 25. ReturnIfAbrupt(s).
    if (state.hadException())
        return;
    // 26. If s is undefined, then
    // a. If u is "sort", then let s be "variant".
    // b. Else
    //    i. Let dataLocale be the value of r.[[dataLocale]].
    //    ii. Let dataLocaleData be Get(localeData, dataLocale).
    //    iii. Let s be Get(dataLocaleData, "sensitivity").
    //    10.2.3 "[[searchLocaleData]][locale] must have a sensitivity property with a String value equal to "base", "accent", "case", or "variant" for all locale values."
    // 27. Set collator.[[sensitivity]] to s.
    if (sensitivityString == "base")
        m_sensitivity = Sensitivity::Base;
    else if (sensitivityString == "accent")
        m_sensitivity = Sensitivity::Accent;
    else if (sensitivityString == "case")
        m_sensitivity = Sensitivity::Case;
    else
        m_sensitivity = Sensitivity::Variant;

    // 28. Let ip be GetOption(options, "ignorePunctuation", "boolean", undefined, false).
    bool usesFallback;
    bool ignorePunctuation = intlBooleanOption(state, options, state.vm().propertyNames->ignorePunctuation, usesFallback);
    if (usesFallback)
        ignorePunctuation = false;
    // 29. ReturnIfAbrupt(ip).
    if (state.hadException())
        return;
    // 30. Set collator.[[ignorePunctuation]] to ip.
    m_ignorePunctuation = ignorePunctuation;

    // 31. Set collator.[[boundCompare]] to undefined.
    // 32. Set collator.[[initializedCollator]] to true.
    m_initializedCollator = true;

    // 33. Return collator.
}
void InspectorTimelineAgent::didCompleteRecordEntry(const TimelineRecordEntry& entry) {
    entry.record->setObject(ASCIILiteral("data"), entry.data);
    entry.record->setArray(ASCIILiteral("children"), entry.children);
    entry.record->setDouble(ASCIILiteral("endTime"), timestamp());
    addRecordToTimeline(entry.record.copyRef(), entry.type);
}
Exemplo n.º 15
0
void WebEditorClient::didEndEditing()
{
    DEFINE_STATIC_LOCAL(String, WebViewDidEndEditingNotification, (ASCIILiteral("WebViewDidEndEditingNotification")));
    m_page->injectedBundleEditorClient().didEndEditing(m_page, WebViewDidEndEditingNotification.impl());
    notImplemented();
}
Exemplo n.º 16
0
void WebInspectorUI::stopElementSelection()
{
    m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setElementSelectionEnabled"), false);
}
Exemplo n.º 17
0
void WebEditorClient::respondToChangedContents()
{
    static NeverDestroyed<String> WebViewDidChangeNotification(ASCIILiteral("WebViewDidChangeNotification"));
    m_page->injectedBundleEditorClient().didChange(m_page, WebViewDidChangeNotification.get().impl());
    notImplemented();
}
Exemplo n.º 18
0
void WebInspectorUI::didSave(const String& url)
{
    m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("savedURL"), url);
}
const String& ContentExtensionsBackend::displayNoneCSSRule()
{
    static NeverDestroyed<const String> rule(ASCIILiteral("display:none !important;"));
    return rule;
}
Exemplo n.º 20
0
void WebInspectorUI::didAppend(const String& url)
{
    m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("appendedToURL"), url);
}
Exemplo n.º 21
0
EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue();
    if (thisValue.isUndefinedOrNull())
        return JSValue::encode(jsNontrivialString(exec, String(thisValue.isUndefined() ? ASCIILiteral("[object Undefined]") : ASCIILiteral("[object Null]"))));
    JSObject* thisObject = thisValue.toObject(exec);

    JSString* result = thisObject->structure()->objectToStringValue();
    if (!result) {
        RefPtr<StringImpl> newString = WTF::tryMakeString("[object ", thisObject->methodTable()->className(thisObject), "]");
        if (!newString)
            return JSValue::encode(throwOutOfMemoryError(exec));

        result = jsNontrivialString(exec, newString.release());
        thisObject->structure()->setObjectToStringValue(exec->vm(), thisObject, result);
    }
    return JSValue::encode(result);
}
Exemplo n.º 22
0
void WebInspectorUI::windowObjectCleared()
{
    if (m_frontendHost)
        m_frontendHost->disconnectClient();

    m_frontendHost = InspectorFrontendHost::create(this, m_page.corePage());
    ScriptGlobalObject::set(*execStateFromPage(mainThreadNormalWorld(), m_page.corePage()), ASCIILiteral("InspectorFrontendHost"), *m_frontendHost);
}
const String& InputTraits<Test::FormCombo>::type()
{
    static NeverDestroyed<const String> type(ASCIILiteral("FormCombo"));
    return type;
}
Exemplo n.º 24
0
void WebAssemblyTableConstructor::finishCreation(VM& vm, WebAssemblyTablePrototype* prototype)
{
    Base::finishCreation(vm, ASCIILiteral("Table"));
    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
Exemplo n.º 25
0
EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState* exec)
{
    if (!exec->argument(0).isObject())
        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
    return JSValue::encode(defineProperties(exec, asObject(exec->argument(0)), exec->argument(1).toObject(exec)));
}
Exemplo n.º 26
0
static IntlCollator* initializeCollator(ExecState& state, IntlCollator& collator, JSValue locales, JSValue optionsValue)
{
    // 10.1.1 InitializeCollator (collator, locales, options) (ECMA-402 2.0)

    // 1. If collator has an [[initializedIntlObject]] internal slot with value true, throw a TypeError exception.
    // 2. Set collator.[[initializedIntlObject]] to true.

    // 3. Let requestedLocales be CanonicalizeLocaleList(locales).
    Vector<String> requestedLocales = canonicalizeLocaleList(state, locales);
    // 4. ReturnIfAbrupt(requestedLocales).
    if (state.hadException())
        return nullptr;

    // 5. If options is undefined, then
    JSObject* options;
    if (optionsValue.isUndefined()) {
        // a. Let options be ObjectCreate(%ObjectPrototype%).
        options = constructEmptyObject(&state);
    } else { // 6. Else
        // a. Let options be ToObject(options).
        options = optionsValue.toObject(&state);
        // b. ReturnIfAbrupt(options).
        if (state.hadException())
            return nullptr;
    }

    // 7. Let u be GetOption(options, "usage", "string", «"sort", "search"», "sort").
    const HashSet<String> usages({ ASCIILiteral("sort"), ASCIILiteral("search") });
    String usage = intlStringOption(state, options, state.vm().propertyNames->usage, usages, "usage must be either \"sort\" or \"search\"", ASCIILiteral("sort"));
    // 8. ReturnIfAbrupt(u).
    if (state.hadException())
        return nullptr;
    // 9. Set collator.[[usage]] to u.
    collator.setUsage(usage);

    // 10. If u is "sort", then
    // a. Let localeData be the value of %Collator%.[[sortLocaleData]];
    // 11. Else
    // a. Let localeData be the value of %Collator%.[[searchLocaleData]].
    Vector<String> (*localeData)(const String&, const String&);
    if (usage == "sort")
        localeData = sortLocaleData;
    else
        localeData = searchLocaleData;

    // 12. Let opt be a new Record.
    HashMap<String, String> opt;

    // 13. Let matcher be GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit").
    const HashSet<String> matchers({ ASCIILiteral("lookup"), ASCIILiteral("best fit") });
    String matcher = intlStringOption(state, options, state.vm().propertyNames->localeMatcher, matchers, "localeMatcher must be either \"lookup\" or \"best fit\"", ASCIILiteral("best fit"));
    // 14. ReturnIfAbrupt(matcher).
    if (state.hadException())
        return nullptr;
    // 15. Set opt.[[localeMatcher]] to matcher.
    opt.set(ASCIILiteral("localeMatcher"), matcher);

    // 16. For each row in Table 1, except the header row, do:
    // a. Let key be the name given in the Key column of the row.
    // b. Let prop be the name given in the Property column of the row.
    // c. Let type be the string given in the Type column of the row.
    // d. Let list be a List containing the Strings given in the Values column of the row, or undefined if no strings are given.
    // e. Let value be GetOption(options, prop, type, list, undefined).
    // f. ReturnIfAbrupt(value).
    // g. If the string given in the Type column of the row is "boolean" and value is not undefined, then
    //    i. Let value be ToString(value).
    //    ii. ReturnIfAbrupt(value).
    // h. Set opt.[[<key>]] to value.
    {
        String numericString;
        bool usesFallback;
        bool numeric = intlBooleanOption(state, options, state.vm().propertyNames->numeric, usesFallback);
        if (state.hadException())
            return nullptr;
        if (!usesFallback)
            numericString = ASCIILiteral(numeric ? "true" : "false");
        opt.set(ASCIILiteral("kn"), numericString);
    }
    {
        const HashSet<String> caseFirsts({ ASCIILiteral("upper"), ASCIILiteral("lower"), ASCIILiteral("false") });
        String caseFirst = intlStringOption(state, options, state.vm().propertyNames->caseFirst, caseFirsts, "caseFirst must be either \"upper\", \"lower\", or \"false\"", String());
        if (state.hadException())
            return nullptr;
        opt.set(ASCIILiteral("kf"), caseFirst);
    }

    // 17. Let relevantExtensionKeys be the value of %Collator%.[[relevantExtensionKeys]].
    // FIXME: Implement kf (caseFirst).
    const Vector<String> relevantExtensionKeys { ASCIILiteral("co"), ASCIILiteral("kn") };

    // 18. Let r be ResolveLocale(%Collator%.[[availableLocales]], requestedLocales, opt, relevantExtensionKeys, localeData).
    const HashSet<String>& availableLocales = state.callee()->globalObject()->intlCollatorAvailableLocales();
    HashMap<String, String> result = resolveLocale(availableLocales, requestedLocales, opt, relevantExtensionKeys, localeData);

    // 19. Set collator.[[locale]] to the value of r.[[locale]].
    collator.setLocale(result.get(ASCIILiteral("locale")));

    // 20. Let k be 0.
    // 21. Let lenValue be Get(relevantExtensionKeys, "length").
    // 22. Let len be ToLength(lenValue).
    // 23. Repeat while k < len:
    // a. Let Pk be ToString(k).
    // b. Let key be Get(relevantExtensionKeys, Pk).
    // c. ReturnIfAbrupt(key).
    // d. If key is "co", then
    //    i. Let property be "collation".
    //    ii. Let value be the value of r.[[co]].
    //    iii. If value is null, let value be "default".
    // e. Else use the row of Table 1 that contains the value of key in the Key column:
    //    i. Let property be the name given in the Property column of the row.
    //    ii. Let value be the value of r.[[<key>]].
    //    iii. If the name given in the Type column of the row is "boolean", let value be the result of comparing value with "true".
    // f. Set collator.[[<property>]] to value.
    // g. Increase k by 1.
    ASSERT(relevantExtensionKeys.size() == 2);
    {
        ASSERT(relevantExtensionKeys[0] == "co");
        const String& value = result.get(ASCIILiteral("co"));
        collator.setCollation(value.isNull() ? ASCIILiteral("default") : value);
    }
    {
        ASSERT(relevantExtensionKeys[1] == "kn");
        const String& value = result.get(ASCIILiteral("kn"));
        collator.setNumeric(value == "true");
    }

    // 24. Let s be GetOption(options, "sensitivity", "string", «"base", "accent", "case", "variant"», undefined).
    const HashSet<String> sensitivities({ ASCIILiteral("base"), ASCIILiteral("accent"), ASCIILiteral("case"), ASCIILiteral("variant") });
    String sensitivity = intlStringOption(state, options, state.vm().propertyNames->sensitivity, sensitivities, "sensitivity must be either \"base\", \"accent\", \"case\", or \"variant\"", String());
    // 25. ReturnIfAbrupt(s).
    if (state.hadException())
        return nullptr;
    // 26. If s is undefined, then
    if (sensitivity.isNull()) {
        // a. If u is "sort", then let s be "variant".
        if (usage == "sort")
            sensitivity = ASCIILiteral("variant");
        else {
            // b. Else
            //    i. Let dataLocale be the value of r.[[dataLocale]].
            //    ii. Let dataLocaleData be Get(localeData, dataLocale).
            //    iii. Let s be Get(dataLocaleData, "sensitivity").
            const String& dataLocale = result.get(ASCIILiteral("dataLocale"));
            sensitivity = localeData(dataLocale, ASCIILiteral("sensitivity"))[0];
        }
    }
    // 27. Set collator.[[sensitivity]] to s.
    collator.setSensitivity(sensitivity);

    // 28. Let ip be GetOption(options, "ignorePunctuation", "boolean", undefined, false).
    bool usesFallback;
    bool ignorePunctuation = intlBooleanOption(state, options, state.vm().propertyNames->ignorePunctuation, usesFallback);
    if (usesFallback)
        ignorePunctuation = false;
    // 29. ReturnIfAbrupt(ip).
    if (state.hadException())
        return nullptr;
    // 30. Set collator.[[ignorePunctuation]] to ip.
    collator.setIgnorePunctuation(ignorePunctuation);

    // 31. Set collator.[[boundCompare]] to undefined.
    // 32. Set collator.[[initializedCollator]] to true.
    // 33. Return collator.
    return &collator;
}
Exemplo n.º 27
0
JSC::JSInternalPromise* ScriptModuleLoader::resolve(JSC::JSGlobalObject* jsGlobalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleNameValue, JSC::JSValue importerModuleKey, JSC::JSValue)
{
    auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(jsGlobalObject);
    auto& jsPromise = *JSC::JSInternalPromiseDeferred::create(exec, &globalObject);
    auto promise = DeferredPromise::create(globalObject, jsPromise);

    // We use a Symbol as a special purpose; It means this module is an inline module.
    // So there is no correct URL to retrieve the module source code. If the module name
    // value is a Symbol, it is used directly as a module key.
    if (moduleNameValue.isSymbol()) {
        promise->resolve<IDLAny>(toJS(exec, &globalObject, asSymbol(moduleNameValue)->privateName()));
        return jsPromise.promise();
    }

    // https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier

    if (!moduleNameValue.isString()) {
        promise->reject(TypeError, ASCIILiteral("Module specifier is not Symbol or String."));
        return jsPromise.promise();
    }

    String specifier = asString(moduleNameValue)->value(exec);

    // 1. Apply the URL parser to specifier. If the result is not failure, return the result.
    URL absoluteURL(URL(), specifier);
    if (absoluteURL.isValid()) {
        promise->resolve<IDLDOMString>(absoluteURL.string());
        return jsPromise.promise();
    }

    // 2. If specifier does not start with the character U+002F SOLIDUS (/), the two-character sequence U+002E FULL STOP, U+002F SOLIDUS (./),
    //    or the three-character sequence U+002E FULL STOP, U+002E FULL STOP, U+002F SOLIDUS (../), return failure and abort these steps.
    if (!specifier.startsWith('/') && !specifier.startsWith("./") && !specifier.startsWith("../")) {
        promise->reject(TypeError, ASCIILiteral("Module specifier does not start with \"/\", \"./\", or \"../\"."));
        return jsPromise.promise();
    }

    // 3. Return the result of applying the URL parser to specifier with script's base URL as the base URL.

    URL completedURL;

    if (isRootModule(importerModuleKey))
        completedURL = m_document.completeURL(specifier);
    else if (importerModuleKey.isString()) {
        URL importerModuleRequestURL(URL(), asString(importerModuleKey)->value(exec));
        if (!importerModuleRequestURL.isValid()) {
            promise->reject(TypeError, ASCIILiteral("Importer module key is an invalid URL."));
            return jsPromise.promise();
        }

        URL importerModuleResponseURL = m_requestURLToResponseURLMap.get(importerModuleRequestURL);
        if (!importerModuleResponseURL.isValid()) {
            promise->reject(TypeError, ASCIILiteral("Importer module has an invalid response URL."));
            return jsPromise.promise();
        }

        completedURL = m_document.completeURL(specifier, importerModuleResponseURL);
    } else {
        promise->reject(TypeError, ASCIILiteral("Importer module key is not Symbol or String."));
        return jsPromise.promise();
    }

    if (!completedURL.isValid()) {
        promise->reject(TypeError, ASCIILiteral("Module name constructs an invalid URL."));
        return jsPromise.promise();
    }

    promise->resolve<IDLDOMString>(completedURL.string());
    return jsPromise.promise();
}
Exemplo n.º 28
0
void WebEditorClient::respondToChangedContents()
{
    DEFINE_STATIC_LOCAL(String, WebViewDidChangeNotification, (ASCIILiteral("WebViewDidChangeNotification")));
    m_page->injectedBundleEditorClient().didChange(m_page, WebViewDidChangeNotification.impl());
    notImplemented();
}
Exemplo n.º 29
0
void WebSocket::close(int code, const String& reason, ExceptionCode& ec)
{
    if (code == WebSocketChannel::CloseEventCodeNotSpecified)
        LOG(Network, "WebSocket %p close() without code and reason", this);
    else {
        LOG(Network, "WebSocket %p close() code=%d reason='%s'", this, code, reason.utf8().data());
        if (!(code == WebSocketChannel::CloseEventCodeNormalClosure || (WebSocketChannel::CloseEventCodeMinimumUserDefined <= code && code <= WebSocketChannel::CloseEventCodeMaximumUserDefined))) {
            ec = INVALID_ACCESS_ERR;
            return;
        }
        CString utf8 = reason.utf8(StrictConversionReplacingUnpairedSurrogatesWithFFFD);
        if (utf8.length() > maxReasonSizeInBytes) {
            scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("WebSocket close message is too long."));
            ec = SYNTAX_ERR;
            return;
        }
    }

    if (m_state == CLOSING || m_state == CLOSED)
        return;
    if (m_state == CONNECTING) {
        m_state = CLOSING;
        m_channel->fail("WebSocket is closed before the connection is established.");
        return;
    }
    m_state = CLOSING;
    if (m_channel)
        m_channel->close(code, reason);
}
Exemplo n.º 30
0
bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool throwException)
{
    JSFunction* thisObject = jsCast<JSFunction*>(object);
    if (thisObject->isHostFunction())
        return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);

    if (propertyName == exec->propertyNames().prototype) {
        // Make sure prototype has been reified, such that it can only be overwritten
        // following the rules set out in ECMA-262 8.12.9.
        PropertySlot slot;
        thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
        thisObject->m_allocationProfile.clear();
        thisObject->m_allocationProfileWatchpoint.notifyWrite();
        return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
    }

    bool valueCheck;
    if (propertyName == exec->propertyNames().arguments) {
        if (thisObject->jsExecutable()->isStrictMode()) {
            if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor))
                thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
            return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
        }
        valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject));
    } else if (propertyName == exec->propertyNames().caller) {
        if (thisObject->jsExecutable()->isStrictMode()) {
            if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor))
                thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
            return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
        }
        valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject));
    } else if (propertyName == exec->propertyNames().length)
        valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount()));
    else if (propertyName == exec->propertyNames().name)
        valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), thisObject->jsExecutable()->nameValue());
    else
        return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
     
    if (descriptor.configurablePresent() && descriptor.configurable()) {
        if (throwException)
            throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
        return false;
    }
    if (descriptor.enumerablePresent() && descriptor.enumerable()) {
        if (throwException)
            throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
        return false;
    }
    if (descriptor.isAccessorDescriptor()) {
        if (throwException)
            throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
        return false;
    }
    if (descriptor.writablePresent() && descriptor.writable()) {
        if (throwException)
            throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
        return false;
    }
    if (!valueCheck) {
        if (throwException)
            throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
        return false;
    }
    return true;
}