/* * Copyright (c) 2021, Sam Atkins * Copyright (c) 2022-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include namespace Web::CSS { WebIDL::ExceptionOr> MediaList::create(JS::Realm& realm, Vector>&& media) { return MUST_OR_THROW_OOM(realm.heap().allocate(realm, realm, move(media))); } MediaList::MediaList(JS::Realm& realm, Vector>&& media) : Bindings::LegacyPlatformObject(realm) , m_media(move(media)) { } JS::ThrowCompletionOr MediaList::initialize(JS::Realm& realm) { MUST_OR_THROW_OOM(Base::initialize(realm)); set_prototype(&Bindings::ensure_web_prototype(realm, "MediaList")); return {}; } // https://www.w3.org/TR/cssom-1/#dom-medialist-mediatext DeprecatedString MediaList::media_text() const { return serialize_a_media_query_list(m_media).release_value_but_fixme_should_propagate_errors().to_deprecated_string(); } // https://www.w3.org/TR/cssom-1/#dom-medialist-mediatext void MediaList::set_media_text(DeprecatedString const& text) { m_media.clear(); if (text.is_empty()) return; m_media = parse_media_query_list(Parser::ParsingContext { realm() }, text); } bool MediaList::is_supported_property_index(u32 index) const { return index < length(); } // https://www.w3.org/TR/cssom-1/#dom-medialist-item DeprecatedString MediaList::item(u32 index) const { if (!is_supported_property_index(index)) return {}; return m_media[index]->to_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string(); } // https://www.w3.org/TR/cssom-1/#dom-medialist-appendmedium void MediaList::append_medium(DeprecatedString medium) { // 1. Let m be the result of parsing the given value. auto m = parse_media_query(Parser::ParsingContext { realm() }, medium); // 2. If m is null, then return. if (!m) return; // 3. If comparing m with any of the media queries in the collection of media queries returns true, then return. auto serialized = m->to_string().release_value_but_fixme_should_propagate_errors(); for (auto& existing_medium : m_media) { if (existing_medium->to_string().release_value_but_fixme_should_propagate_errors() == serialized) return; } // 4. Append m to the collection of media queries. m_media.append(m.release_nonnull()); } // https://www.w3.org/TR/cssom-1/#dom-medialist-deletemedium void MediaList::delete_medium(DeprecatedString medium) { auto m = parse_media_query(Parser::ParsingContext { realm() }, medium); if (!m) return; m_media.remove_all_matching([&](auto& existing) -> bool { return m->to_string().release_value_but_fixme_should_propagate_errors() == existing->to_string().release_value_but_fixme_should_propagate_errors(); }); // FIXME: If nothing was removed, then throw a NotFoundError exception. } bool MediaList::evaluate(HTML::Window const& window) { for (auto& media : m_media) media->evaluate(window); return matches(); } bool MediaList::matches() const { if (m_media.is_empty()) { return true; } for (auto& media : m_media) { if (media->matches()) return true; } return false; } WebIDL::ExceptionOr MediaList::item_value(size_t index) const { if (index >= m_media.size()) return JS::js_undefined(); return JS::PrimitiveString::create(vm(), m_media[index]->to_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string()); } }