Serenity Operating System
at master 125 lines 3.9 kB view raw
1/* 2 * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> 3 * Copyright (c) 2022-2023, Andreas Kling <kling@serenityos.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <LibWeb/Bindings/Intrinsics.h> 9#include <LibWeb/Bindings/MediaListPrototype.h> 10#include <LibWeb/CSS/MediaList.h> 11#include <LibWeb/CSS/Parser/Parser.h> 12#include <LibWeb/WebIDL/ExceptionOr.h> 13 14namespace Web::CSS { 15 16WebIDL::ExceptionOr<JS::NonnullGCPtr<MediaList>> MediaList::create(JS::Realm& realm, Vector<NonnullRefPtr<MediaQuery>>&& media) 17{ 18 return MUST_OR_THROW_OOM(realm.heap().allocate<MediaList>(realm, realm, move(media))); 19} 20 21MediaList::MediaList(JS::Realm& realm, Vector<NonnullRefPtr<MediaQuery>>&& media) 22 : Bindings::LegacyPlatformObject(realm) 23 , m_media(move(media)) 24{ 25} 26 27JS::ThrowCompletionOr<void> MediaList::initialize(JS::Realm& realm) 28{ 29 MUST_OR_THROW_OOM(Base::initialize(realm)); 30 set_prototype(&Bindings::ensure_web_prototype<Bindings::MediaListPrototype>(realm, "MediaList")); 31 32 return {}; 33} 34 35// https://www.w3.org/TR/cssom-1/#dom-medialist-mediatext 36DeprecatedString MediaList::media_text() const 37{ 38 return serialize_a_media_query_list(m_media).release_value_but_fixme_should_propagate_errors().to_deprecated_string(); 39} 40 41// https://www.w3.org/TR/cssom-1/#dom-medialist-mediatext 42void MediaList::set_media_text(DeprecatedString const& text) 43{ 44 m_media.clear(); 45 if (text.is_empty()) 46 return; 47 m_media = parse_media_query_list(Parser::ParsingContext { realm() }, text); 48} 49 50bool MediaList::is_supported_property_index(u32 index) const 51{ 52 return index < length(); 53} 54 55// https://www.w3.org/TR/cssom-1/#dom-medialist-item 56DeprecatedString MediaList::item(u32 index) const 57{ 58 if (!is_supported_property_index(index)) 59 return {}; 60 61 return m_media[index]->to_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string(); 62} 63 64// https://www.w3.org/TR/cssom-1/#dom-medialist-appendmedium 65void MediaList::append_medium(DeprecatedString medium) 66{ 67 // 1. Let m be the result of parsing the given value. 68 auto m = parse_media_query(Parser::ParsingContext { realm() }, medium); 69 70 // 2. If m is null, then return. 71 if (!m) 72 return; 73 74 // 3. If comparing m with any of the media queries in the collection of media queries returns true, then return. 75 auto serialized = m->to_string().release_value_but_fixme_should_propagate_errors(); 76 for (auto& existing_medium : m_media) { 77 if (existing_medium->to_string().release_value_but_fixme_should_propagate_errors() == serialized) 78 return; 79 } 80 81 // 4. Append m to the collection of media queries. 82 m_media.append(m.release_nonnull()); 83} 84 85// https://www.w3.org/TR/cssom-1/#dom-medialist-deletemedium 86void MediaList::delete_medium(DeprecatedString medium) 87{ 88 auto m = parse_media_query(Parser::ParsingContext { realm() }, medium); 89 if (!m) 90 return; 91 m_media.remove_all_matching([&](auto& existing) -> bool { 92 return m->to_string().release_value_but_fixme_should_propagate_errors() == existing->to_string().release_value_but_fixme_should_propagate_errors(); 93 }); 94 // FIXME: If nothing was removed, then throw a NotFoundError exception. 95} 96 97bool MediaList::evaluate(HTML::Window const& window) 98{ 99 for (auto& media : m_media) 100 media->evaluate(window); 101 102 return matches(); 103} 104 105bool MediaList::matches() const 106{ 107 if (m_media.is_empty()) { 108 return true; 109 } 110 111 for (auto& media : m_media) { 112 if (media->matches()) 113 return true; 114 } 115 return false; 116} 117 118WebIDL::ExceptionOr<JS::Value> MediaList::item_value(size_t index) const 119{ 120 if (index >= m_media.size()) 121 return JS::js_undefined(); 122 return JS::PrimitiveString::create(vm(), m_media[index]->to_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string()); 123} 124 125}