|
| 1 | +/* |
| 2 | + * Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org> |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: BSD-2-Clause |
| 5 | + */ |
| 6 | + |
| 7 | +#include <LibWeb/SVG/SVGList.h> |
| 8 | +#include <LibWeb/SVG/SVGTransform.h> |
| 9 | + |
| 10 | +namespace Web::SVG { |
| 11 | + |
| 12 | +template<typename T> |
| 13 | +SVGList<T>::SVGList(JS::Realm& realm, Vector<T> items, ReadOnlyList read_only) |
| 14 | + : m_realm(realm) |
| 15 | + , m_items(move(items)) |
| 16 | + , m_read_only(read_only) |
| 17 | +{ |
| 18 | +} |
| 19 | + |
| 20 | +template<typename T> |
| 21 | +SVGList<T>::SVGList(JS::Realm& realm, ReadOnlyList read_only) |
| 22 | + : m_realm(realm) |
| 23 | + , m_read_only(read_only) |
| 24 | +{ |
| 25 | +} |
| 26 | + |
| 27 | +template<typename T> |
| 28 | +void SVGList<T>::visit_edges(GC::Cell::Visitor& visitor) |
| 29 | +{ |
| 30 | + visitor.visit(m_realm); |
| 31 | + visitor.visit(m_items); |
| 32 | +} |
| 33 | + |
| 34 | +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNameList__length |
| 35 | +template<typename T> |
| 36 | +WebIDL::UnsignedLong SVGList<T>::length() const |
| 37 | +{ |
| 38 | + // The length and numberOfItems IDL attributes represents the length of the list, and on getting simply return the |
| 39 | + // length of the list. |
| 40 | + return m_items.size(); |
| 41 | +} |
| 42 | + |
| 43 | +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNameList__clear |
| 44 | +template<typename T> |
| 45 | +WebIDL::ExceptionOr<void> SVGList<T>::clear() |
| 46 | +{ |
| 47 | + // 1. If the list is read only, then throw a NoModificationAllowedError. |
| 48 | + if (m_read_only == ReadOnlyList::Yes) |
| 49 | + return WebIDL::NoModificationAllowedError::create(m_realm, "Cannot modify a read-only list"_utf16); |
| 50 | + |
| 51 | + // 2. Detach and then remove all elements in the list. |
| 52 | + // FIXME: Detach items. |
| 53 | + m_items.clear(); |
| 54 | + |
| 55 | + // FIXME: 3. If the list reflects an attribute, or represents the base value of an object that reflects an attribute, then |
| 56 | + // reserialize the reflected attribute. |
| 57 | + |
| 58 | + return {}; |
| 59 | +} |
| 60 | + |
| 61 | +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNameList__initialize |
| 62 | +template<typename T> |
| 63 | +WebIDL::ExceptionOr<T> SVGList<T>::initialize_(T new_item) |
| 64 | +{ |
| 65 | + // 1. If the list is read only, then throw a NoModificationAllowedError. |
| 66 | + if (m_read_only == ReadOnlyList::Yes) |
| 67 | + return WebIDL::NoModificationAllowedError::create(m_realm, "Cannot modify a read-only list"_utf16); |
| 68 | + |
| 69 | + // 2. Detach and then remove all elements in the list. |
| 70 | + // FIXME: Detach items. |
| 71 | + m_items.clear(); |
| 72 | + |
| 73 | + // FIXME: 3. If newItem is an object type, and newItem is not a detached object, then set newItem to be a newly created |
| 74 | + // object of the same type as newItem and which has the same (number or length) value. |
| 75 | + |
| 76 | + // FIXME: 4. Attach newItem to the list interface object. |
| 77 | + |
| 78 | + // 5. Append newItem to this list. |
| 79 | + m_items.append(new_item); |
| 80 | + |
| 81 | + // FIXME: 6. If the list reflects an attribute, or represents the base value of an object that reflects an attribute, then |
| 82 | + // reserialize the reflected attribute. |
| 83 | + |
| 84 | + // 7. Return newItem. |
| 85 | + return new_item; |
| 86 | +} |
| 87 | + |
| 88 | +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNameList__getItem |
| 89 | +template<typename T> |
| 90 | +WebIDL::ExceptionOr<T> SVGList<T>::get_item(WebIDL::UnsignedLong index) |
| 91 | +{ |
| 92 | + // 1. If index is greater than or equal to the length of the list, then throw an IndexSizeError. |
| 93 | + if (index >= m_items.size()) |
| 94 | + return WebIDL::IndexSizeError::create(m_realm, "List index out of bounds"_utf16); |
| 95 | + |
| 96 | + // 2. Return the element in the list at position index. |
| 97 | + return m_items[index]; |
| 98 | +} |
| 99 | + |
| 100 | +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNameList__insertItemBefore |
| 101 | +template<typename T> |
| 102 | +WebIDL::ExceptionOr<T> SVGList<T>::insert_item_before(T new_item, WebIDL::UnsignedLong index) |
| 103 | +{ |
| 104 | + // 1. If the list is read only, then throw a NoModificationAllowedError. |
| 105 | + if (m_read_only == ReadOnlyList::Yes) |
| 106 | + return WebIDL::NoModificationAllowedError::create(m_realm, "Cannot modify a read-only list"_utf16); |
| 107 | + |
| 108 | + // FIXME: 2. If newItem is an object type, and newItem is not a detached object, then set newItem to be a newly created |
| 109 | + // object of the same type as newItem and which has the same (number or length) value. |
| 110 | + |
| 111 | + // 3. If index is greater than the length of the list, then set index to be the list length. |
| 112 | + if (index > m_items.size()) |
| 113 | + index = m_items.size(); |
| 114 | + |
| 115 | + // 4. Insert newItem into the list at index index. |
| 116 | + m_items.insert(index, new_item); |
| 117 | + |
| 118 | + // FIXME: 5. Attach newItem to the list interface object. |
| 119 | + |
| 120 | + // FIXME: 6. If the list reflects an attribute, or represents the base value of an object that reflects an attribute, then |
| 121 | + // reserialize the reflected attribute. |
| 122 | + |
| 123 | + // 7. Return newItem. |
| 124 | + return new_item; |
| 125 | +} |
| 126 | + |
| 127 | +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNameList__replaceItem |
| 128 | +template<typename T> |
| 129 | +WebIDL::ExceptionOr<T> SVGList<T>::replace_item(T new_item, WebIDL::UnsignedLong index) |
| 130 | +{ |
| 131 | + // 1. If the list is read only, then throw a NoModificationAllowedError. |
| 132 | + if (m_read_only == ReadOnlyList::Yes) |
| 133 | + return WebIDL::NoModificationAllowedError::create(m_realm, "Cannot modify a read-only list"_utf16); |
| 134 | + |
| 135 | + // 2. If index is greater than or equal to the length of the list, then throw an IndexSizeError. |
| 136 | + if (index >= m_items.size()) |
| 137 | + return WebIDL::IndexSizeError::create(m_realm, "List index out of bounds"_utf16); |
| 138 | + |
| 139 | + // FIXME: 3. If newItem is an object type, and newItem is not a detached object, then set newItem to be a newly created |
| 140 | + // object of the same type as newItem and which has the same (number or length) value. |
| 141 | + |
| 142 | + // FIXME: 4. Detach the element in the list at index index. |
| 143 | + |
| 144 | + // 5. Replace the element in the list at index index with newItem. |
| 145 | + m_items[index] = new_item; |
| 146 | + |
| 147 | + // FIXME: 6. Attach newItem to the list interface object. |
| 148 | + |
| 149 | + // FIXNE: 7. If the list reflects an attribute, or represents the base value of an object that reflects an attribute, then |
| 150 | + // reserialize the reflected attribute. |
| 151 | + |
| 152 | + // 8. Return newItem. |
| 153 | + return new_item; |
| 154 | +} |
| 155 | + |
| 156 | +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNameList__removeItem |
| 157 | +template<typename T> |
| 158 | +WebIDL::ExceptionOr<T> SVGList<T>::remove_item(WebIDL::UnsignedLong index) |
| 159 | +{ |
| 160 | + // 1. If the list is read only, then throw a NoModificationAllowedError. |
| 161 | + if (m_read_only == ReadOnlyList::Yes) |
| 162 | + return WebIDL::NoModificationAllowedError::create(m_realm, "Cannot modify a read-only list"_utf16); |
| 163 | + |
| 164 | + // 2. If index is greater than or equal to the length of the list, then throw an IndexSizeError with code. |
| 165 | + if (index >= m_items.size()) |
| 166 | + return WebIDL::IndexSizeError::create(m_realm, "List index out of bounds"_utf16); |
| 167 | + |
| 168 | + // 3. Let item be the list element at index index. |
| 169 | + auto item = m_items[index]; |
| 170 | + |
| 171 | + // FIXME: 4. Detach item. |
| 172 | + |
| 173 | + // 5. Remove the list element at index index. |
| 174 | + m_items.remove(index); |
| 175 | + |
| 176 | + // 6. Return item. |
| 177 | + return item; |
| 178 | +} |
| 179 | + |
| 180 | +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNameList__appendItem |
| 181 | +template<typename T> |
| 182 | +WebIDL::ExceptionOr<T> SVGList<T>::append_item(T new_item) |
| 183 | +{ |
| 184 | + // 1. If the list is read only, then throw a NoModificationAllowedError. |
| 185 | + if (m_read_only == ReadOnlyList::Yes) |
| 186 | + return WebIDL::NoModificationAllowedError::create(m_realm, "Cannot modify a read-only list"_utf16); |
| 187 | + |
| 188 | + // FIXME: 2. If newItem is an object type, and newItem is not a detached object, then set newItem to be a newly created |
| 189 | + // object of the same type as newItem and which has the same (number or length) value. |
| 190 | + |
| 191 | + // 3. Let index be the length of the list. |
| 192 | + // AD-HOC: No, this is unused. |
| 193 | + |
| 194 | + // 4. Append newItem to the end of the list. |
| 195 | + m_items.append(new_item); |
| 196 | + |
| 197 | + // FIXME: 5. Attach newItem to the list interface object. |
| 198 | + |
| 199 | + // FIXME: 6. If the list reflects an attribute, or represents the base value of an object that reflects an attribute, then |
| 200 | + // reserialize the reflected attribute. |
| 201 | + |
| 202 | + // 7. Return newItem. |
| 203 | + return new_item; |
| 204 | +} |
| 205 | + |
| 206 | +template class SVGList<GC::Ref<SVGTransform>>; |
| 207 | + |
| 208 | +} |
0 commit comments