2#include "exceptions.cpp"
14#include <initializer_list>
19#define DOCUMENT_POSITION_DISCONNECTED 0x01
20#define DOCUMENT_POSITION_PRECEDING 0x02
21#define DOCUMENT_POSITION_FOLLOWING 0x04
22#define DOCUMENT_POSITION_CONTAINS 0x08
23#define DOCUMENT_POSITION_CONTAINED_BY 0x10
24#define DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC 0x20
26#define START_TO_START 0
31#define FILTER_ACCEPT 1
32#define FILTER_REJECT 2
35#define SHOW_ALL 0xFFFFFFFF
36#define SHOW_ELEMENT 0x1
37#define SHOW_ATTRIBUTE 0x2
39#define SHOW_CDATA_SECTION 0x8
40#define SHOW_ENTITY_REFERENCE 0x10
41#define SHOW_ENTITY 0x20
42#define SHOW_PROCESSING_INSTRUCTION 0x40
43#define SHOW_COMMENT 0x80
44#define SHOW_DOCUMENT 0x100
45#define SHOW_DOCUMENT_TYPE 0x200
46#define SHOW_DOCUMENT_FRAGMENT 0x400
47#define SHOW_NOTATION 0x800
54struct EventListenerOptions;
105 CDATA_SECTION_NODE = 4,
106 ENTITY_REFERENCE_NODE = 5,
108 PROCESSING_INSTRUCTION_NODE = 7,
111 DOCUMENT_TYPE_NODE = 10,
112 DOCUMENT_FRAGMENT_NODE = 11,
117enum event_phase:
unsigned int{
124enum ShadowRootMode{ openh, closed};
125enum SlotAssignmentMode{ manual, named};
140 UNDEFINED, FAILED, UNCUSTOMIZED, PRECUSTOMIZED, CUSTOM
149void add_abort_algo(
const std::function<
void()> &algo,
AbortSignal* signal);
151void signal_abort(
AbortSignal* signal, std::any reason =
nullptr);
153AbortSignal* create_dependent_abort_signal(std::vector<AbortSignal*> signals,
AbortSignal* signalInterface =
nullptr,
Realm* realm =
nullptr);
154bool fire_event(DOMString e,
EventTarget* target,
Event* temporary_class =
nullptr ,
bool legacy_target_override_flag =
false);
156DOMString replace_data(
Node* node,
unsigned long offset,
unsigned long count, DOMString data);
157Element* create_element(
Document* document, DOMString localName, std::optional<DOMString> namesp, std::optional<DOMString> prefix = std::nullopt, std::optional<DOMString> is = std::nullopt,
bool synchronousCustomElements =
false, std::variant<DOMString,std::nullptr_t,CustomElementRegistry> registry = std::string(
"default"));
158void flatten_element_creation_options(std::variant<DOMString,ElementCreationOptions> options,
Document* document,
CustomElementRegistry* registry, std::optional<DOMString> &is);
160Element* internal_create_element_ns(
Document* document, std::optional<DOMString> namesp, DOMString qualifiedName, std::variant<DOMString,ElementCreationOptions> options);
161void change_attribute_value(
Attr* attribute, DOMString value);
162void append_attribute(
Attr* attribute,
Element* element);
163void remove_attribute(
Attr* attribute);
164void replace_attribute(
Attr* oldAttribute,
Attr* newAttribute);
165Attr* fetch_attribute(DOMString qualifiedName,
Element* element);
166Attr* fetch_attribute(std::optional<DOMString> namesp, DOMString localName,
Element* element);
167DOMString fetch_attribute(
Element* element, DOMString localName, std::optional<DOMString> namesp = std::nullopt);
169void set_attribute_value(
Element* element, DOMString localName, DOMString value, std::optional<DOMString> prefix = std::nullopt, std::optional<DOMString> namesp = std::nullopt);
170Attr* remove_attribute_by_name(DOMString qualifiedName,
Element* element);
171Attr* remove_attribute_by_namespace(std::optional<DOMString> namesp, DOMString localName,
Element* element);
172void attach_shadow_root(
Element* element, ShadowRootMode mode,
bool clonable,
bool serializable,
bool delegatesFocus, SlotAssignmentMode slotAssignment, std::optional<CustomElementRegistry> registry);
174DOMString replace_all(
Node* node,
Node* newParent);
175DOMString substring_data(
Node* node,
unsigned long offset,
unsigned long count);
176bool check_exclusive_text_node(
Text* node);
177std::vector<Text*> contiguous_text_nodes(
Text* node);
178std::vector<Text*> contiguous_exclusive_text_nodes(
Text* node);
179DOMString child_text_content(
Node* node);
180DOMString descendant_text_content(
Node* node);
181Text* split_text_node(
Text* node,
unsigned long offset);
182int position(
Node* nodeA,
unsigned long offsetA,
Node* nodeB,
unsigned long offsetB);
184bool contained_in_range(
Node* node,
Range* range);
185bool partially_contained_in_range(
Node* node,
Range* range);
186void pre_remove_range(
Node* node);
187void set_start_end(
Range* range,
Node* node,
int offset,
bool start =
true);
188void select_node_within_rangee(
Node* node,
Range* range);
191void insert_node_in_range(
Node* node,
Range* range);
196bool inner_invoke(
Event* event, std::vector<event_listener*> &listeners,
enum event_phase phase,
bool invocationTargetInShadowTree, std::optional<bool> legacyOutputDidListenersThrowFlag = std::nullopt);
197void append_to_event_path(
Event* event,
EventTarget* invocationTarget,
EventTarget* shadowAdjustedTarget,
EventTarget* relatedTarget, std::vector<EventTarget*> &touchTargets,
bool slot_in_closed_tree);
198void invoke_event(
path_structs &struc,
Event* event,
enum event_phase phase, std::optional<bool> legacyOutputDidListenersThrowFlag = std::nullopt);
201bool nodequals(
Node* first,
Node* second);
202void string_replace_all(std::string &str,
Node* parent);
203std::optional<DOMString> locate_a_namespace(
Node* node, std::optional<DOMString> prefix);
204std::optional<DOMString> locate_a_namespace_prefix(
Element* element, std::optional<DOMString> namesp);
206int determine_node_length(
Node* node);
207Node* convert_nodes_to_node(std::vector<std::variant<Node*, DOMString>> nodes,
Document* document);
208bool check_ancestor(
Node* node,
Node* target,
bool inclusive =
false);
209bool check_descendant(
Node* node,
Node* target,
bool inclusive =
false);
211bool check_shadow_including_descendant(
Node* node,
Node* target,
bool inclusive =
false);
212bool is_closed_shadow_hidden(
Node* A,
Node* B);
214bool host_including_inclusive_ancestor(
Node* A,
Node* B);
215void ensure_pre_insert_validity(
Node* node,
Node* parent,
Node* child);
219void insert_node(
Node* node,
Node* parent,
Node* child,
bool suppress_observers =
false);
222void remove_node(
Node* node);
223void before(std::vector<std::variant<Node*, DOMString>> &nodes,
Node* obj);
224void after(std::vector<std::variant<Node*, DOMString>>& nodes,
Node* obj);
225void replaceWith(std::vector<std::variant<Node*, DOMString>> &nodes,
Node* obj);
226void remove(
Node* obj);
232bool default_passive_value(
const DOMString &type,
EventTarget* eventTarget);
233bool dispatch_event(
Event* event,
EventTarget* target, std::optional<bool> legacy_target_override_flag = std::nullopt, std::optional<bool> legacy_output_did_listeners_throw_flag = std::nullopt);
244 Event*
event =
nullptr;
257 void handleEvent(
const Event* event);
262struct event_listener{
265 bool capture =
false;
266 std::optional<bool> passive = std::nullopt;
269 bool removed =
false;
271 event_listener(
const DOMString &type,
EventListener* callback =
nullptr,
bool capture =
false,
const std::optional<bool> passive = std::nullopt,
bool once =
false,
AbortSignal *signal =
nullptr,
bool removed =
false){
273 this->callback = callback;
274 this->capture = capture;
275 this->passive = passive;
277 this->signal = signal;
278 this->removed = removed;
281 bool operator==(event_listener &ev)
const{
282 return (this->type==ev.type && this->callback==ev.callback && this->capture==ev.capture && this->passive==ev.passive && this->once==ev.once && this->signal==ev.signal && this->removed==ev.removed);
284 bool operator!=(event_listener &ev)
const{
290struct AddEventListenerOptions{
292 std::optional<bool> passive = std::nullopt;
296 AddEventListenerOptions(
bool capture, std::optional<bool> passive,
bool once,
AbortSignal* signal =
nullptr){
297 this->capture = capture;
298 this->passive = passive;
300 this->signal = signal;
306 bool has_activation_behavior =
false;
307 bool has_legacy_canceled_activation_behavior =
false;
308 bool has_legacy_pre_activation_behavior =
false;
311 std::function<void(
Event* event)> activation_behavior_algorithm = [](
Event* event) {};
312 std::function<void()> legacy_canceled_activation_behavior_algorithm = []() {};
313 std::function<void()> legacy_pre_activation_behavior_algorithm = []() {};
315 std::vector<event_listener*> event_listener_list = {};
319 void addEventListener(DOMString &type,
EventListener* callback, std::variant<AddEventListenerOptions,bool> &options);
320 void removeEventListener(DOMString &type,
EventListener* callback,
bool capture);
321 void removeAllEventListeners();
322 bool dispatchEvent(
Event* event);
324 bool operator==(
const EventTarget &a){
325 if (this->event_listener_list.size()!=a.event_listener_list.size()){
329 for (
size_t i=0; i<this->event_listener_list.size(); i++){
330 if (*(this->event_listener_list[i])!=*(a.event_listener_list[i])){
337 bool operator!=(
const EventTarget &a){
341 virtual EventTarget* get_the_parent(
const Event* event){
345 virtual ~EventTarget() =
default;
351 bool dependent =
false;
352 std::any reason =
nullptr;
356 static AbortSignal* abort(std::any reason =
nullptr);
358 static AbortSignal* _any(std::vector<AbortSignal*> signals);
361 void throwIfAborted();
364 std::vector<AbortSignal*> source_signals = {};
365 std::vector<AbortSignal*> dependent_signals = {};
367 std::vector<std::function<void()>> abort_algos = {};
374 return this->isaborted();
377 if (this->reason.has_value()){
379 auto k = std::any_cast<std::nullptr_t>(this->reason);
382 catch(std::bad_any_cast){
389 return this->dependent;
391 void setdependent(
bool dependent){
392 this->dependent = dependent;
394 std::any getreason(){
401class AbortController{
405 void abort(std::any reason =
nullptr)
const;
407 virtual ~AbortController() =
default;
415 bool invocation_target_in_shadow_tree;
418 std::vector<EventTarget*> touch_target_list = {};
419 bool root_of_closed_tree;
420 bool slot_in_closed_tree;
422 path_structs(
EventTarget *it =
nullptr,
bool itst =
false,
EventTarget *sat =
nullptr,
EventTarget *rt =
nullptr, std::vector<EventTarget*> ttl = {},
bool rct =
false,
bool sct =
false){
423 this->invocation_target = it;
424 this->invocation_target_in_shadow_tree = itst;
425 this->shadow_adjusted_target = sat;
426 this->related_target = rt;
427 this->touch_target_list = ttl;
428 this->root_of_closed_tree = rct;
429 this->slot_in_closed_tree = sct;
439 enum event_phase eventPhase = NONE;
443 DOMHighResTimeStamp timeStamp;
445 bool isTrusted =
false;
448 Event(
const DOMString &type,
bool bubbles =
false,
bool cancelable =
false,
bool composed =
false);
449 Event(
const Event* temp);
451 void inner_event_creation_steps(Event* event,
Realm* realm, DOMHighResTimeStamp &time,
bool bubbles =
false,
bool cancelable =
false,
bool composed =
false);
454 bool stop_propagation_flag =
false;
455 bool stop_immediate_propagation_flag =
false;
456 bool canceled_flag =
false;
457 bool in_passive_listener_flag =
false;
458 bool composed_flag =
false;
459 bool initialized_flag =
false;
460 bool dispatch_flag =
false;
463 std::vector<path_structs> path = {};
464 std::vector<EventTarget*> touch_target_list = {};
466 void initEvent(DOMString type,
bool bubbles =
false,
bool cancelable =
false);
467 void stopPropagation();
468 void stopImmediatePropagation();
469 void preventDefault();
470 std::vector<EventTarget*> composedPath();
471 void set_canceled_flag();
475 DOMString gettype()
const{
485 return this->relatedTarget;
488 return this->currentTarget;
490 enum event_phase geteventPhase()
const{
491 return this->eventPhase;
493 void seteventPhase(
enum event_phase temp){
494 this->eventPhase = temp;
496 bool getbubbles()
const{
497 return this->bubbles;
499 bool getcancelable()
const{
500 return this->cancelable;
502 bool getdefaultPrevented()
const{
503 return this->canceled_flag;
505 bool getcomposed()
const{
506 return this->composed_flag;
508 bool getisTrusted()
const{
509 return this->isTrusted;
511 DOMHighResTimeStamp gettimeStamp()
const{
512 return this->timeStamp;
515 bool getcancelBubble()
const{
516 return this->stop_propagation_flag;
518 void setcancelBubble(
bool value){
520 this->stop_propagation_flag =
true;
524 bool getreturnValue()
const{
525 return !this->canceled_flag;
527 void setreturnValue(
bool value){
529 this->set_canceled_flag();
534 virtual bool operator==(Event* ev){
535 if (this->type == ev->gettype() && this->target == ev->gettarget() && this->timeStamp == ev->gettimeStamp()){
541 virtual Event* newObject(){
542 return new Event(this->type);
545 virtual ~Event() =
default;
549class CustomEvent:
public Event{
551 std::any detail =
nullptr;
552 CustomEvent(DOMString
const type, std::any &detail,
bool bubbles =
false,
bool cancelable =
false,
bool composed =
false);
553 void initCustomEvent(DOMString
const type,
bool bubbles =
false,
bool cancelable =
false, std::any detail =
nullptr);
555 std::any getdetail()
const{
559 CustomEvent(
const CustomEvent* temp): Event(temp->type, temp->bubbles, temp->cancelable, temp->composed){
560 this->detail = temp->detail;
563 virtual ~CustomEvent() =
default;
568class MouseEvent:
public Event{
570 MouseEvent(
const DOMString &type,
bool bubbles =
false,
bool cancelable =
false,
bool composed =
false):Event(type,bubbles,cancelable,composed){};
572 virtual ~MouseEvent() =
default;
592 std::vector<Node*> node_list = {};
595 Node* item(
const unsigned long index)
const;
598 Node* operator[](
unsigned long index)
const {
599 return this->item(index);
602 bool operator==(
const NodeList* otherNodeList)
const;
605 [[nodiscard]]
unsigned long length()
const;
607 void append(
Node* node){
608 this->node_list.push_back(node);
611 void insert(
Node* node,
const unsigned long &index){
612 if (index<0){
return;}
613 this->node_list.insert(this->node_list.begin()+index, node);
616 void remove(
Node* node);
624class Node:
public EventTarget{
633 Element* parentElement =
nullptr;
638 virtual Node* firstChild();
639 virtual Node* lastChild();
640 virtual Node* previousSibling();
641 virtual Node* nextSibling();
643 bool hasChildNodes()
const;
645 Node* getRootNode(
bool composed =
false);
648 DOMString textContent;
650 Node* cloneNode(
bool subtree);
653 Node(node_type nodeType, DOMString nodeName,
Document* ownerDocument =
nullptr, Node* parentNode =
nullptr);
655 unsigned long length(){
667 bool isEqualNode(Node* otherNode);
668 bool isSameNode(Node* otherNode);
670 unsigned short compareDocumentPosition(Node* other);
671 bool contains(Node* other);
673 virtual std::optional<DOMString> lookupPrefix(std::optional<DOMString> &namesp);
674 std::optional<DOMString> lookupNamespaceURI(std::optional<DOMString> &prefix);
676 bool isDefaultNamespace(std::optional<DOMString> &namesp);
678 Node* insertBefore(Node* node, Node* child);
679 Node* appendChild(Node* node);
680 Node* replaceChild(Node* node, Node* child);
681 Node* removeChild(Node* child);
683 virtual Node* get_the_parent(
Event* event);
685 virtual std::optional<DOMString> getnodeValue(){
688 virtual void setnodeValue(DOMString &val){};
689 virtual std::optional<DOMString> gettextContent(){
692 virtual void settextContent(DOMString &val){};
695 bool operator==(Node& other){
return this->isEqualNode(&other); }
698 bool operator^(Node* other){
699 Node* currentNode = other->childNodes[0];
700 std::vector<Node*> temp = {currentNode};
701 while (currentNode!=
nullptr){
702 if (currentNode ==
this){
705 if (currentNode->childNodes.length()!=0){
706 temp.push_back(currentNode);
707 currentNode = currentNode->firstChild();
710 currentNode = currentNode->nextSibling();
711 while (currentNode==
nullptr && !temp.empty()){
712 currentNode = (*(temp.end() -1))->nextSibling();
713 temp.erase(temp.end()-1);
719 unsigned long index(){
720 auto a = std::find(this->childNodes.node_list.begin(), this->childNodes.node_list.end(),
this);
721 return a - this->childNodes.node_list.begin();
724 virtual ~Node() =
default;
727std::ostream& operator<<(std::ostream& os,
const Node& node) {
728 if (node.nodeType == 1) {
729 os <<
"ELEMENT NODE\n" << node.nodeName;
731 os <<
"OTHER NODE\n" << node.nodeName;
738 bool selfOnly =
false;
743 void acceptNode(
Node* node){};
752 bool pointerBeforeReferenceNode;
753 unsigned long whatToShow;
759 Node* previousNode();
767 virtual ~NodeIterator() =
default;
773 unsigned long whatToShow;
786 Node* previousSibling();
788 Node* previousNode();
791 virtual ~TreeWalker() =
default;
798 Node* startContainer;
799 unsigned long startOffset;
801 unsigned long endOffset;
807struct StaticRangeInit{
808 Node* startContainer;
809 unsigned long startOffset;
811 unsigned long endOffset;
812 StaticRangeInit(
Node* sc,
unsigned long sos,
Node* ec,
unsigned long eos){
825 virtual ~StaticRange() =
default;
831 Node* commonAncestorContainer();
834 void setStart(
Node* node,
unsigned long offset);
835 void setEnd(
Node* node,
unsigned long offset);
836 void setStartBefore(
Node* node);
837 void setStartAfter(
Node* node);
838 void setEndBefore(
Node* node);
839 void setEndAfter(
Node* node);
840 void collapse(
bool toStart =
false);
841 void selectNode(
Node* node);
842 void selectNodeContents(
Node* node);
844 short compareBoundaryPoints(
unsigned short how, Range* sourceRange);
847 void deleteContents();
850 void insertNode(
Node* node);
851 void surroundContents(
Node* newParent);
855 bool isPointInRange(
Node* node,
unsigned long offset);
856 short comparePoint(
Node* node,
unsigned long offset);
857 bool intersectsNode(
Node* node);
860 DOMString stringification_behavior();
863 virtual ~Range() =
default;
884 std::vector<Element*> element_list = {};
887 Element* item(
const unsigned long &index)
const;
890 Element* operator[](
const unsigned long &index)
const {
891 return this->item(index);
896 Element* operator[](
const DOMString &name)
const{
901 [[nodiscard]]
unsigned long length()
const;
904 this->element_list.push_back(node);
907 void insert(
Element* node,
const unsigned long &index){
908 if (index<0){
return;}
909 this->element_list.insert(this->element_list.begin()+index, node);
914 for (
auto a: this->element_list){
927class ParentNode:
public Node {
930 Element* firstElementChild()
const{
931 return children.item(0);
933 Element* lastElementChild()
const{
934 return this->children.item(this->children.length()-1);
937 unsigned long childElementCount()
const{
938 return children.length();
941 void evaluate_children(){
942 for (
auto a: this->childNodes.node_list){
949 void prepend(std::vector<std::variant<Node*, DOMString>> &nodes);
950 void append(std::vector<std::variant<Node*, DOMString>> &nodes);
951 void replaceChildren(std::vector<std::variant<Node*, DOMString>> &nodes);
952 void moveBefore(Node* node,Node* child);
954 Element* querySelector(DOMString selectors);
955 NodeList querySelectorAll(DOMString selectors);
957 virtual void making_it_abstract(){};
959 ParentNode(node_type nodeType, DOMString nodeName,
Document* ownerDocument, Node* parentNode): Node(nodeType, nodeName, ownerDocument, parentNode){};
961 virtual ~ParentNode() =
default;
965class Attr:
public Node{
967 std::optional<DOMString> namespaceURI = std::nullopt;
968 std::optional<DOMString> prefix = std::nullopt;
971 Element* ownerElement =
nullptr;
972 bool specified =
true;
974 DOMString value =
"";
975 DOMString qualifiedName();
977 Attr(DOMString localName);
980 void setvalue(DOMString value){
981 if (this->ownerElement==
nullptr){ this->value = value; }
985 virtual ~Attr() =
default;
989class CharacterData:
public Node{
993 unsigned long length();
994 DOMString substringData(
unsigned long offset,
unsigned long count);
995 void appendData(DOMString data);
996 void insertData(
unsigned long offset, DOMString data);
997 void deleteData(
unsigned long offset,
unsigned long count);
998 void replaceData(
unsigned long offset,
unsigned long count, DOMString data);
999 Element* previousElementSibling();
1000 Element* nextElementSibling();
1007 CharacterData(
Document* ownerdoc =
nullptr, Node* parentnode =
nullptr): Node(CDATA_SECTION_NODE,
"#cdata-section", ownerdoc, parentnode){};
1009 DOMString getdata(){
return this->data; }
1010 virtual void setdata(DOMString data){
1011 replace_data(
this, 0, this->length(),data);
1014 virtual ~CharacterData() =
default;
1017class Text:
public CharacterData{
1019 DOMString wholeText();
1023 virtual void setdata(DOMString data)
override{
1024 replace_data(
this, 0, this->length(),data);
1028 this->setdata(data);
1030 Text* splitText(
unsigned long offset);
1032 virtual ~Text() =
default;
1037class ProcessingInstruction:
public CharacterData{
1041 virtual void setdata(DOMString data)
override{
1042 replace_data(
this, 0, this->length(),data);
1045 ProcessingInstruction(
Document* ownerdoc =
nullptr,
Node* parentnode =
nullptr): CharacterData(ownerdoc, parentnode){};
1047 virtual ~ProcessingInstruction() =
default;
1052class Comment:
public CharacterData{
1055 virtual void setdata(DOMString data)
override{
1056 replace_data(
this, 0, this->length(),data);
1059 Comment(DOMString data =
""){
1060 this->setdata(data);
1063 virtual ~Comment() =
default;
1071 virtual void setdata(DOMString data)
override{
1072 replace_data(
dynamic_cast<Node*
>(
this),0, this->length(),data);
1079class Document:
public ParentNode{
1083 USVString URL =
"about:blank";
1086 DOMString contentType =
"application/xml";
1091 DOMString encoding =
"utf-8";
1093 DOMString* origin =
nullptr;
1094 DocMode mode = NO_QUIRKS;
1095 bool allow_declarative_shodow_roots =
false;
1097 Document(Document* ownerdoc =
nullptr,
Node* parentnode =
nullptr): ParentNode(DOCUMENT_NODE,
"#document", ownerdoc, parentnode){
1101 DOMString compatMode();
1103 DOMString* lookupPrefix(std::optional<DOMString> namesp);
1106 HTMLCollection* getElementsByTagNameNS(std::optional<DOMString> namesp, DOMString localname);
1107 HTMLCollection* getElementsByClassName(std::vector<DOMString> &classNames);
1108 friend Element* getElementById(
Node* node,
const DOMString &elementId);
1111 Element* createElement(DOMString localName, std::variant<DOMString,ElementCreationOptions> options);
1112 Element* createElementNS(std::optional<DOMString> namesp, DOMString qualifiedName, std::variant<DOMString,ElementCreationOptions> options);
1113 Node* importNode(
Node* node, std::variant<bool,ImportNodeOptions> options =
false);
1118 Text* createTextNode(DOMString data);
1120 Comment* createComment(DOMString data);
1122 Attr* createAttribute(DOMString localName);
1123 Attr* createAttributeNS(std::optional<DOMString> namesp, DOMString qualifiedName);
1124 Event* createEvent(DOMString interface);
1125 Range* createRange();
1130 return this->custom_element_registry;
1133 virtual Node* get_the_parent(Event* event){
1134 if (event->gettype()==
"load"){
1140 virtual void making_it_abstract(){};
1142 virtual ~Document() =
default;
1146class DocumentType:
public Node{
1157 DocumentType(DOMString name,DOMString publicId=
"",DOMString systemId=
"",
Document* ownerdoc =
nullptr, Node* parentnode =
nullptr): Node(DOCUMENT_TYPE_NODE, name, ownerdoc, parentnode){
1159 this->publicId = publicId;
1160 this->systemId = systemId;
1162 DOMString getname(){
1165 DOMString getpublicId(){
1168 DOMString getsystemId(){
1172 virtual ~DocumentType() =
default;
1176class DocumentFragment:
public ParentNode{
1178 Element* associatedHost =
nullptr;
1179 friend Element* getElementById(
Node* node ,
const DOMString &elementId);
1180 DocumentFragment(
Document* ownerdoc =
nullptr,
Node* parentnode =
nullptr): ParentNode(DOCUMENT_FRAGMENT_NODE,
"#document-fragment", ownerdoc, parentnode){};
1182 virtual ~DocumentFragment() =
default;
1190 ShadowRootMode mode;
1191 bool delegatesFocus =
false;
1192 bool availableToElementInternals =
false;
1193 bool declarative =
false;
1194 SlotAssignmentMode slotAssignment;
1195 bool clonable =
false;
1196 bool serializable =
false;
1197 Element* host(){
return this->associatedHost; }
1200 bool keepCustomElementRegistryNull =
false;
1214struct ElementCreationOptions{
1215 CustomElementRegistry* CustomElementRegistry =
nullptr;
1216 std::optional<DOMString> is = std::nullopt;
1218 ElementCreationOptions(){};
1221struct ShadowRootInit{
1222 ShadowRootMode mode;
1223 bool delegatesFocus =
false;
1224 SlotAssignmentMode slotAssignment = named;
1225 bool clonable =
false;
1226 bool serializable =
false;
1229 ShadowRootInit(ShadowRootMode mod){
1237 std::vector<Attr*> attribute_list = {};
1239 unsigned long length();
1240 Attr* item(
unsigned long index);
1241 Attr* getNamedItem(DOMString qualifiedName);
1243 Attr* getNamedItemNS(std::optional<DOMString> namesp, DOMString localName);
1248 Attr* removeNamedItem(DOMString qualifiedName);
1249 Attr* removeNamedItemNS(std::optional<DOMString> namesp, DOMString localName);
1255class Element:
public ParentNode{
1257 std::optional<DOMString> namespaceURI;
1258 std::optional<DOMString> prefix;
1259 DOMString localName;
1264 ElementState customElementState;
1267 DOMString className;
1270 std::optional<DOMString> is;
1272 DOMString html_uppercased_qualified_name(){
1273 DOMString qualified_name;
1274 if (this->prefix==std::nullopt){ qualified_name = this->localName; }
1275 else{ qualified_name = this->prefix.value() +
":" + this->localName; }
1279 return qualified_name;
1282 Element(std::optional<DOMString> namesp, std::optional<DOMString> prefix, DOMString localName,
CustomElementRegistry* customElementRegistry =
nullptr, ElementState customElementState = UNDEFINED,
Document* ownerdoc =
nullptr,
Node* parentnode =
nullptr): ParentNode(ELEMENT_NODE, this->html_uppercased_qualified_name(), ownerdoc, parentnode){
1283 this->namespaceURI = namesp;
1284 this->prefix = prefix;
1285 this->localName = localName;
1286 this->customElementRegistry = customElementRegistry;
1287 this->customElementState = customElementState;
1290 Element* previousElementSibling();
1291 Element* nextElementSibling();
1293 DOMString tagName(){
1294 return this->html_uppercased_qualified_name();
1298 void setAttribute(DOMString qualifiedName, DOMString value);
1299 void setAttributeNS(std::optional<DOMString> namesp, DOMString qualifiedName, DOMString value);
1300 void removeAttribute(DOMString qualifiedName);
1301 void removeAttributeNS(std::optional<DOMString> namesp, DOMString localName);
1302 bool toggleAttribute(DOMString qualifiedName, std::optional<bool> force);
1303 Attr* setAttributeNode(
Attr* attr);
1304 Attr* setAttributeNodeNS(
Attr* attr);
1305 Attr* removeAttributeNode(
Attr* attr);
1307 bool hasAttributes();
1308 std::vector<DOMString> getAttributeNames();
1309 std::optional<DOMString> getAttribute(DOMString qualifiedName);
1310 std::optional<DOMString> getAttributeNS(std::optional<DOMString> namesp, DOMString localName);
1311 bool hasAttribute(DOMString qualifiedName);
1312 bool hasAttributeNS(std::optional<DOMString> namesp, DOMString localname);
1314 Attr* getAttributeNode(DOMString qualifiedName);
1315 Attr* getAttributeNodeNS(std::optional<DOMString> namesp, DOMString localName);
1318 std::optional<Element> closest(DOMString selectors);
1319 bool matches(DOMString selectors);
1322 HTMLCollection* getElementsByTagNameNS(std::optional<DOMString> namesp, DOMString localName);
1325 Element* insertAdjacentElement(DOMString where, Element element);
1326 void insertAdjacentText(DOMString where, DOMString data);
1333 bool operator==(Element* other){
return dynamic_cast<Node*
>(
this)->isEqualNode(
dynamic_cast<Node*
>(other)); }
1335 virtual void making_it_abstract(){};
1344 void setid(DOMString value){
1348 DOMString getclassName(){
1352 void setclassName(DOMString value){
1356 DOMString getslot(){
1360 void setslot(DOMString value){
1365 if (this->shadow_root==
nullptr || this->shadow_root->mode==closed){
return nullptr; }
1366 return this->shadow_root;
1369 void update_slot_name(DOMString name, std::optional<DOMString> oldvalue, std::optional<DOMString> value){
1370 if (value == oldvalue){
return; }
1371 if (!value.has_value() && oldvalue.has_value() && oldvalue.value()==
""){
return; }
1372 if (value.has_value() && value.value()==
"" && !oldvalue.has_value()){
return; }
1373 if (!value.has_value() || value.value()==
""){
1374 this->localName =
"";
1377 this->localName = value.value();
1382 virtual ~Element() =
default;
1393 Document* associated_doc =
nullptr;
1395 DocumentType* createDocumentType(DOMString name, DOMString publicId, DOMString systemId);
1396 XMLDocument* createDocument(std::optional<DOMString> namesp, DOMString qualifiedName, std::optional<DocumentType> doctype = std::nullopt);
1398 Document* createHTMLDocument(std::optional<DOMString> title);
1407 std::optional<DOMString> item(
unsigned long index){
1408 if (index>=this->length()){
1409 return std::nullopt;
1413 bool contains(DOMString token){
1414 auto a = this->list.find(token);
1415 if (a == this->list.end()){
1422 void add(std::vector<DOMString> tokens);
1423 void remove(std::vector<DOMString> tokens);
1424 bool toggle(DOMString token, std::optional<bool> force);
1425 bool replace(DOMString token, DOMString newToken);
1426 DOMString getvalue(){
1427 return this->serialize();
1429 void setvalue(DOMString value){
1434 bool supports(DOMString token);
1435 std::set<DOMString> list = {};
1437 Element* associatedElement =
nullptr;
1438 Attr* associatedAttribute =
nullptr;
1440 unsigned long length(){
1441 return this->list.size();
1444 bool validate(DOMString token){
1445 auto ltoken = std::copy(token.begin(),token.begin(), token.end());
1446 std::transform(token.begin(), token.end(), token.begin(), [](
unsigned char c){ return std::tolower(c); });
1451 if (!this->associatedAttribute){
1457 DOMString serialize(){
1463 DOMTokenList(
Element* element =
nullptr,
Attr* attribute =
nullptr){
1464 this->associatedElement = element;
1465 this->associatedAttribute = attribute;
1467 if (this->getvalue()==
""){
1475 virtual ~DOMTokenList() =
default;
1488std::set<DOMString> parse_ordered_set(DOMString input){
1489 std::vector<int> asciiWhitespace = {9,10,12,13,32};
1490 std::vector<DOMString> inputTokens = split_text_multiple(input, asciiWhitespace);
1491 std::set<DOMString> tokens;
1492 for (DOMString a: inputTokens){
1499DOMString serialize_ordered_set(std::set<DOMString> input){
1502 for (
auto a: input){
1503 (void)str.append(a);
1504 if (i!=(input.size()-1)){
1520bool valid_namespace_prefix(DOMString input){
1521 if (input.size()==0){
return false; }
1523 for (
auto it=input.begin(); it!=input.end();){
1525 temp = utf8::next(it, input.end());
1527 catch (utf8::not_enough_room){
1530 if (temp==9 || temp==10 || temp==12 || temp==13 || temp==32 || temp==0 || temp==47 || temp==62){
1547bool valid_attribute_local_name(DOMString input){
1548 if (input.size()==0){
return false; }
1550 for (
auto it=input.begin(); it!=input.end();){
1551 if (temp==9 || temp==10 || temp==12 || temp==13 || temp==32 || temp==0 || temp==47 || temp==61 || temp==62){
1561bool valid_element_local_name(DOMString input){
1562 if (input.size()==0){
return false; }
1563 auto it = input.begin();
1564 unsigned int first = utf8::next(it, input.end());
1566 if ((first>=65 && first<=90) || (first>=97 && first<=122)){
1567 for (;it<input.end();){
1569 temp = utf8::next(it, input.end());
1571 catch (utf8::not_enough_room){
1574 if (temp==9 || temp==10 || temp==12 || temp==13 || temp==32 || temp==0 || temp==47 || temp==62){
1580 if (first!=58 && first!=95 && (first<128 || first>1114111)){
1583 for (it=input.begin();it<input.end();){
1585 temp = utf8::next(it, input.end());
1587 catch (utf8::not_enough_room){
1590 if ((temp<65 || temp>90) && (temp<97 || temp>122) && (temp<48 || temp>57) && temp!=45 && temp!=46 && temp!=58 && temp!=95 && (temp<128 || temp>1114111)){
1605bool valid_doctype_name(DOMString input){
1607 for (
auto it=input.begin(); it<input.end();){
1608 temp = utf8::next(it, input.end());
1609 if (temp==9 || temp==10 || temp==12 || temp==13 || temp==32 || temp==0 || temp==62){
1619bool valid_custom_element_name(DOMString name){
1620 if (!valid_element_local_name(name)){
return false; }
1622 if (a<97 && a>122){
return false; }
1623 bool containsHyphen =
false;
1624 for (
auto ch: name){
1625 if (ch==
'-'){ containsHyphen =
true; }
1627 if (c>=65 && c<=90){
return false; }
1629 if (!containsHyphen){
return false; }
1630 if (name==
"annotation-xml" || name==
"color-profile" || name==
"font-face" || name==
"font-face-src" || name==
"font-face-uri" || name==
"font-face-format" || name==
"font-face-name" || name==
"missing-glyph"){
1636bool valid_shadow_host_name(DOMString name){
1637 if (!valid_custom_element_name(name)){
return false; }
1638 if (name!=
"article" && name!=
"aside" && name!=
"blockquote" && name!=
"body" && name!=
"div" && name!=
"footer" && name!=
"h1" && name!=
"h2" && name!=
"h3" && name!=
"h4" && name!=
"h5" && name!=
"h6" && name!=
"header" && name!=
"main" && name!=
"nav" && name!=
"p" && name!=
"section" && name!=
"span"){
1652void validate_and_extract(std::optional<DOMString> &namesp,DOMString qualifiedName, DOMString context,std::optional<DOMString> &prefix,DOMString &localName){
1653 if (namesp.has_value() && namesp.value()==
""){ namesp = std::nullopt; }
1654 prefix = std::nullopt;
1655 localName = qualifiedName;
1656 if (qualifiedName.find(
":")!=std::string::npos){
1657 std::vector<DOMString> splitResult = split_text(qualifiedName,
":");
1658 prefix = splitResult[0];
1659 localName = splitResult[1];
1660 if (!valid_namespace_prefix(prefix.value())){
throw InvalidCharacterError(
"The prefix aka 'text before colon (:)' in the qualifiedName (2nd arg) should be a valid namespace prefix !"); }
1662 assert(!prefix.has_value() || valid_namespace_prefix(prefix.value()));
1663 if (context==
"attribute" && !valid_attribute_local_name(localName)){
throw InvalidCharacterError(
"qualified name (sometimes, text after colon (:)) isn't a valid attribute name !"); }
1664 if (context==
"element" && !valid_element_local_name(localName)){
throw InvalidCharacterError(
"qualified name (sometimes, text after colon (:)) isn't a valid element name !"); }
1665 if (!prefix.has_value() && !namesp.has_value()){
throw NamespaceError(
"Namespace error !! Namespace & Namespace Prefix are both null !"); }
1666 if (prefix.has_value() && prefix.value()==
"xml" && namesp.has_value() && namesp.value()!=
"http://www.w3.org/XML/1998/namespace"){
throw NamespaceError(
"Namespace error !! Namespace & namespace prefix don't match !"); }
1667 if ((qualifiedName==
"xmlns" ||(prefix.has_value() && prefix.value()==
"xmlns")) && (!namesp.has_value() || namesp.value()!=
"http://www.w3.org/2000/xmlns/")){
throw NamespaceError(
"Namespace error !! Namespace & namespace prefix don't match !"); }
1668 if (namesp.has_value() && namesp.value()==
"http://www.w3.org/2000/xmlns/" && (qualifiedName!=
"xmlns" && (!prefix.has_value() ||(prefix.has_value() && prefix.value()!=
"xmlns")))){
throw NamespaceError(
"Namespace error !! Namespace & namespace prefix don't match !"); }
1683 temp->callback = callback;
1685 temp->passive = std::nullopt;
1686 temp->signal =
nullptr;
1687 if (std::holds_alternative<bool>(options)){
1688 temp->capture = std::get<bool>(options);
1690 else if (std::holds_alternative<AddEventListenerOptions>(options)){
1691 auto opts = std::get<AddEventListenerOptions>(options);
1692 temp->capture = opts.capture;
1693 temp->once = opts.once;
1694 if (opts.passive.has_value()){
1695 temp->passive = opts.passive;
1698 temp->signal = opts.signal;
1705 listener->removed =
true;
1706 auto it = std::find(eventTarget->event_listener_list.begin(),eventTarget->event_listener_list.end(), listener);
1707 if (it!=eventTarget->event_listener_list.end()){
1708 eventTarget->event_listener_list.erase(it);
1712void add_abort_algo(
const std::function<
void()> &algo,
AbortSignal* signal){
1713 if (signal->isaborted()){
1716 signal->abort_algos.push_back(algo);
1720 for (
auto algo: signal->abort_algos){
1723 signal->abort_algos.clear();
1724 fire_event(
"abort", signal);
1727void signal_abort(
AbortSignal* signal, std::any reason) {
1728 if (signal->isaborted()) {
1731 if (reason.has_value()){
1732 signal->reason = reason;
1735 signal->reason =
new AbortError(
"Abort errors !!");
1738 std::vector<AbortSignal*> dependentSignalsToAbort = {};
1739 for (
auto &dependentSignal: signal->dependent_signals) {
1740 if (!(dependentSignal->isaborted())) {
1741 dependentSignal->reason = signal->reason;
1742 dependentSignalsToAbort.push_back(dependentSignal);
1745 run_abort_steps(signal);
1746 for (
const auto &dependentSignal: dependentSignalsToAbort) {
1747 run_abort_steps(dependentSignal);
1752 if (listener->signal !=
nullptr && listener->signal->isaborted()){
return; }
1753 if (listener->callback ==
nullptr){
return; }
1754 if (listener->passive == std::nullopt){
1755 listener->passive = default_passive_value(listener->type, eventTarget);
1759 if (ev->type == listener->type && ev->callback == listener->callback && ev->capture == listener->capture){
1765 eventTarget->event_listener_list.push_back(listener);
1767 if (listener->signal !=
nullptr ){
1768 add_abort_algo(std::bind(remove_event_listener, eventTarget, listener), listener->signal);
1773 AbortSignal* resultSignal = signalInterface->create_object();
1775 if (signal->isaborted()) {
1776 resultSignal->reason = signal->reason;
1777 return resultSignal;
1780 resultSignal->dependent =
true;
1782 if (!(signal-> dependent)) {
1783 resultSignal->source_signals.push_back(signal);
1784 signal->dependent_signals.push_back(resultSignal);
1787 for (
AbortSignal* sourceSignal: signal->source_signals) {
1788 assert(!(sourceSignal->isaborted()) && !(sourceSignal->dependent));
1789 resultSignal->source_signals.push_back(sourceSignal);
1790 sourceSignal->dependent_signals.push_back(resultSignal);
1794 return resultSignal;
1798bool fire_event(DOMString e,
EventTarget* target,
Event* temporary_class,
bool legacy_target_override_flag) {
1800 if (!temporary_class){
1801 event =
new Event(e);
1804 event = temporary_class->newObject();
1807 bool returning_val = dispatch_event(event, target, legacy_target_override_flag);
1809 return returning_val;
1813DOMString replace_data(
Node* node,
unsigned long offset,
unsigned long count, DOMString data){
1814 unsigned length = node->length();
1815 if (offset>length){
throw IndexSizeError(
"greater than error !!"); }
1816 if ((offset+count)>length){ count = length-offset; }
1821Element* create_element(
Document* document, DOMString localName, std::optional<DOMString> namesp, std::optional<DOMString> prefix, std::optional<DOMString> is,
bool synchronousCustomElements, std::variant<DOMString,std::nullptr_t,CustomElementRegistry> registry){
1823 temp->ownerDocument = document;
1824 temp->localName = localName;
1825 temp->namespaceURI = namesp;
1826 temp->prefix = prefix;
1831void flatten_element_creation_options(std::variant<DOMString,ElementCreationOptions> options,
Document* document,
CustomElementRegistry* registry, std::optional<DOMString> &is){
1832 if (std::holds_alternative<ElementCreationOptions>(options)){
1834 if (temp.CustomElementRegistry){
1835 registry = temp.CustomElementRegistry;
1837 if (registry!=document->custom_element_registry){
1840 if (temp.is.has_value()){
1843 if (registry!=
nullptr && is!=std::nullopt){
1847 if (registry==
nullptr){}
1852 if (node->parentNode!=
nullptr){ remove_node(node); }
1858Element* internal_create_element_ns(
Document* document, std::optional<DOMString> namesp, DOMString qualifiedName, std::variant<DOMString,ElementCreationOptions> options){
1859 std::optional<DOMString> prefix;
1860 DOMString localName;
1861 validate_and_extract(namesp, qualifiedName,
"element", prefix, localName);
1863 std::optional<DOMString> is;
1864 flatten_element_creation_options(options, document, registry, is);
1870void change_attribute_value(
Attr* attribute, DOMString value){
1871 DOMString oldValue = attribute->value;
1872 attribute->value = value;
1876void append_attribute(
Attr* attribute,
Element* element){
1877 element->attributes.attribute_list.push_back(attribute);
1878 attribute->ownerElement = element;
1883void remove_attribute(
Attr* attribute){
1884 Element* element = attribute->ownerElement;
1885 element->attributes.attribute_list.erase(std::find(element->attributes.attribute_list.begin(), element->attributes.attribute_list.end(), attribute));
1886 attribute->ownerElement =
nullptr;
1890void replace_attribute(
Attr* oldAttribute,
Attr* newAttribute){
1891 Element* element = oldAttribute->ownerElement;
1892 std::replace(element->attributes.attribute_list.begin(), element->attributes.attribute_list.end(), oldAttribute, newAttribute);
1893 newAttribute->ownerElement = element;
1895 oldAttribute->ownerElement =
nullptr;
1899Attr* fetch_attribute(DOMString qualifiedName,
Element* element){
1903 for (
auto attr: element->attributes.attribute_list){
1904 if (attr->qualifiedName()==qualifiedName){
1911Attr* fetch_attribute(std::optional<DOMString> namesp, DOMString localName,
Element* element){
1912 if (namesp.has_value() && namesp.value()==
""){ namesp = std::nullopt; }
1913 for (
auto attr: element->attributes.attribute_list){
1914 if (attr->namespaceURI==namesp && attr->localName==localName){
1922DOMString fetch_attribute(
Element* element, DOMString localName, std::optional<DOMString> namesp){
1923 Attr* attr = fetch_attribute(namesp, localName, element);
1924 if (attr==
nullptr){
return ""; }
1931 Attr* oldAttr = fetch_attribute(attr->namespaceURI, attr->localName, element);
1932 if (oldAttr==attr){
return attr; }
1933 if (oldAttr!=
nullptr){
1934 replace_attribute(oldAttr, attr);
1937 append_attribute(attr, element);
1943void set_attribute_value(
Element* element, DOMString localName, DOMString value, std::optional<DOMString> prefix, std::optional<DOMString> namesp){
1944 Attr* attribute = fetch_attribute(namesp, localName, element);
1945 if (attribute==
nullptr){
1947 attr->namespaceURI = namesp;
1948 attr->prefix = prefix;
1949 attr->value = value;
1951 append_attribute(attr, element);
1954 change_attribute_value(attribute, value);
1957Attr* remove_attribute_by_name(DOMString qualifiedName,
Element* element){
1958 Attr* attr = fetch_attribute(qualifiedName, element);
1960 remove_attribute(attr);
1965Attr* remove_attribute_by_namespace(std::optional<DOMString> namesp, DOMString localName,
Element* element){
1966 Attr* attr = fetch_attribute(namesp, localName, element);
1968 remove_attribute(attr);
1973void attach_shadow_root(
Element* element, ShadowRootMode mode,
bool clonable,
bool serializable,
bool delegatesFocus, SlotAssignmentMode slotAssignment, std::optional<CustomElementRegistry> registry){
1974 if (element->namespaceURI!=
"http://www.w3.org/1999/xhtml"){
throw NotSupportedError(
"nope not supported"); }
1977 if (element->getshadow_root()!=
nullptr){
1978 ShadowRoot* currentShadowRoot = element->getshadow_root();
1979 if (!currentShadowRoot->declarative || currentShadowRoot->mode!=mode){
throw NotSupportedError(
"nope not supporting :) !"); }
1981 for (
auto child: currentShadowRoot->childNodes.node_list){
1984 currentShadowRoot->declarative =
false;
1990 shadow->associatedHost = element;
1991 shadow->mode = mode;
1992 shadow->delegatesFocus = delegatesFocus;
1993 if (element->customElementState==PRECUSTOMIZED && element->customElementState==CUSTOM){
1994 shadow->availableToElementInternals =
true;
1996 shadow->slotAssignment = slotAssignment;
1997 shadow->declarative =
false;
1998 shadow->clonable = clonable;
1999 shadow->serializable = serializable;
2000 shadow->custom_element_registry = ®istry.value();
2001 element->shadow_root = shadow;
2005 std::transform(where.begin(), where.end(), where.begin(), [](
unsigned char c){ return std::tolower(c); } );
2006 if (where==
"beforebegin"){
2007 if (element->parentNode==
nullptr){
return nullptr; }
2008 return pre_insert_node(node,
dynamic_cast<Node*
>(element)->parentNode,
dynamic_cast<Node*
>(element));
2010 else if (where==
"afterbegin"){
2011 return pre_insert_node(node,
dynamic_cast<Node*
>(element),
dynamic_cast<Node*
>(element)->firstChild());
2013 else if (where==
"beforeend"){
2014 return pre_insert_node(node,
dynamic_cast<Node*
>(element),
nullptr);
2016 else if (where==
"afterend"){
2017 if (element->parentNode==
nullptr){
return nullptr; }
2018 return pre_insert_node(node, element->parentNode,
dynamic_cast<Node*
>(element)->nextSibling());
2025DOMString replace_all(
Node* node,
Node* newParent){
2030DOMString substring_data(
Node* node,
unsigned long offset,
unsigned long count){
2031 unsigned length = node->length();
2032 if (offset>length){
throw IndexSizeError(
"greater than error !!"); }
2034 if ((offset+count)>length){
return temp->getdata().substr(offset); }
2035 return temp->getdata().substr(offset, count);
2039bool check_exclusive_text_node(
Text* node){
2040 if (
dynamic_cast<CDATASection*
>(node)){
return false; }
2044std::vector<Text*> contiguous_text_nodes(
Text* node){
2045 std::vector<Text*> temp = {node};
2046 Text* currentNode =
dynamic_cast<Text*
>(node->previousSibling());
2047 while (currentNode){
2048 temp.insert(temp.begin(), currentNode);
2049 currentNode =
dynamic_cast<Text*
>(currentNode->previousSibling());
2051 currentNode =
dynamic_cast<Text*
>(node->nextSibling());
2052 while (currentNode){
2053 temp.push_back(currentNode);
2054 currentNode =
dynamic_cast<Text*
>(currentNode->nextSibling());
2059std::vector<Text*> contiguous_exclusive_text_nodes(
Text* node){
2060 std::vector<Text*> temp = {node};
2061 Text* currentNode =
dynamic_cast<Text*
>(
dynamic_cast<Node*
>(node)->previousSibling());
2062 auto smth =
dynamic_cast<Node*
>(currentNode);
2063 while (currentNode && !
dynamic_cast<CDATASection*
>(currentNode)){
2064 temp.insert(temp.begin(), currentNode);
2065 currentNode =
dynamic_cast<Text*
>(smth->previousSibling());
2066 smth =
dynamic_cast<Node*
>(currentNode);
2068 currentNode =
dynamic_cast<Text*
>(node->nextSibling());
2069 while (currentNode && !
dynamic_cast<CDATASection*
>(currentNode)){
2070 temp.push_back(currentNode);
2071 currentNode =
dynamic_cast<Text*
>(smth->nextSibling());
2072 smth =
dynamic_cast<Node*
>(currentNode);
2080DOMString child_text_content(
Node* node){
2081 DOMString temp =
"";
2082 for (
auto a: node->childNodes.node_list){
2083 Text* temp2 =
dynamic_cast<Text*
>(a);
2084 if (temp2){ temp+= temp2->getdata(); }
2089DOMString descendant_text_content(
Node* node){
2090 Node* currentNode = node->childNodes[0];
2091 std::vector<Node*> temp = {currentNode};
2093 DOMString data =
"";
2094 while (currentNode!=
nullptr){
2095 temp2 =
dynamic_cast<Text*
>(currentNode);
2098 data += temp3->getdata();
2100 if (currentNode->childNodes.length()!=0){
2101 temp.push_back(currentNode);
2102 currentNode = currentNode->firstChild();
2105 currentNode = currentNode->nextSibling();
2106 while (currentNode==
nullptr && !temp.empty()){
2107 currentNode = (*(temp.end() -1))->nextSibling();
2108 temp.erase(temp.end()-1);
2115Text* split_text_node(
Text* node,
unsigned long offset){
2116 auto smth =
dynamic_cast<Node*
>(node);
2117 unsigned long length = smth->length();
2118 if (offset>length){
throw IndexSizeError(
"size issues ! You are fat :) "); }
2119 unsigned long count = length - offset;
2121 DOMString data = substring_data(smth, offset, count);
2125 Node* parent = smth->parentNode;
2126 if (parent!=
nullptr){
2127 insert_node(
dynamic_cast<Node*
>(new_node), parent, smth->nextSibling());
2129 replace_data(
dynamic_cast<Node*
>(node), offset, count,
"");
2133int position(
Node* nodeA,
unsigned long offsetA,
Node* nodeB,
unsigned long offsetB){
2134 assert(nodeA->getRootNode()==nodeB->getRootNode());
2136 if (offsetA==offsetB){
return 0; }
2137 if (offsetA<offsetB){
return -1; }
2141 int a = position(nodeB, offsetB, nodeA, offsetA);
2142 if (a==-1){
return 1; }
2143 if (a==1){
return -1; }
2145 if (check_ancestor(nodeB, nodeA)){
2146 Node* child = nodeB;
2147 bool ischild =
false;
2151 for (
auto a: nodeA->childNodes.node_list){
2152 if (a==child){ ischild =
true;
break; }
2156 child = child->parentNode;
2168 if (range->startContainer->getRootNode(
true)!=range->endContainer->getRootNode(
true)){
2171 if (range->startOffset<0 || range->startOffset>range->startContainer->length()){
2174 if (range->endOffset<0 || range->endOffset>range->endContainer->length()){
2177 int temp = position(range->startContainer, range->startOffset, range->endContainer, range->endOffset);
2184bool contained_in_range(
Node* node,
Range* range){
2185 if (node->getRootNode()!=range->startContainer->getRootNode()){
2188 int temp = position(node, 0, range->startContainer, range->startOffset);
2189 if (temp==0 || temp==-1){
2192 temp = position(node, node->length(), range->endContainer, range->endOffset);
2193 if (temp==0 || temp==1){
2199bool partially_contained_in_range(
Node* node,
Range* range){
2200 bool one = check_ancestor(range->startContainer, node,
true);
2201 bool two = check_ancestor(range->endContainer, node,
true);
2202 if ((one && !two) || (!one && two)){
2208void pre_remove_range(
Node* node){
2209 Node* parent = node->parentNode;
2210 assert(parent!=
nullptr);
2211 unsigned long index = node->index();
2214void set_start_end(
Range* range,
Node* node,
int offset,
bool start){
2216 if (offset>node->length()){
throw IndexSizeError(
"size issues, fatty !!"); }
2218 if ((range->startContainer->getRootNode()!=node->getRootNode()) || position(node, offset, range->endContainer, range->endOffset)==1){
2219 range->endContainer = node;
2220 range->endOffset = offset;
2222 range->startContainer = node;
2223 range->startOffset = offset;
2226 if ((range->startContainer->getRootNode()!=node->getRootNode()) || position(node, offset, range->startContainer, range->startOffset)==-1){
2227 range->startContainer = node;
2228 range->startOffset = offset;
2230 range->endContainer = node;
2231 range->endOffset = offset;
2236void select_node_within_rangee(
Node* node,
Range* range){
2237 Node* parent = node->parentNode;
2239 unsigned long index = node->index();
2240 range->startContainer = parent;
2241 range->startOffset = index;
2242 range->endContainer = parent;
2243 range->endOffset = index + 1;
2250 if (range->collapsed()){
2253 Node* original_startnode = range->startContainer;
2254 unsigned long original_startoffset = range->startOffset;
2255 Node* original_endnode = range->endContainer;
2256 unsigned long original_endoffset = range->endOffset;
2258 if (original_startnode==original_endnode &&
dynamic_cast<CharacterData*
>(original_startnode)){
2259 Node* temp = clone_node(original_startnode);
2261 clone->setdata(substring_data(original_startnode, original_startoffset, original_endoffset - original_startoffset));
2262 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2263 replace_data(original_startnode, original_startoffset, original_endoffset - original_startoffset,
"");
2266 Node* common_ancestor = original_startnode;
2267 while (!check_ancestor(original_endnode, common_ancestor,
true)){
2268 common_ancestor = common_ancestor->parentNode;
2270 Node* first_partially_contained_child =
nullptr;
2271 if (!check_ancestor(original_endnode, original_startnode,
true)){
2272 for (
auto a: common_ancestor->childNodes.node_list){
2273 if (partially_contained_in_range(a, range)){
2274 first_partially_contained_child = a;
2279 Node* last_partially_contained_child =
nullptr;
2280 if (!check_ancestor(original_startnode, original_endnode,
true)){
2281 for (
auto a: common_ancestor->childNodes.node_list){
2282 if (partially_contained_in_range(a, range)){
2283 last_partially_contained_child = a;
2287 std::vector<Node*> contained_children = {};
2288 for (
auto a: common_ancestor->childNodes.node_list){
2289 if (contained_in_range(a, range)){
2290 contained_children.push_back(a);
2297 unsigned long new_offset;
2298 if (check_ancestor(original_endnode, original_startnode,
true)){
2299 new_node = original_startnode;
2300 new_offset = original_startoffset;
2303 Node* referenceNode = original_startnode;
2304 Node* parent = referenceNode->parentNode;
2305 while (parent!=
nullptr && !check_ancestor(original_endnode, parent,
true)){
2306 referenceNode = parent;
2307 parent = referenceNode->parentNode;
2309 new_node = referenceNode->parentNode;
2310 new_offset = referenceNode->index() + 1;
2312 if (
dynamic_cast<CharacterData*
>(first_partially_contained_child)){
2313 Node* temp = clone_node(original_startnode);
2315 clone->setdata(substring_data(original_startnode, original_startoffset, original_startnode->length() - original_startoffset));
2317 replace_data(original_startnode, original_startoffset, original_startnode->length() - original_startoffset,
"");
2319 else if (first_partially_contained_child!=
nullptr){
2320 Node* temp = clone_node(first_partially_contained_child);
2324 subrange->startContainer = original_startnode;
2325 subrange->startOffset = original_startoffset;
2326 subrange->endContainer = first_partially_contained_child;
2327 subrange->endOffset = first_partially_contained_child->length();
2331 for (
auto child: contained_children){
2334 if (
dynamic_cast<CharacterData*
>(last_partially_contained_child)){
2335 Node* temp = clone_node(original_endnode);
2337 clone->setdata(substring_data(original_endnode, 0, original_endoffset));
2338 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2339 replace_data(original_endnode, 0, original_endoffset,
"");
2341 else if (first_partially_contained_child!=
nullptr){
2342 Node* temp = clone_node(last_partially_contained_child);
2344 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2346 subrange->startContainer = last_partially_contained_child;
2347 subrange->startOffset = 0;
2348 subrange->endContainer = original_endnode;
2349 subrange->endOffset = original_endoffset;
2351 pre_insert_node(
dynamic_cast<Node*
>(subfragment),
dynamic_cast<Node*
>(clone),
nullptr);
2353 range->startContainer = new_node;
2354 range->endContainer = new_node;
2355 range->startOffset = new_offset;
2356 range->endOffset = new_offset;
2365 if (range->collapsed()){
2368 Node* original_startnode = range->startContainer;
2369 unsigned long original_startoffset = range->startOffset;
2370 Node* original_endnode = range->endContainer;
2371 unsigned long original_endoffset = range->endOffset;
2373 if (original_startnode==original_endnode &&
dynamic_cast<CharacterData*
>(original_startnode)){
2374 Node* temp = clone_node(original_startnode);
2376 clone->setdata(substring_data(original_startnode, original_startoffset, original_endoffset - original_startoffset));
2377 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2380 Node* common_ancestor = original_startnode;
2381 while (!check_ancestor(original_endnode, common_ancestor,
true)){
2382 common_ancestor = common_ancestor->parentNode;
2384 Node* first_partially_contained_child =
nullptr;
2385 if (!check_ancestor(original_endnode, original_startnode,
true)){
2386 for (
auto a: common_ancestor->childNodes.node_list){
2387 if (partially_contained_in_range(a, range)){
2388 first_partially_contained_child = a;
2393 Node* last_partially_contained_child =
nullptr;
2394 if (!check_ancestor(original_startnode, original_endnode,
true)){
2395 for (
auto a: common_ancestor->childNodes.node_list){
2396 if (partially_contained_in_range(a, range)){
2397 last_partially_contained_child = a;
2402 std::vector<Node*> contained_children = {};
2403 for (
auto a: common_ancestor->childNodes.node_list){
2404 if (contained_in_range(a, range)){
2405 contained_children.push_back(a);
2412 if (
dynamic_cast<CharacterData*
>(first_partially_contained_child)){
2413 Node* temp = clone_node(original_startnode);
2415 clone->setdata(substring_data(original_startnode, original_startoffset, original_startnode->length() - original_startoffset));
2416 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2418 else if (first_partially_contained_child!=
nullptr){
2419 Node* temp = clone_node(first_partially_contained_child);
2421 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2423 subrange->startContainer = original_startnode;
2424 subrange->startOffset = original_startoffset;
2425 subrange->endContainer = first_partially_contained_child;
2426 subrange->endOffset = first_partially_contained_child->length();
2428 pre_insert_node(
dynamic_cast<Node*
>(subfragment),
dynamic_cast<Node*
>(clone),
nullptr);
2430 for (
auto child: contained_children){
2431 Node* clone = clone_node(
dynamic_cast<Node*
>(child));
2432 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2435 if (
dynamic_cast<CharacterData*
>(last_partially_contained_child)){
2436 Node* temp = clone_node(original_endnode);
2438 clone->setdata(substring_data(original_endnode, 0, original_endoffset));
2439 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2441 else if (first_partially_contained_child!=
nullptr){
2442 Node* temp = clone_node(last_partially_contained_child);
2444 pre_insert_node(
dynamic_cast<Node*
>(clone),
dynamic_cast<Node*
>(fragment),
nullptr);
2446 subrange->startContainer = last_partially_contained_child;
2447 subrange->startOffset = 0;
2448 subrange->endContainer = original_endnode;
2449 subrange->endOffset = original_endoffset;
2451 pre_insert_node(
dynamic_cast<Node*
>(subfragment),
dynamic_cast<Node*
>(clone),
nullptr);
2457void insert_node_in_range(
Node* node,
Range* range){
2458 if (
dynamic_cast<ProcessingInstruction*
>(range->startContainer) ||
dynamic_cast<Comment*
>(range->startContainer) ||(
dynamic_cast<Text*
>(range->startContainer) && range->startContainer->parentNode==
nullptr) || range->startContainer==node){
2461 Node* referenceNode =
nullptr;
2462 if (
dynamic_cast<Text*
>(range->startContainer)){
2463 referenceNode = range->startContainer;
2466 for (
auto a: range->startContainer->childNodes.node_list){
2467 if (a->index()==range->startOffset){
2474 if (!referenceNode){
2475 parent = range->startContainer;
2478 parent = referenceNode->parentNode;
2480 ensure_pre_insert_validity(node, parent, referenceNode);
2481 Text* tempji =
dynamic_cast<Text*
>(range->startContainer);
2483 referenceNode =
dynamic_cast<Node*
>(split_text_node(tempji, range->startOffset));
2485 if (node==referenceNode){
2486 referenceNode = referenceNode->nextSibling();
2488 if (node->parentNode!=
nullptr){
2492 unsigned long newOffset;
2493 if (referenceNode==
nullptr){
2494 newOffset = parent->length();
2497 newOffset = referenceNode->index();
2501 newOffset += node->length();
2507 pre_insert_node(node, parent, referenceNode);
2508 if (range->collapsed()){
2509 range->endContainer = parent;
2510 range->endOffset = newOffset;
2516 if (!check_ancestor(node_iterator->referenceNode, toBeRemovedNode,
true) || toBeRemovedNode==node_iterator->root){
2519 if (node_iterator->pointerBeforeReferenceNode){
2524 node_iterator->pointerBeforeReferenceNode =
false;
2526 if (toBeRemovedNode->previousSibling()==
nullptr){
2530 Node* prev = toBeRemovedNode->previousSibling();
2531 for (
auto a: prev->childNodes.node_list){}
2536 Node* reference = iterator->referenceNode;
2537 bool beforeNode = iterator->pointerBeforeReferenceNode;
2544 if (beforeNode){ beforeNode =
false; }
2546 else if (direction==-1){
2550 if (!beforeNode){ beforeNode =
true; }
2552 unsigned short result = iterator->
filter_node(node);
2553 if (result==FILTER_ACCEPT){
2557 iterator->referenceNode = node;
2558 iterator->pointerBeforeReferenceNode = beforeNode;
2564 Node* node = walker->currentNode;
2567 node = node->firstChild();
2570 node = node->lastChild();
2572 while (node!=
nullptr){
2573 unsigned short result = walker->
filter_node(node);
2574 if (result==FILTER_ACCEPT){
2575 walker->currentNode = node;
2578 else if (result == FILTER_SKIP){
2579 if (type==1){ child = node->firstChild(); }
2580 else if (type==-1){ child = node->lastChild(); }
2583 while (node!=
nullptr){
2586 sibling = node->nextSibling();
2589 sibling = node->previousSibling();
2591 if (sibling!=
nullptr){
2595 Node* parent = node->parentNode;
2596 if (parent==
nullptr || parent==walker->root || parent==walker->currentNode){
2607 Node* node = walker->currentNode;
2608 if (node==walker->root){
2614 sibling = node->nextSibling();
2617 sibling = node->previousSibling();
2619 while (sibling!=
nullptr){
2621 unsigned short result = walker->
filter_node(node);
2623 if (result==FILTER_ACCEPT){
2624 walker->currentNode = node;
2629 sibling = node->firstChild();
2632 sibling = node->lastChild();
2635 if (result==FILTER_REJECT || sibling==
nullptr){
2637 sibling = node->nextSibling();
2640 sibling = node->previousSibling();
2644 node = node->parentNode;
2645 if (node==
nullptr || node==walker->root){
2654bool default_passive_value(
const DOMString &type,
EventTarget* eventTarget){
2655 if (type==
"touchstart" || type==
"touchmove" || type==
"wheel" || type==
"mousewheel"){
2656 if (
dynamic_cast<Window*
>(eventTarget)){
2660 auto temp =
dynamic_cast<Node*
>(eventTarget);
2661 if (temp && temp->ownerDocument==(
dynamic_cast<Document*
>(eventTarget))){
2664 else if (temp &&
dynamic_cast<Document*
>(temp->parentNode)==temp->ownerDocument){
2673bool dispatch_event(
Event* event,
EventTarget* target, std::optional<bool> legacy_target_override_flag, std::optional<bool> legacy_output_did_listeners_throw_flag){
2674 event->dispatch_flag =
true;
2677 if (!legacy_target_override_flag.has_value()) {
2678 targetOverride = target;
2685 EventTarget* relatedTarget = retard(event->getrelatedTarget(), target);
2686 bool clearTargets =
false;
2688 Node* targetNode =
dynamic_cast<Node*
>(target);
2690 if (target!=relatedTarget || target==event->getrelatedTarget()) {
2691 std::vector<EventTarget*> touchTargets = {};
2692 for (
auto touchTarget: event->touch_target_list){
2693 touchTargets.push_back(retard(touchTarget,target));
2696 append_to_event_path(event,target,targetOverride,relatedTarget,touchTargets,
false);
2698 bool isActivationEvent =
false;
2699 if ((
dynamic_cast<MouseEvent*
>(event)) && event->gettype()==
"click"){
2700 isActivationEvent =
true;
2703 if (isActivationEvent && target->has_activation_behavior){
2704 activationTarget = target;
2707 auto te =
dynamic_cast<Element*
>(target);
2708 if (te && te->assignedSlot){
2712 auto f =
dynamic_cast<Text*
>(target);
2713 if (f && f->assignedSlot){
2718 bool slot_in_closed_tree =
false;
2719 EventTarget* parent = target->get_the_parent(event);
2721 auto parentNode =
dynamic_cast<Node*
>(parent);
2722 auto parentRoot =
dynamic_cast<ShadowRoot*
>(parentNode->getRootNode());
2724 assert(
dynamic_cast<Element*
>(parent) && parentRoot && parentRoot->host());
2725 slottable =
nullptr;
2726 if (parentRoot && parentRoot->mode==closed){
2727 slot_in_closed_tree =
true;
2730 auto te =
dynamic_cast<Element*
>(parent);
2731 if (te && te->assignedSlot){
2735 auto f =
dynamic_cast<Text*
>(parent);
2736 if (f && f->assignedSlot){
2740 relatedTarget = retard(event->getrelatedTarget(),parent);
2741 std::vector<EventTarget*> touchTargets = {};
2742 for (
EventTarget* touchboi: event->touch_target_list){
2743 touchTargets.push_back(retard(touchboi,parent));
2745 if (
dynamic_cast<Window*
>(parent) || (parentNode && check_shadow_including_descendant(targetNode->getRootNode(),parentNode,
true))){
2746 if (isActivationEvent && event->getbubbles() && !activationTarget && parent->has_activation_behavior){
2747 activationTarget = parent;
2749 append_to_event_path(event, parent,
nullptr, relatedTarget, touchTargets, slot_in_closed_tree);
2751 else if (parent==relatedTarget){
2756 if (isActivationEvent && !activationTarget && target->has_activation_behavior){
2757 activationTarget = target;
2759 append_to_event_path(event, parent, target, relatedTarget, touchTargets, slot_in_closed_tree);
2762 parent = parent->get_the_parent(event);
2764 slot_in_closed_tree =
false;
2769 if (a.shadow_adjusted_target){
2770 clearTargetsStruct = a;
2774 auto tempShadowAdjustedTarget =
dynamic_cast<Node*
>(clearTargetsStruct.shadow_adjusted_target);
2775 if (tempShadowAdjustedTarget &&
dynamic_cast<ShadowRoot*
>(tempShadowAdjustedTarget->getRootNode())){
2776 clearTargets =
true;
2779 auto tempRelatedTarget =
dynamic_cast<Node*
>(clearTargetsStruct.related_target);
2780 if (tempRelatedTarget &&
dynamic_cast<ShadowRoot*
>(tempRelatedTarget->getRootNode())){
2781 clearTargets =
true;
2785 for (
EventTarget* a: clearTargetsStruct.touch_target_list){
2786 tempNode2 =
dynamic_cast<Node*
>(a);
2787 if (tempNode2 &&
dynamic_cast<ShadowRoot*
>(tempNode2->getRootNode())){
2788 clearTargets =
true;
2796 if (activationTarget && activationTarget->has_legacy_pre_activation_behavior){
2797 activationTarget->legacy_pre_activation_behavior_algorithm();
2799 std::vector<path_structs> rev_path = std::vector<path_structs>(event->path.rbegin(),event->path.rend());
2801 if (struc.shadow_adjusted_target){
2802 event->seteventPhase(AT_TARGET);
2805 event->seteventPhase(CAPTURING_PHASE);
2807 invoke_event(struc, event, CAPTURING_PHASE, legacy_output_did_listeners_throw_flag);
2810 if (a.shadow_adjusted_target){
2811 event->seteventPhase(AT_TARGET);
2814 if (!(event->getbubbles())){
2817 event->seteventPhase(BUBBLING_PHASE);
2819 invoke_event(a, event, BUBBLING_PHASE, legacy_output_did_listeners_throw_flag);
2822 event->seteventPhase(NONE);
2823 event->currentTarget =
nullptr;
2824 event->path.clear();
2825 event->dispatch_flag =
false;
2826 event->stop_propagation_flag =
false;
2827 event->stop_immediate_propagation_flag =
false;
2829 event->target =
nullptr;
2830 event->relatedTarget =
nullptr;
2831 event->touch_target_list.clear();
2833 if (activationTarget){
2834 if (!event->canceled_flag){
2835 activationTarget->activation_behavior_algorithm(event);
2837 else if(activationTarget->has_legacy_canceled_activation_behavior){
2838 activationTarget->legacy_canceled_activation_behavior_algorithm;
2841 if (event->canceled_flag){
2847void append_to_event_path(
Event* event,
EventTarget* invocationTarget,
EventTarget* shadowAdjustedTarget,
EventTarget* relatedTarget, std::vector<EventTarget*> &touchTargets,
bool slot_in_closed_tree){
2848 bool invocationTargetInShadowTree =
false;
2849 auto tempNode =
dynamic_cast<Node*
>(invocationTarget);
2850 if (tempNode &&
dynamic_cast<ShadowRoot*
>(tempNode->getRootNode())){
2851 invocationTargetInShadowTree =
true;
2853 bool root_of_closed_tree =
false;
2854 auto temp =
dynamic_cast<ShadowRoot*
>(invocationTarget);
2855 if (temp && temp->mode==closed){
2856 root_of_closed_tree =
true;
2858 event->path.push_back(
path_structs(invocationTarget, invocationTargetInShadowTree, shadowAdjustedTarget, relatedTarget, touchTargets, root_of_closed_tree, slot_in_closed_tree));
2861bool inner_invoke(
Event* event, std::vector<event_listener*> &listeners,
enum event_phase phase,
bool invocationTargetInShadowTree, std::optional<bool> legacyOutputDidListenersThrowFlag){
2864 if (!(listener->removed)) {
2867 if (event->type!=listener->type) {
2868 std::cout<<
"Event caught of type "<<
event->type;
2872 if ((phase==CAPTURING_PHASE && !(listener->capture)) || (phase==BUBBLING_PHASE && listener->capture)) {
2875 if (listener->once) {
2876 remove_event_listener(event->currentTarget, listener);
2881 Event* currentEvent =
nullptr;
2882 if (listener->passive) {
2883 event->in_passive_listener_flag =
true;
2886 event->in_passive_listener_flag =
false;
2887 if (event->stop_immediate_propagation_flag) {
2895void invoke_event(
path_structs &struc,
Event* event,
enum event_phase phase, std::optional<bool> legacyOutputDidListenersThrowFlag) {
2896 event->target =
nullptr;
2898 if (a.shadow_adjusted_target){
2899 event->target = a.shadow_adjusted_target;
2902 event->relatedTarget = struc.related_target;
2903 event->touch_target_list = struc.touch_target_list;
2904 if (event->stop_propagation_flag){
return; }
2905 event->currentTarget = struc.invocation_target;
2906 std::vector<event_listener*> listeners (event->currentTarget->event_listener_list);
2908 bool invocationTargetInShadowTree = struc.invocation_target_in_shadow_tree;
2909 bool found = inner_invoke(event, listeners, phase, invocationTargetInShadowTree,legacyOutputDidListenersThrowFlag);
2911 if (!found && event->isTrusted) {
2912 DOMString originalEventType =
event->type;
2913 if (event->type==
"animationend") {
2914 event->type =
"webkitAnimationEnd";
2916 else if (event->type==
"animationiteration") {
2917 event->type =
"webkitAnimationIteration";
2919 else if (event->type==
"animationstart") {
2920 event->type =
"webkitAnimationStart";
2922 else if (event->type==
"transitionend") {
2923 event->type =
"webkitTransitionEnd";
2926 inner_invoke(event, listeners, phase, invocationTargetInShadowTree, legacyOutputDidListenersThrowFlag);
2927 event->type = originalEventType;
2936 if (document==
nullptr){
2937 document = node->ownerDocument;
2940 Node* copy = clone_a_single_node(node, document, fallbackRegistry);
2941 if (parent !=
nullptr){
2942 pre_insert_node(copy, parent,
nullptr);
2945 for (
auto child: node->childNodes.node_list){
2946 clone_node(child, document, subtree, copy, fallbackRegistry);
2965 Node* copy =
nullptr;
3034 assert(
dynamic_cast<Node*
>(copy));
3036 copy->ownerDocument = document;
3040bool nodequals(
Node* first,
Node* second){
3041 if (
typeid(first) !=
typeid(second)){
3098 if (first->childNodes.length() != second->childNodes.length()){
3102 for (
auto a: first->childNodes.node_list){
3103 if (!nodequals(a, second->childNodes[i])){
3111void string_replace_all(std::string &str,
Node* parent){
3121std::optional<DOMString> locate_a_namespace(
Node* node, std::optional<DOMString> prefix){
3170 return std::nullopt;
3173std::optional<DOMString> locate_a_namespace_prefix(
Element* element, std::optional<DOMString> namesp){
3185 return std::nullopt;
3211 auto temp =
dynamic_cast<Node*
>(a);
3215 if (!
dynamic_cast<ShadowRoot*
>(temp->getRootNode())){
3218 auto temp2 =
dynamic_cast<Node*
>(b);
3219 if (temp2 && (check_shadow_including_descendant(temp->getRootNode(), temp2,
true))){
3222 auto temp3 =
dynamic_cast<ShadowRoot*
>(temp->getRootNode());
3230int determine_node_length(
Node* node){
3237 return node->childNodes.node_list.size();
3244Node* convert_nodes_to_node(std::vector<std::variant<Node*, DOMString>> nodes,
Document* document) {
3245 Node* node =
nullptr;
3247 for (
auto a: nodes){
3248 if (std::holds_alternative<DOMString>(a)){
3256 node = std::get<Node*>(nodes.at(0));
3267bool check_ancestor(
Node* node,
Node* target,
bool inclusive){
3268 if (inclusive && node->isSameNode(target)){
3271 if (node==
nullptr || target==
nullptr){
3274 Node* parent = node->parentNode;
3284bool check_descendant(
Node* node,
Node* target,
bool inclusive){
3285 if (node==
nullptr || target==
nullptr){
3288 if (node->childNodes.length()==0){
return false; }
3289 if (inclusive && node->isSameNode(target)){
3292 Node* currentNode = node->childNodes[0];
3293 std::vector<Node*> temp = {currentNode};
3294 while (currentNode!=
nullptr){
3295 if (currentNode == target){
3298 if (currentNode->childNodes.length()!=0){
3299 temp.push_back(currentNode);
3300 currentNode = currentNode->firstChild();
3303 currentNode = currentNode->nextSibling();
3304 while (currentNode==
nullptr && !temp.empty()){
3305 currentNode = (*(temp.end() -1))->nextSibling();
3306 temp.erase(temp.end()-1);
3313 if (doc==
nullptr || node==
nullptr || target==
nullptr){
3341bool check_shadow_including_descendant(
Node* node,
Node* target,
bool inclusive){
3342 if (node==
nullptr || target==
nullptr){
3345 if (check_descendant(node, target, inclusive)){
return true; }
3354bool is_closed_shadow_hidden(
Node* A,
Node* B){
3369 temp = A->getRootNode();
3379bool host_including_inclusive_ancestor(
Node* A,
Node* B){
3380 if (check_ancestor(B, A,
true)){
3389void ensure_pre_insert_validity(
Node* node,
Node* parent,
Node* child){
3394 if (host_including_inclusive_ancestor(node, parent)){
3398 if (child && child->parentNode != parent){
3408 int element_count = 0;
3409 int doctype_count = 0;
3410 for (
auto a: parent->childNodes.node_list){
3411 if (
dynamic_cast<Element*
>(a)){ element_count++; }
3412 else if (
dynamic_cast<DocumentType*
>(a)){ doctype_count++; }
3417 for (
auto a: node->childNodes.node_list){
3418 if (
dynamic_cast<Element*
>(a)){ count++; }
3419 if (
dynamic_cast<Text*
>(a)){ has =
true; }
3421 if (count>1 || has){
3425 if (element_count>0 &&
dynamic_cast<DocumentType*
>(child)){
3430 else if (
dynamic_cast<Element*
>(node)){
3431 if (element_count>0 &&
dynamic_cast<DocumentType*
>(child)){
3436 if (doctype_count>0 && child){
3439 if (!child && element_count){
3451 Node* referenceChild = child;
3452 if (referenceChild == node){
3453 referenceChild = node->nextSibling();
3455 insert_node(node, parent, referenceChild);
3459void insert_node(
Node* node,
Node* parent,
Node* child,
bool suppress_observers){
3462 nodes = &node->childNodes;
3466 nodes->node_list.push_back(node);
3468 int count = nodes->length();
3469 if (count==0){
return; }
3472 queue_tree_mutation_record(node,
new NodeList(), nodes,
nullptr,
nullptr);
3477 Node* previousSibling;
3479 previousSibling = child->previousSibling();
3482 previousSibling = parent->lastChild();
3484 for (
auto tempnode: nodes->node_list){
3487 parent->childNodes.append(tempnode);
3490 auto gg = std::find(parent->childNodes.node_list.begin(), parent->childNodes.node_list.end(), child);
3491 if (gg!=parent->childNodes.node_list.end()){
3504void remove_node(
Node* node){}
3507void before(std::vector<std::variant<Node*, DOMString>> &nodes,
Node* obj){
3508 Node* parent = obj->parentNode;
3509 if (parent==
nullptr){
return;}
3510 Node* viablePreviousSibling =
nullptr;
3511 Node* prev = obj->previousSibling();
3514 for (
auto a: nodes){
3515 if (std::holds_alternative<Node*>(a)){
3516 if (std::get<Node*>(a)->isEqualNode(prev)){
3523 viablePreviousSibling = prev;
3526 prev = prev->previousSibling();
3530 Node* node =
new Node(ELEMENT_NODE, kk);
3531 if (viablePreviousSibling==
nullptr){
3532 viablePreviousSibling = parent->firstChild();
3535 viablePreviousSibling = viablePreviousSibling->nextSibling();
3537 pre_insert_node(node, parent, viablePreviousSibling);
3541void after(std::vector<std::variant<Node*, DOMString>>& nodes,
Node* obj){
3542 Node* parent = obj->parentNode;
3543 if (parent==
nullptr){
return;}
3544 Node* viableNextSibling =
nullptr;
3545 Node* next = obj->nextSibling();
3548 for (
auto a: nodes){
3549 if (std::holds_alternative<Node*>(a)){
3550 if (std::get<Node*>(a)->isEqualNode(next)){
3557 viableNextSibling = next;
3560 next = next->nextSibling();
3564 Node* node =
new Node(ELEMENT_NODE, kk);
3565 pre_insert_node(node, parent, viableNextSibling);
3568void replaceWith(std::vector<std::variant<Node*, DOMString>> &nodes,
Node* obj){
3569 Node* parent = obj->parentNode;
3570 if (parent==
nullptr){
return;}
3571 Node* viableNextSibling =
nullptr;
3572 Node* next = obj->nextSibling();
3575 for (
auto a: nodes){
3576 if (std::holds_alternative<Node*>(a)){
3577 if (std::get<Node*>(a)->isEqualNode(next)){
3584 viableNextSibling = next;
3587 next = next->nextSibling();
3592 Node* node =
new Node(ELEMENT_NODE,ff);
3593 if (*obj->parentNode==*parent){
3594 replace(obj, node, parent);
3597 pre_insert_node(node, parent, viableNextSibling);
3601void remove(
Node* obj){
3602 if (obj->parentNode==
nullptr){
return;}
3607 return new Node(ELEMENT_NODE,
"");
3610 return new Node(ELEMENT_NODE,
"");
3622void Event::inner_event_creation_steps(
Event* event,
Realm* realm, DOMHighResTimeStamp &time,
bool bubbles,
bool cancelable,
bool composed){
3623 event->initialized_flag =
true;
3624 event->timeStamp = time;
3625 event->bubbles = bubbles;
3626 event->cancelable = cancelable;
3627 event->composed = composed;
3630Event::Event(
const DOMString &type,
bool bubbles,
bool cancelable,
bool composed){
3631 DOMHighResTimeStamp now = time(NULL);
3632 inner_event_creation_steps(
this,
nullptr, now, bubbles, cancelable, composed);
3636Event::Event(
const Event* temp){
3637 DOMHighResTimeStamp now = time(NULL);
3638 inner_event_creation_steps(
this,
nullptr, now, temp->bubbles, temp->cancelable, temp->composed);
3639 this->type = temp->type;
3642inline void Event::stopPropagation(){
3643 this->stop_propagation_flag =
true;
3646inline void Event::stopImmediatePropagation(){
3647 this->stop_propagation_flag =
true;
3648 this->stop_immediate_propagation_flag =
true;
3651inline void Event::set_canceled_flag(){
3652 if (this->cancelable && !this->in_passive_listener_flag){
3653 this->canceled_flag =
true;
3657void Event::preventDefault(){
3659 this->set_canceled_flag();
3662void Event::initEvent(DOMString type,
bool bubbles,
bool cancelable){
3663 if (this->dispatch_flag){
3666 this->isTrusted =
false;
3667 this->initialized_flag =
true;
3668 this->stop_propagation_flag =
false;
3669 this->stop_immediate_propagation_flag =
false;
3670 this->canceled_flag =
false;
3671 this->target =
nullptr;
3673 this->bubbles = bubbles;
3674 this->cancelable = cancelable;
3677std::vector<EventTarget*> Event::composedPath(){
3678 std::vector<EventTarget*> composed_path = {};
3679 if (this->path.empty()){
3680 return composed_path;
3682 assert(
dynamic_cast<EventTarget*
>(this->currentTarget));
3683 composed_path.push_back(this->currentTarget);
3684 int currentTargetIndex = 0;
3685 int currentTargetHiddenSubtreeLevel = 0;
3686 for (
int index = this->path.size() - 1; index>=0; index--){
3687 if (this->path[index].root_of_closed_tree){
3688 currentTargetHiddenSubtreeLevel++;
3690 if (this->path[index].invocation_target==this->currentTarget){
3691 currentTargetIndex = index;
3694 if (this->path[index].slot_in_closed_tree){
3695 currentTargetHiddenSubtreeLevel--;
3698 int currentHiddenLevel = currentTargetHiddenSubtreeLevel;
3699 int maxHiddenLevel = currentTargetHiddenSubtreeLevel;
3700 for (
int index = currentTargetIndex - 1; index>=0; index--){
3701 if (this->path[index].root_of_closed_tree){
3702 currentHiddenLevel++;
3704 if (currentHiddenLevel<=maxHiddenLevel){
3705 composed_path.insert(composed_path.begin(),this->path[index].invocation_target);
3707 if (this->path[index].slot_in_closed_tree){
3708 currentHiddenLevel--;
3709 if (currentHiddenLevel<maxHiddenLevel){
3710 maxHiddenLevel = currentHiddenLevel;
3714 currentHiddenLevel = currentTargetHiddenSubtreeLevel;
3715 maxHiddenLevel = currentTargetHiddenSubtreeLevel;
3716 for (
int index = currentTargetIndex + 1; index<this->path.size(); index++){
3717 if (this->path[index].slot_in_closed_tree){
3718 currentHiddenLevel++;
3720 if (currentHiddenLevel<=maxHiddenLevel){
3721 composed_path.push_back(this->path[index].invocation_target);
3723 if (this->path[index].root_of_closed_tree){
3724 currentHiddenLevel--;
3725 if (currentHiddenLevel<maxHiddenLevel){
3726 maxHiddenLevel = currentHiddenLevel;
3730 return composed_path;
3740CustomEvent::CustomEvent(DOMString
const type, std::any &detail,
bool bubbles,
bool cancelable,
bool composed):
Event(type, bubbles, cancelable, composed){
3741 this->detail = detail;
3744void CustomEvent::initCustomEvent(DOMString
const type,
bool bubbles,
bool cancelable, std::any detail){
3745 if (this->dispatch_flag){
3748 this->initEvent(type, bubbles, cancelable);
3749 this->detail = detail;
3754 DOMHighResTimeStamp now = time(NULL);
3755 eventInterface->inner_event_creation_steps(eventInterface, realm, now);
3756 eventInterface->isTrusted =
true;
3757 return eventInterface;
3761void EventTarget::addEventListener(DOMString &type,
EventListener* callback, std::variant<AddEventListenerOptions,bool> &options){
3762 event_listener* temp = flatten(type, callback, options);
3763 add_event_listener(
this, temp);
3766void EventTarget::removeEventListener(DOMString &type,
EventListener* callback,
bool capture){
3768 event_listener* el =
new event_listener(type, callback, capture);
3769 for (event_listener* ev: this->event_listener_list){
3771 remove_event_listener(
this, el);
3777void EventTarget::removeAllEventListeners(){
3778 for (event_listener* a: event_listener_list){
3782 event_listener_list.clear();
3785bool EventTarget::dispatchEvent(
Event* event) {
3786 if (event->dispatch_flag || !event->initialized_flag){
3787 throw InvalidStateError(
"Invalid State");
3789 event->isTrusted =
false;
3790 return dispatch_event(event,
this,
false);
3802AbortController::AbortController(){
3803 this->signal =
new AbortSignal();
3806void AbortController::abort(std::any reason)
const{
3807 signal_abort(this->signal, reason);
3811 AbortSignal* signal =
new AbortSignal();
3812 if (reason.has_value()) {
3813 signal->reason = reason;
3816 signal->reason = AbortError(
"Damn ! Abort error paji! ");
3828AbortSignal *AbortSignal::_any(std::vector<AbortSignal *> signals) {
3829 return create_dependent_abort_signal(signals);
3832void AbortSignal::throwIfAborted() {
3833 if (this->isaborted()) {
3840Node* NodeList::item(
const unsigned long index)
const{
3842 return node_list.at(index);
3844 catch (
const std::out_of_range&) {
3849unsigned long NodeList::length()
const{
3850 return node_list.size();
3853bool NodeList::operator==(
const NodeList* otherNodeList)
const{
3854 if (this->length() != otherNodeList->length()){
3857 for (
size_t i=0; i<this->length(); i++){
3858 if (this->item(i)->isEqualNode(otherNodeList->item(i))){
3866void NodeList::remove(
Node* node){
3868 for (
auto a: this->node_list){
3869 if (a->isEqualNode(node)){
3870 this->node_list.erase(this->node_list.begin()+i);
3878NodeList::~NodeList(){
3879 for (
auto a: node_list) {
3887Node::Node(node_type nodeType, DOMString nodeName,
Document* ownerDocument,
Node* parentNode){
3888 this->nodeType = nodeType;
3889 this->nodeName = nodeName;
3890 this->ownerDocument = ownerDocument;
3891 this->parentNode = parentNode;
3892 if (
dynamic_cast<Element*
>(parentNode)){
3893 this->parentElement =
dynamic_cast<Element*
>(parentNode);
3897bool inline Node::isConnected(){
3898 if (
dynamic_cast<Document*
>(this->getRootNode(
true))){
3904Node* Node::getRootNode(
bool composed){
3906 auto temp =
dynamic_cast<ShadowRoot*
>(
this);
3908 return temp->host()->getRootNode(composed);
3911 if (this->parentNode){
3912 return this->parentNode->getRootNode(composed);
3917inline bool Node::hasChildNodes()
const{
3918 if (this->childNodes.length()==0){
return false; }
3922inline Node* Node::firstChild(){
3923 return this->childNodes[0];
3925inline Node* Node::lastChild(){
3926 return this->childNodes.item(this->childNodes.length()-1);
3928Node* Node::previousSibling() {
3929 if (this->parentNode) {
3930 auto& vect = this->parentNode->childNodes.node_list;
3931 for (
size_t i = 0; i < vect.size(); i++) {
3932 if (vect[i] ==
this) {
3933 if (i == 0)
return nullptr;
3941Node* Node::nextSibling() {
3942 if (this->parentNode) {
3943 auto& vect = this->parentNode->childNodes.node_list;
3944 for (
size_t i = 0; i < vect.size(); i++) {
3945 if (vect[i] ==
this) {
3946 if (i + 1 >= vect.size())
return nullptr;
3954Node* Node::get_the_parent(
Event* event){
3955 Element* temp =
dynamic_cast<Element*
>(
this);
3957 if (temp->assignedSlot!=
nullptr){
3958 return temp->assignedSlot;
3961 Text* temp2 =
dynamic_cast<Text*
>(
this);
3967 return this->parentNode;
3970Node* Node::cloneNode(
bool subtree){
3972 return clone_node(
this,
nullptr, subtree);
3976bool Node::isEqualNode(
Node* otherNode){
3977 if (otherNode==
nullptr){
return false; }
3978 if (nodequals(
this, otherNode)){
3984bool Node::isSameNode(
Node* otherNode){
3985 if (otherNode==
this){
3991unsigned short Node::compareDocumentPosition(
Node* other){
3992 if (this->isSameNode(other)){
3995 Node* node1 = other;
3997 Attr* attr1 =
nullptr;
3998 Attr* attr2 =
nullptr;
3999 Attr* temp =
dynamic_cast<Attr*
>(node1);
4003 node1 =
dynamic_cast<Node*
>(attr1->ownerElement);
4004 temp2 =
dynamic_cast<Element*
>(attr1->ownerElement);
4006 temp =
dynamic_cast<Attr*
>(node2);
4009 node2 =
dynamic_cast<Node*
>(attr2->ownerElement);
4010 temp2 =
dynamic_cast<Element*
>(attr2->ownerElement);
4011 if (attr2!=
nullptr && node1!=
nullptr && node2==node1){
4012 for (Attr* attr: temp2->attributes.attribute_list){
4013 if (nodequals(attr, attr1)){
4014 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_PRECEDING;
4016 if (nodequals(attr, attr2)){
4017 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_FOLLOWING;
4022 if (node1==
nullptr || node2==
nullptr || node1->getRootNode()!=node2->getRootNode()){
4023 return DOCUMENT_POSITION_DISCONNECTED + DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_PRECEDING;
4025 if ((check_ancestor(
dynamic_cast<Node*
>(node2->ownerDocument), node2, node1) && attr1==
nullptr) || (node1==node2 && attr2!=
nullptr)){
4026 return DOCUMENT_POSITION_CONTAINS + DOCUMENT_POSITION_PRECEDING;
4028 if ((check_descendant(node2, node1) && attr2==
nullptr) || (node1==node2 && attr1!=
nullptr)){
4029 return DOCUMENT_POSITION_CONTAINED_BY + DOCUMENT_POSITION_FOLLOWING;
4031 if (check_node_precedes(node2->ownerDocument, node2, node1)){
4032 return DOCUMENT_POSITION_PRECEDING;
4034 return DOCUMENT_POSITION_FOLLOWING;
4037bool Node::contains(
Node* other){
4038 if (other==
nullptr){
return false;}
4039 return check_descendant(
this, other,
true);
4042std::optional<DOMString> Node::lookupPrefix(std::optional<DOMString> &namesp){
4043 if (namesp==std::nullopt || namesp==
""){
return std::nullopt; }
4044 if (this->parentElement==
nullptr){
return std::nullopt; }
4045 return locate_a_namespace_prefix(this->parentElement, namesp);
4048std::optional<DOMString> Node::lookupNamespaceURI(std::optional<DOMString> &prefix){
4049 if (prefix==
""){ prefix=std::nullopt; }
4050 return locate_a_namespace(
this, prefix);
4053bool Node::isDefaultNamespace(std::optional<DOMString> &namesp){
4054 if (namesp==
""){ namesp=std::nullopt; }
4055 std::optional<DOMString> defaultNamespace = locate_a_namespace(
this, std::nullopt);
4056 if (defaultNamespace==namesp){
return true; }
4061 return pre_insert_node(node,
this, child);
4064Node* Node::appendChild(
Node* node){
4065 return pre_insert_node(node,
this,
nullptr);
4069 return replace_node(node,
this, child);
4072Node* Node::removeChild(
Node* child){
4073 return pre_remove_node(child,
this);
4077void Node::normalize(){
4078 if (this->childNodes.length()==0){
return; }
4079 Node* currentNode = this->childNodes[0];
4080 std::vector<Node*> temp = {currentNode};
4081 while (currentNode!=
nullptr){
4082 if (
dynamic_cast<Text*
>(currentNode) && !
dynamic_cast<CDATASection*
>(currentNode)){
4083 unsigned long length = this->length();
4085 remove_node(currentNode);
4091 if (currentNode->childNodes.length()!=0){
4092 temp.push_back(currentNode);
4093 currentNode = currentNode->firstChild();
4096 currentNode = currentNode->nextSibling();
4097 while (currentNode==
nullptr && !temp.empty()){
4098 currentNode = (*(temp.end() -1))->nextSibling();
4099 temp.erase(temp.end()-1);
4104Element* HTMLCollection::item(
const unsigned long &index)
const{
4106 return element_list.at(index);
4108 catch (
const std::out_of_range&) {
4117 for (
auto element: element_list) {
4120 if (element->id==name) {
4127unsigned long HTMLCollection::length()
const{
4128 return element_list.size();
4131HTMLCollection::~HTMLCollection(){
4132 for (
auto a: element_list) {
4135 element_list.clear();
4140void ParentNode::prepend(std::vector<std::variant<Node*, DOMString>> &nodes) {
4142 Node* temp =
new Node(ELEMENT_NODE, kk);
4144 auto smth =
dynamic_cast<Node*
>(
this);
4145 pre_insert_node(temp,
dynamic_cast<Node*
>(
this), smth->firstChild());
4148void ParentNode::append(std::vector<std::variant<Node*, DOMString>> &nodes){
4150 Node* temp =
new Node(ELEMENT_NODE, kk);
4152 pre_insert_node(temp,
dynamic_cast<Node*
>(
this),
nullptr);
4155void ParentNode::replaceChildren(std::vector<std::variant<Node*, DOMString>> &nodes){
4157 Node* temp =
new Node(ELEMENT_NODE, kk);
4159 ensure_pre_insert_validity(temp,
dynamic_cast<Node*
>(
this),
nullptr);
4160 replace_all(temp,
dynamic_cast<Node*
>(
this));
4163void ParentNode::moveBefore(
Node* node,
Node* child){
4164 Node* referenceChild = child;
4165 if (*referenceChild == *node){
4166 referenceChild = node->nextSibling();
4168 move_node(node,
dynamic_cast<Node*
>(
this), referenceChild);
4176Element* Element::previousElementSibling(){
4177 auto smth =
dynamic_cast<Node*
>(
this);
4178 Node* prev = smth->previousSibling();
4180 auto bro =
dynamic_cast<Element*
>(prev);
4184 prev = prev->previousSibling();
4189Element* Element::nextElementSibling(){
4190 auto smth =
dynamic_cast<Node*
>(
this);
4191 Node* next = smth->nextSibling();
4193 auto bro =
dynamic_cast<Element*
>(next);
4197 next = next->nextSibling();
4202Element* CharacterData::previousElementSibling(){
4203 auto smth =
dynamic_cast<Node*
>(
this);
4204 Node* prev = smth->previousSibling();
4206 if (
dynamic_cast<Element*
>(prev)){
4207 return dynamic_cast<Element*
>(prev);
4209 prev = prev->previousSibling();
4214Element* CharacterData::nextElementSibling(){
4215 auto smth =
dynamic_cast<Node*
>(
this);
4216 Node* next = smth->nextSibling();
4218 if (
dynamic_cast<Element*
>(next)){
4219 return dynamic_cast<Element*
>(next);
4221 next = next->nextSibling();
4230DOMString* Document::lookupPrefix(std::optional<DOMString> namesp){
4231 if (namesp==std::nullopt || namesp.value()==
""){
return nullptr; }
4232 if (this->documentElement()==
nullptr){
return nullptr; }
4239DOMString Document::compatMode(){
4240 if (this->mode==QUIRKS){
4241 return "BackCompat";
4243 return "CSS1Compat";
4247 for (
size_t i=0; i<this->childNodes.length(); i++){
4248 DocumentType* temp =
dynamic_cast<DocumentType*
>(this->childNodes[i]);
4256Element* Document::documentElement(){
4257 for (
size_t i=0; i<this->childNodes.length(); i++){
4258 Element* temp =
dynamic_cast<Element*
>(this->childNodes[i]);
4268HTMLCollection* Document::getElementsByTagName(DOMString qualifiedName){
4270 return new HTMLCollection();
4273HTMLCollection* Document::getElementsByTagNameNS(std::optional<DOMString> namesp, DOMString localname){
4275 return new HTMLCollection();
4278HTMLCollection* Document::getElementsByClassName(std::vector<DOMString> &classNames){
4280 return new HTMLCollection();
4283Element* Document::createElement(DOMString localName, std::variant<DOMString,ElementCreationOptions> options){
4284 if (!valid_element_local_name(localName)){
throw InvalidCharacterError(
"Character Name invalid !!"); }
4285 if (this->type!=XML){
4286 std::transform(localName.begin(), localName.end(), localName.begin(), [](
unsigned char c){ return std::tolower(c); });
4288 CustomElementRegistry* registry;
4289 std::optional<DOMString> is;
4290 std::optional<DOMString> namesp;
4291 flatten_element_creation_options(options,
this, registry, is);
4292 if (this->type!=XML || this->contentType==
"application/xhtml+xml"){
4293 namesp =
"http://www.w3.org/1999/xhtml";
4296 namesp = std::nullopt;
4299 return new Element(
"",
"",
"");
4302Element* Document::createElementNS(std::optional<DOMString> namesp, DOMString qualifiedName, std::variant<DOMString,ElementCreationOptions> options){
4303 return internal_create_element_ns(
this, namesp, qualifiedName, options);
4307 DocumentFragment* temp =
new DocumentFragment();
4312Text* Document::createTextNode(DOMString data){
4313 Text* temp =
new Text(data);
4318CDATASection* Document::createCDATASection(DOMString data){
4319 if (this->type!=XML){
throw NotSupportedError(
"Html Doc ain't supported !"); }
4320 if (data.find(
"]]>") != std::string::npos) {
throw InvalidCharacterError(
"Invalid Characters !"); }
4321 CDATASection* temp =
new CDATASection();
4322 temp->setdata(data);
4327Comment* Document::createComment(DOMString data){
4328 Comment* temp =
new Comment(data);
4335 if (data.find(
"?>") != std::string::npos){
throw InvalidCharacterError(
"Invalid Characters !"); }
4336 ProcessingInstruction* temp =
new ProcessingInstruction();
4337 temp->target = target;
4338 temp->setdata(data);
4343Node* Document::importNode(
Node* node, std::variant<bool,ImportNodeOptions> options){
4344 if (
dynamic_cast<Document*
>(node) ||
dynamic_cast<ShadowRoot*
>(node)){
throw NotSupportedError(
"Document and Shadow Root not supported !!"); }
4345 bool subtree =
false;
4346 CustomElementRegistry* registry =
nullptr;
4347 if (std::holds_alternative<bool>(options)){ subtree = std::get<bool>(options); }
4349 ImportNodeOptions temp = std::get<ImportNodeOptions>(options);
4350 subtree = !temp.selfOnly;
4351 if (temp.customElementRegistry!=
nullptr){ registry = temp.customElementRegistry; }
4352 if (registry && registry!=this->custom_element_registry){
throw NotSupportedError(
"NOT SUPPORTED :) !"); }
4354 return clone_node(node,
this, subtree,
nullptr, registry);
4357Node* Document::adoptNode(
Node* node){
4358 if (
dynamic_cast<Document*
>(node)){
throw NotSupportedError(
"Document ain't supported !"); }
4359 if (
dynamic_cast<ShadowRoot*
>(node)){
throw HeirarchyRequestError(
"IDK WHY THIS !!"); }
4360 DocumentFragment* temp =
dynamic_cast<DocumentFragment*
>(node);
4361 if (temp && temp->associatedHost!=
nullptr){
4368Attr* Document::createAttribute(DOMString localName){
4369 if (!valid_attribute_local_name(localName)){
throw InvalidCharacterError(
"Invalid Attribute Name"); }
4370 if (this->type!=XML){
4371 std::transform(localName.begin(), localName.end(), localName.begin(), [](
unsigned char c){ return std::tolower(c); });
4373 Attr* temp =
new Attr(localName);
4378Attr* Document::createAttributeNS(std::optional<DOMString> namesp, DOMString qualifiedName){
4379 std::optional<DOMString> prefix;
4380 DOMString localName;
4381 validate_and_extract(namesp, qualifiedName,
"attribute",prefix, localName);
4382 Attr* temp =
new Attr(localName);
4383 temp->namespaceURI = namesp;
4384 temp->prefix = prefix;
4389Event* Document::createEvent(DOMString interface){
4390 Event* constructor =
nullptr;
4391 if (constructor==
nullptr){
4392 throw NotSupportedError(
"Not supported :)) !!");
4397Range* createRange(){
4414DocumentType* DOMImplementation::createDocumentType(DOMString name, DOMString publicId, DOMString systemId){
4415 if (!valid_doctype_name(name)){
throw InvalidCharacterError(
"Invalid Chars !!"); }
4416 DocumentType* temp =
new DocumentType(name, publicId, systemId);
4421XMLDocument* DOMImplementation::createDocument(std::optional<DOMString> namesp, DOMString qualifiedName, std::optional<DocumentType> doctype){
4422 XMLDocument* document =
new XMLDocument();
4423 Element* element =
nullptr;
4424 if (qualifiedName!=
""){
4425 element = internal_create_element_ns(
dynamic_cast<Document*
>(document), namesp, qualifiedName, ElementCreationOptions());
4427 if (doctype.has_value()){ pre_insert_node(
dynamic_cast<Node*
>(document),
dynamic_cast<Node*
>(&doctype.value()),
nullptr); }
4428 if (element!=
nullptr){ pre_insert_node(
dynamic_cast<Node*
>(document),
dynamic_cast<Node*
>(element),
nullptr); }
4429 document->origin=this->associated_doc->origin;
4430 if (namesp.value()==
"http://www.w3.org/1999/xhtml"){
4431 document->contentType =
"application/xhtml+xml";
4433 else if (namesp.value()==
"http://www.w3.org/2000/svg"){
4434 document->contentType =
"image/svg+xml";
4437 document->contentType =
"application/xml";
4442Document* DOMImplementation::createHTMLDocument(std::optional<DOMString> title){
4443 Document* document =
new Document();
4444 document->type = HTML;
4445 document->contentType =
"text/html";
4446 DocumentType* doct =
new DocumentType(
"html");
4447 doct->ownerDocument = document;
4448 pre_insert_node(
dynamic_cast<Node*
>(document),
dynamic_cast<Node*
>(doct),
nullptr);
4449 Element* htmlElement = create_element(document,
"html",
"http://www.w3.org/1999/xhtml", std::nullopt);
4450 pre_insert_node(
dynamic_cast<Node*
>(document),
dynamic_cast<Node*
>(htmlElement),
nullptr);
4451 Element* headElement = create_element(document,
"head",
"http://www.w3.org/1999/xhtml", std::nullopt);
4452 pre_insert_node(
dynamic_cast<Node*
>(htmlElement),
dynamic_cast<Node*
>(headElement),
nullptr);
4453 if (title!=std::nullopt){
4454 Element* titleElement = create_element(document,
"title",
"http://www.w3.org/1999/xhtml", std::nullopt);
4455 pre_insert_node(
dynamic_cast<Node*
>(headElement),
dynamic_cast<Node*
>(titleElement),
nullptr);
4456 Text* text =
new Text(title.value());
4457 text->ownerDocument = document;
4458 pre_insert_node(
dynamic_cast<Node*
>(titleElement),
dynamic_cast<Node*
>(text),
nullptr);
4461 pre_insert_node(
dynamic_cast<Node*
>(htmlElement),
dynamic_cast<Node*
>(create_element(document,
"body",
"http://www.w3.org/1999/xhtml", std::nullopt)),
nullptr);
4462 document->origin = this->associated_doc->origin;
4468bool DOMImplementation::hasFeature(){
return true; }
4473bool Element::hasAttributes(){
4474 if (this->attributes.attribute_list.size()==0){
4480std::vector<DOMString> Element::getAttributeNames(){
4481 std::vector<DOMString> attribute_qualified_names = {};
4482 for (
auto a: this->attributes.attribute_list){
4483 if (a->prefix==std::nullopt){
4484 attribute_qualified_names.push_back(a->localName);
4487 attribute_qualified_names.push_back(a->prefix.value() +
":" + a->localName);
4490 return attribute_qualified_names;
4494std::optional<DOMString> Element::getAttribute(DOMString qualifiedName){
4495 Attr* attr = fetch_attribute(qualifiedName,
this);
4496 if (attr==
nullptr){
return std::nullopt; }
4500std::optional<DOMString> Element::getAttributeNS(std::optional<DOMString> namesp, DOMString localName){
4501 Attr* attr = fetch_attribute(namesp, localName,
this);
4502 if (attr==
nullptr){
return std::nullopt; }
4507void Element::setAttribute(DOMString qualifiedName, DOMString value){
4508 if (!valid_attribute_local_name(qualifiedName)){
throw InvalidCharacterError(
"Invalid name for attribute !!"); }
4513 Attr* attribute =
nullptr;
4514 for (
auto attr: this->attributes.attribute_list){
4516 if (attr->prefix == std::nullopt){
4517 qualif = attr->localName;
4520 qualif = attr->prefix.value() +
":" + attr->localName;
4522 if (qualif==qualifiedName){
4527 if (attribute==
nullptr){
4528 Attr* temp =
new Attr(qualifiedName);
4529 temp->value = value;
4531 append_attribute(temp,
this);
4534 change_attribute_value(attribute, value);
4537void Element::setAttributeNS(std::optional<DOMString> namesp, DOMString qualifiedName, DOMString value){
4538 std::optional<DOMString> prefix;
4539 DOMString localName;
4540 validate_and_extract(namesp, qualifiedName,
"element", prefix, localName);
4541 set_attribute_value(
this, localName, value, prefix, namesp);
4544void Element::removeAttribute(DOMString qualifiedName){
4545 remove_attribute_by_name(qualifiedName,
this);
4548void Element::removeAttributeNS(std::optional<DOMString> namesp, DOMString localName){
4549 remove_attribute_by_namespace(namesp, localName,
this);
4553bool Element::hasAttribute(DOMString qualifiedName){
4557 for (
auto attr: this->attributes.attribute_list){
4559 if (attr->prefix == std::nullopt){
4560 qualif = attr->localName;
4563 qualif = attr->prefix.value() +
":" + attr->localName;
4565 if (qualif==qualifiedName){
4572bool Element::toggleAttribute(DOMString qualifiedName, std::optional<bool> force){
4573 if (!valid_attribute_local_name(qualifiedName)){
throw InvalidCharacterError(
"Invalid Attribute Name boi !"); }
4577 Attr* attribute =
nullptr;
4578 for (
auto attr: this->attributes.attribute_list){
4580 if (attr->prefix == std::nullopt){
4581 qualif = attr->localName;
4584 qualif = attr->prefix.value() +
":" + attr->localName;
4586 if (qualif==qualifiedName){
4591 if (attribute==
nullptr){
4592 if (!force.has_value() || (force.has_value() && force.value()==
true)){
4593 Attr* temp =
new Attr(qualifiedName);
4596 append_attribute(temp,
this);
4601 if (!force.has_value() || (force.has_value() && force.value()==
false)){
4602 remove_attribute_by_name(qualifiedName,
this);
4608bool Element::hasAttributeNS(std::optional<DOMString> namesp, DOMString localname){
4609 if (namesp.has_value() && namesp.value()==
""){ namesp = std::nullopt; }
4610 for (
auto a: this->attributes.attribute_list){
4611 if (a->namespaceURI==namesp && a->localName==localName){
4619Attr* Element::getAttributeNode(DOMString qualifiedName){
4620 return fetch_attribute(qualifiedName,
this);
4623Attr* Element::getAttributeNodeNS(std::optional<DOMString> namesp, DOMString localName){
4624 return fetch_attribute(namesp, localName,
this);
4627Attr* Element::setAttributeNode(
Attr* attr){
4628 return set_attribute(attr,
this);
4631Attr* Element::setAttributeNodeNS(
Attr* attr){
4632 return set_attribute(attr,
this);
4635Attr* Element::removeAttributeNode(
Attr* attr){
4637 for (
auto a: this->attributes.attribute_list){
4638 if (a==attr){ found =
true; }
4640 if (!found){
throw NotFoundError(
"Attribute Not Found !"); }
4641 remove_attribute(attr);
4647 CustomElementRegistry* registry = this->customElementRegistry;
4648 if (init.customElementRegistry!=
nullptr){
4649 registry = init.customElementRegistry;
4652 attach_shadow_root(
this, init.mode, init.clonable, init.serializable, init.delegatesFocus, init.slotAssignment, *registry);
4653 return this->getshadow_root();
4656Element* Element::insertAdjacentElement(DOMString where,
Element element){
4658 return new Element(
"",
"",
"");
4661void Element::insertAdjacentText(DOMString where, DOMString data){
4667HTMLCollection* Element::getElementsByTagName(DOMString qualifiedName){
4669 return new HTMLCollection();
4672HTMLCollection* Element::getElementsByTagNameNS(std::optional<DOMString> namesp, DOMString localName){
4674 return new HTMLCollection();
4677HTMLCollection* Element::getElementsByClassName(DOMString classNames){
4679 return new HTMLCollection();
4684Attr* NamedNodeMap::item(
unsigned long index){
4686 return attribute_list.at(index);
4688 catch (
const std::out_of_range&) {
4694unsigned long NamedNodeMap::length(){
4695 return attribute_list.size();
4698Attr* NamedNodeMap::getNamedItem(DOMString qualifiedName){
4699 return fetch_attribute(qualifiedName, this->associatedElement);
4702Attr* NamedNodeMap::getNamedItemNS(std::optional<DOMString> namesp, DOMString localName){
4703 return fetch_attribute(namesp, localName, this->associatedElement);
4706Attr* NamedNodeMap::setNamedItem(
Attr* attr){
4707 return set_attribute(attr, this->associatedElement);
4710Attr* NamedNodeMap::setNamedItemNS(
Attr* attr){
4711 return set_attribute(attr, this->associatedElement);
4714Attr* NamedNodeMap::removeNamedItem(DOMString qualifiedName){
4715 Attr* attr = remove_attribute_by_name(qualifiedName, this->associatedElement);
4716 if (attr==
nullptr){
throw NotFoundError(
"Attribute not found !!"); }
4720Attr* NamedNodeMap::removeNamedItemNS(std::optional<DOMString> namesp, DOMString localName){
4721 Attr* attr = remove_attribute_by_namespace(namesp, localName, this->associatedElement);
4722 if (attr==
nullptr){
throw NotFoundError(
"Attribute not found !!"); }
4728Attr::Attr(DOMString localName):
Node(ATTRIBUTE_NODE, this->qualifiedName()){
4729 this->localName = localName;
4732DOMString Attr::qualifiedName(){
4733 if (this->prefix==std::nullopt){
4734 return this->localName;
4736 return this->prefix.value() +
":" + this->localName;
4740unsigned long CharacterData::length(){
4741 return this->data.length();
4744DOMString CharacterData::substringData(
unsigned long offset,
unsigned long count){
4745 return substring_data(
dynamic_cast<Node*
>(
this), offset, count);
4748void CharacterData::appendData(DOMString data){
4749 replace_data(
dynamic_cast<Node*
>(
this), this->length(), 0, data);
4752void CharacterData::insertData(
unsigned long offset, DOMString data){
4753 replace_data(
dynamic_cast<Node*
>(
this), offset, 0, data);
4756void CharacterData::deleteData(
unsigned long offset,
unsigned long count){
4757 replace_data(
dynamic_cast<Node*
>(
this), offset, count,
"");
4760void CharacterData::replaceData(
unsigned long offset,
unsigned long count, DOMString data){
4761 replace_data(
dynamic_cast<Node*
>(
this), offset, count, data);
4765Text* Text::splitText(
unsigned long offset){
4766 return split_text_node(
this, offset);
4769DOMString Text::wholeText(){
4770 DOMString data =
"";
4771 for (
auto a: contiguous_text_nodes(
this)){
4780bool AbstractRange::collapsed(){
4781 if (this->startContainer==this->endContainer && this->startOffset==this->endOffset){
4789 if (
dynamic_cast<DocumentType*
>(init.startContainer) ||
dynamic_cast<Attr*
>(init.startContainer) ||
dynamic_cast<DocumentType*
>(init.endContainer) ||
dynamic_cast<Attr*
>(init.endContainer) ){
4790 throw InvalidNodeTypeError(
"invalid node type baby !!");
4792 this->startContainer = init.startContainer;
4793 this->startOffset = init.startOffset;
4794 this->endContainer = init.endContainer;
4795 this->endOffset = init.endOffset;
4800Node* Range::commonAncestorContainer(){
4801 Node* container = this->startContainer;
4802 while (!check_ancestor(this->endContainer, container,
true)){
4803 container = container->parentNode;
4809void Range::setStart(
Node* node,
unsigned long offset){
4810 set_start_end(
this, node, offset);
4813void Range::setEnd(
Node* node,
unsigned long offset){
4814 set_start_end(
this, node, offset,
false);
4817void Range::setStartBefore(
Node* node){
4818 Node* parent = node->parentNode;
4819 if (parent==
nullptr){
throw InvalidNodeTypeError(
"invalid node type dummy !"); }
4820 set_start_end(
this, parent, node->index());
4823void Range::setStartAfter(
Node* node){
4824 Node* parent = node->parentNode;
4825 if (parent==
nullptr){
throw InvalidNodeTypeError(
"invalid node type dummy !"); }
4826 set_start_end(
this, parent, node->index()+1);
4829void Range::setEndBefore(
Node* node){
4830 Node* parent = node->parentNode;
4831 if (parent==
nullptr){
throw InvalidNodeTypeError(
"invalid node type dummy !"); }
4832 set_start_end(
this, parent, node->index(),
false);
4835void Range::setEndAfter(
Node* node){
4836 Node* parent = node->parentNode;
4837 if (parent==
nullptr){
throw InvalidNodeTypeError(
"invalid node type dummy !"); }
4838 set_start_end(
this, parent, node->index()+1,
false);
4841void Range::collapse(
bool toStart){
4843 this->endContainer = this->startContainer;
4844 this->endOffset = this->startOffset;
4847 this->startContainer = this->endContainer;
4848 this->startOffset = this->endOffset;
4852void Range::selectNode(
Node* node){
4853 select_node_within_rangee(node,
this);
4856void Range::selectNodeContents(
Node* node){
4857 if (
dynamic_cast<DocumentType*
>(node)){
throw InvalidNodeTypeError(
"invalid node type boi !!!"); }
4858 unsigned long length = node->length();
4859 this->startContainer = node;
4860 this->startOffset = 0;
4861 this->endContainer = node;
4862 this->endOffset = length;
4865short Range::compareBoundaryPoints(
unsigned short how,
Range* sourceRange){
4866 if (how!=START_TO_START && how!=START_TO_END && how!=END_TO_END && how!=END_TO_START){
4867 throw NotSupportedError(
"not supported this start end whatever !");
4869 if (this->startContainer->getRootNode()!=sourceRange->startContainer->getRootNode()){
4870 throw WrongDocumentError(
"wrong document ! read it u sick boi !!");
4873 unsigned long thisoffset;
4875 unsigned long otheroffset;
4876 if (how==START_TO_START){
4877 thisnode = this->startContainer;
4878 thisoffset = this->startOffset;
4879 othernode = sourceRange->startContainer;
4880 otheroffset = sourceRange->startOffset;
4882 else if (how==START_TO_END){
4883 thisnode = this->endContainer;
4884 thisoffset = this->endOffset;
4885 othernode = sourceRange->startContainer;
4886 otheroffset = sourceRange->startOffset;
4888 else if (how==END_TO_END){
4889 thisnode = this->endContainer;
4890 thisoffset = this->endOffset;
4891 othernode = sourceRange->endContainer;
4892 otheroffset = sourceRange->endOffset;
4894 else if (how==END_TO_START){
4895 thisnode = this->startContainer;
4896 thisoffset = this->startOffset;
4897 othernode = sourceRange->endContainer;
4898 otheroffset = sourceRange->endOffset;
4900 return position(thisnode, thisoffset, othernode, otheroffset);
4904void Range::deleteContents(){
4905 if (this->collapsed()){
4908 Node* original_startnode = this->startContainer;
4909 unsigned long original_startoffset = this->startOffset;
4910 Node* original_endnode = this->endContainer;
4911 unsigned long original_endoffset = this->endOffset;
4913 if (original_startnode==original_endnode &&
dynamic_cast<CharacterData*
>(original_startnode)){
4914 replace_data(original_startnode, original_startoffset, original_endoffset - original_startoffset,
"");
4917 std::vector<Node*> nodes_to_remove = {};
4919 unsigned long new_offset;
4920 if (check_ancestor(original_endnode, original_startnode,
true)){
4921 new_node = original_startnode;
4922 new_offset = original_startoffset;
4925 Node* reference_node = original_startnode;
4926 while(reference_node->parentNode!=
nullptr && !check_ancestor(original_endnode, reference_node,
true)){
4927 reference_node = reference_node->parentNode;
4929 new_node = reference_node->parentNode;
4930 new_offset = reference_node->index() + 1;
4932 if (
dynamic_cast<CharacterData*
>(original_startnode)){
4933 replace_data(original_startnode, original_startoffset, original_startnode->length() - original_startoffset,
"");
4935 for (
auto node: nodes_to_remove){
4938 if (
dynamic_cast<CharacterData*
>(original_endnode)){
4939 replace_data(original_endnode, 0, original_endoffset,
"");
4941 this->startContainer = new_node;
4942 this->startOffset = new_offset;
4943 this->endContainer = new_node;
4944 this->endOffset = new_offset;
4948 return new DocumentFragment();
4952 return new DocumentFragment();
4955void Range::insertNode(
Node* node){
4956 insert_node_in_range(node,
this);
4959void Range::surroundContents(
Node* newParent){
4960 if (
dynamic_cast<Document*
>(newParent) ||
dynamic_cast<DocumentType*
>(newParent) ||
dynamic_cast<DocumentFragment*
>(newParent)){
4961 throw InvalidNodeTypeError(
"invalid node type baby !!");
4963 DocumentFragment* fragment = extract_range(
this);
4964 if (newParent->hasChildNodes()){
4965 replace_all(
nullptr, newParent);
4967 insert_node_in_range(newParent,
this);
4968 pre_insert_node(
dynamic_cast<Node*
>(fragment), newParent,
nullptr);
4969 select_node_within_rangee(newParent,
this);
4973Range* Range::cloneRange(){
4974 Range* temp =
new Range();
4975 temp->startContainer = this->startContainer;
4976 temp->startOffset = this->startOffset;
4977 temp->endContainer = this->endContainer;
4978 temp->endOffset = this->endOffset;
4982bool Range::isPointInRange(
Node* node,
unsigned long offset){
4983 if (node->getRootNode()!=this->startContainer->getRootNode()){
4986 if (
dynamic_cast<DocumentType*
>(node)){
4987 throw InvalidNodeTypeError(
"u got from the name !");
4989 if (offset>node->length()){
4990 throw IndexSizeError(
"index is not fit !!");
4992 if (position(node, offset, this->startContainer, this->startOffset)==-1 || position(node, offset, this->endContainer, this->endOffset)==1){
4999short Range::comparePoint(
Node* node,
unsigned long offset){
5000 if (node->getRootNode()!=this->startContainer->getRootNode()){
5001 throw WrongDocumentError(
"Wrong document !!");
5003 if (
dynamic_cast<DocumentType*
>(node)){
5004 throw InvalidNodeTypeError(
"invalid node type !!");
5006 if (offset>node->length()){
5007 throw IndexSizeError(
"index size issue !!");
5009 if (position(node, offset, this->startContainer, this->startOffset)==-1){
5012 if (position(node, offset, this->endContainer, this->endOffset)==1){
5019bool Range::intersectsNode(
Node* node){
5020 if (node->getRootNode()!=this->startContainer->getRootNode()){
5023 Node* parent = node->parentNode;
5024 if (parent==
nullptr){
5027 unsigned long offset = node->index();
5028 if (position(parent, offset, this->endContainer, this->endOffset)==-1 && position(parent, offset+1, this->startContainer, this->startOffset)==1){
5034DOMString Range::stringification_behavior(){
5036 Text* temp =
dynamic_cast<Text*
>(this->startContainer);
5037 if (this->startContainer==this->endContainer && temp){
5043 temp =
dynamic_cast<Text*
>(this->endContainer);
5092Node* TreeWalker::parentNode(){
5093 Node* node = this->currentNode;
5094 while (node!=
nullptr && node!=this->root){
5095 node = node->parentNode;
5096 if (node!=
nullptr && this->
filter_node(node)==FILTER_ACCEPT){
5097 this->currentNode = node;
5151Node* TreeWalker::nextNode(){
5152 Node* node = this->currentNode;
5153 unsigned short result = FILTER_ACCEPT;
5155 while (result!=FILTER_REJECT && node->hasChildNodes()){
5156 node = node->firstChild();
5158 if (result == FILTER_ACCEPT){
5159 this->currentNode = node;
5163 Node* sibling =
nullptr;
5164 Node* temporary = node;
5165 while (temporary!=
nullptr){
5166 if (temporary==this->root){
5169 sibling = temporary->nextSibling();
5170 if (sibling!=
nullptr){
5174 temporary = temporary->parentNode;
5177 if (result==FILTER_ACCEPT){
5178 this->currentNode = node;
5186void DOMTokenList::add(std::vector<DOMString> tokens){
5187 for (
auto token: tokens){
5188 if (token==
""){
throw SyntaxError(
"sytaxxxxxx"); }
5189 if (token.find(
" ")!=std::string::npos){
throw InvalidCharacterError(
"uk !"); }
5191 for (
auto token: tokens){
5192 this->list.insert(token);
5198void DOMTokenList::remove(std::vector<DOMString> tokens){
5199 for (
auto token: tokens){
5200 if (token==
""){
throw SyntaxError(
"sytaxxxxxx"); }
5201 if (token.find(
" ")!=std::string::npos){
throw InvalidCharacterError(
"uk !"); }
5203 for (
auto token: tokens){
5204 this->list.erase(token);
5209bool DOMTokenList::toggle(DOMString token, std::optional<bool> force){
5210 if (token==
""){
throw SyntaxError(
"sytaxxxxxx"); }
5211 if (token.find(
" ")!=std::string::npos){
throw InvalidCharacterError(
"uk !"); }
5212 if (this->list.find(token)!=this->list.end()){
5213 if (!force.has_value() || !force.value()){
5214 this->list.erase(token);
5220 if (!force.has_value() || force){
5221 this->list.insert(token);
5229bool DOMTokenList::replace(DOMString token, DOMString newToken){
5230 if (token==
"" || newToken==
""){
throw SyntaxError(
"sytaxxxxxx"); }
5231 if (token.find(
" ")!=std::string::npos || newToken.find(
" ")!=std::string::npos){
throw InvalidCharacterError(
"uk !"); }
5232 if (this->list.find(token)==this->list.end()){
return false; }
5233 this->list.erase(token);
5234 this->list.insert(newToken);
5240bool DOMTokenList::supports(DOMString token){
5241 return this->validate(token);
static AbortSignal * timeout(unsigned long long milliseconds)
DOMString characterSet
serialize
USVString documentURI
serialize
Element * namedItem(const DOMString &name) const
unsigned short filter_node(Node *node)
HTMLSlotElement * assignedSlot
IMPORTANT SOMEWHERE in dispatch_event (slottable check)
unsigned short filter_node(Node *node)