%PDF- %PDF-
| Direktori : /proc/self/root/usr/share/nodejs/jsdom/lib/jsdom/living/svg/ |
| Current File : //proc/self/root/usr/share/nodejs/jsdom/lib/jsdom/living/svg/SVGListBase.js |
"use strict";
const DOMException = require("domexception/webidl2js-wrapper");
const idlUtils = require("../generated/utils");
const { attach, detach } = require("../helpers/svg/basic-types");
// https://svgwg.org/svg2-draft/types.html#ListInterfaces
// Child classes must implement _reserialize()
class List {
_initList({
element,
attribute,
readOnly = false
}) {
this._element = element;
this._attribute = attribute;
this._attributeRegistryEntry = element.constructor.attributeRegistry.get(attribute);
this._readOnly = readOnly;
this._list = [];
this._version = -1;
}
get _needsResync() {
return this._version < this._element._version;
}
_synchronize() {
if (!this._needsResync) {
return;
}
let value = [];
if (this._element.hasAttributeNS(null, this._attribute)) {
value = this._attributeRegistryEntry.getValue(this._element.getAttributeNS(null, this._attribute));
}
if (value.length === 0 && this._attributeRegistryEntry.initialValue !== undefined) {
value = this._attributeRegistryEntry.getValue(this._attributeRegistryEntry.initialValue);
}
// TODO: support non-DOMString lists.
this._list = value;
this._version = this._element._version;
}
_reserialize() {
const elements = this._list;
this._element.setAttributeNS(null, this._attribute, this._attributeRegistryEntry.serialize(elements));
// Prevent ping-ponging back and forth between _reserialize() and _synchronize().
this._version = this._element._version;
}
[idlUtils.supportsPropertyIndex](index) {
this._synchronize();
return index >= 0 && index < this.length;
}
get [idlUtils.supportedPropertyIndices]() {
this._synchronize();
return this._list.keys();
}
get length() {
this._synchronize();
return this._list.length;
}
get numberOfItems() {
this._synchronize();
return this._list.length;
}
clear() {
this._synchronize();
if (this._readOnly) {
throw DOMException.create(this._globalObject, [
"Attempting to modify a read-only list",
"NoModificationAllowedError"
]);
}
for (const item of this._list) {
detach(item);
}
this._list.length = 0;
this._reserialize();
}
initialize(newItem) {
this._synchronize();
if (this._readOnly) {
throw DOMException.create(this._globalObject, [
"Attempting to modify a read-only list",
"NoModificationAllowedError"
]);
}
for (const item of this._list) {
detach(item);
}
this._list.length = 0;
// TODO: clone non-DOMString list elements.
attach(newItem, this);
this._list.push(newItem);
this._reserialize();
}
getItem(index) {
this._synchronize();
if (index >= this._list.length) {
throw DOMException.create(this._globalObject, [
`The index provided (${index}) is greater than or equal to the maximum bound (${this._list.length}).`,
"IndexSizeError"
]);
}
return this._list[index];
}
insertItemBefore(newItem, index) {
this._synchronize();
if (this._readOnly) {
throw DOMException.create(this._globalObject, [
"Attempting to modify a read-only list",
"NoModificationAllowedError"
]);
}
// TODO: clone non-DOMString list elements.
if (index > this._list.length) {
index = this._list.length;
}
this._list.splice(index, 0, newItem);
attach(newItem, this);
this._reserialize();
return newItem;
}
replaceItem(newItem, index) {
this._synchronize();
if (this._readOnly) {
throw DOMException.create(this._globalObject, [
"Attempting to modify a read-only list",
"NoModificationAllowedError"
]);
}
if (index >= this._list.length) {
throw DOMException.create(this._globalObject, [
`The index provided (${index}) is greater than or equal to the maximum bound (${this._list.length}).`,
"IndexSizeError"
]);
}
// TODO: clone non-DOMString list elements.
detach(this._list[index]);
this._list[index] = newItem;
attach(newItem, this);
this._reserialize();
return newItem;
}
removeItem(index) {
this._synchronize();
if (this._readOnly) {
throw DOMException.create(this._globalObject, [
"Attempting to modify a read-only list",
"NoModificationAllowedError"
]);
}
if (index >= this._list.length) {
throw DOMException.create(this._globalObject, [
`The index provided (${index}) is greater than or equal to the maximum bound (${this._list.length}).`,
"IndexSizeError"
]);
}
const item = this._list[index];
detach(item);
this._list.splice(index, 1);
this._reserialize();
return item;
}
appendItem(newItem) {
this._synchronize();
// TODO: clone non-DOMString list elements.
this._list.push(newItem);
attach(newItem, this);
this._reserialize();
return newItem;
}
[idlUtils.indexedSetNew](index, value) {
// Note: this will always throw a IndexSizeError.
this.replaceItem(value, index);
}
[idlUtils.indexedSetExisting](index, value) {
this.replaceItem(value, index);
}
}
module.exports = List;